From 4c7d2ba42f46738adac4e60f0e9a6798e2906a5e Mon Sep 17 00:00:00 2001 From: Hannes Winkler Date: Sat, 16 Nov 2019 23:45:29 +0100 Subject: [PATCH 1/4] more verbose modesetting automatic drm device selection --- Makefile | 2 +- src/flutter-pi.c | 143 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 126 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 74ff9bff..d9ce7357 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = cc LD = cc -REAL_CFLAGS = -I./include $(shell pkg-config --cflags dri gbm libdrm glesv2 egl) -D_GNU_SOURCE -DBUILD_ELM327PLUGIN $(CFLAGS) +REAL_CFLAGS = -I./include $(shell pkg-config --cflags dri gbm libdrm glesv2 egl) -DBUILD_ELM327PLUGIN $(CFLAGS) REAL_LDFLAGS = $(shell pkg-config --libs dri gbm libdrm glesv2 egl) -lrt -lflutter_engine -lpthread -ldl $(LDFLAGS) SOURCES = src/flutter-pi.c src/platformchannel.c src/pluginregistry.c src/plugins/elm327plugin.c src/plugins/services-plugin.c src/plugins/testplugin.c diff --git a/src/flutter-pi.c b/src/flutter-pi.c index c3d863c5..0606baf0 100644 --- a/src/flutter-pi.c +++ b/src/flutter-pi.c @@ -64,7 +64,8 @@ uint32_t refresh_rate; double pixel_ratio = 0.0; struct { - char device[128]; + char device[PATH_MAX]; + bool has_device; int fd; uint32_t connector_id; drmModeModeInfo *mode; @@ -89,6 +90,7 @@ struct { EGLSurface surface; bool modifiers_supported; + char *renderer; EGLDisplay (*eglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list); EGLSurface (*eglCreatePlatformWindowSurfaceEXT)(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); @@ -372,12 +374,17 @@ const GLubyte *hacked_glGetString(GLenum name) { void *proc_resolver(void* userdata, const char* name) { if (name == NULL) return NULL; + static int is_videocore4 = -1; + /* * The mesa v3d driver reports some OpenGL ES extensions as supported and working * even though they aren't. hacked_glGetString is a workaround for this, which will * cut out the non-working extensions from the list of supported extensions. */ - if (strcmp(name, "glGetString") == 0) { + + if (is_videocore4 == -1) is_videocore4 = strcmp(egl.renderer, "VC4 V3D 2.1") == 0; + + if (is_videocore4 && (strcmp(name, "glGetString") == 0)) { return hacked_glGetString; } @@ -494,7 +501,7 @@ bool setup_paths(void) { return false; } - snprintf(drm.device, sizeof(drm.device), "/dev/dri/card0"); + //snprintf(drm.device, sizeof(drm.device), "/dev/dri/card0"); return true; @@ -511,22 +518,110 @@ bool init_display(void) { drmModeEncoder *encoder; int i, ok, area; + if (!drm.has_device) { + printf("Finding a suitable DRM device, since none is given...\n"); + drmDevicePtr devices[64] = { NULL }; + int num_devices, fd = -1; + + num_devices = drmGetDevices2(0, devices, sizeof(devices)/sizeof(drmDevicePtr)); + if (num_devices < 0) { + fprintf(stderr, "could not query drm device list: %s\n", strerror(-num_devices)); + return false; + } + + printf("looking for a suitable DRM device from %d available DRM devices...\n", num_devices); + for (i = 0; i < num_devices; i++) { + drmDevicePtr device = devices[i]; + + printf(" devices[%d]: \n", i); + + printf(" available nodes: "); + if (device->available_nodes & (1 << DRM_NODE_PRIMARY)) printf("DRM_NODE_PRIMARY, "); + if (device->available_nodes & (1 << DRM_NODE_CONTROL)) printf("DRM_NODE_CONTROL, "); + if (device->available_nodes & (1 << DRM_NODE_RENDER)) printf("DRM_NODE_RENDER"); + printf("\n"); + + for (int j=0; j < DRM_NODE_MAX; j++) { + if (device->available_nodes & (1 << j)) { + printf(" nodes[%s] = \"%s\"\n", + j == DRM_NODE_PRIMARY ? "DRM_NODE_PRIMARY" : + j == DRM_NODE_CONTROL ? "DRM_NODE_CONTROL" : + j == DRM_NODE_RENDER ? "DRM_NODE_RENDER" : "unknown", + device->nodes[j] + ); + } + } - printf("Opening DRM device...\n"); - drm.fd = open(drm.device, O_RDWR); - if (drm.fd < 0) { - fprintf(stderr, "Could not open DRM device\n"); - return false; + printf(" bustype: %s\n", + device->bustype == DRM_BUS_PCI ? "DRM_BUS_PCI" : + device->bustype == DRM_BUS_USB ? "DRM_BUS_USB" : + device->bustype == DRM_BUS_PLATFORM ? "DRM_BUS_PLATFORM" : + device->bustype == DRM_BUS_HOST1X ? "DRM_BUS_HOST1X" : + "unknown" + ); + + if (device->bustype == DRM_BUS_PLATFORM) { + printf(" businfo.fullname: %s\n", device->businfo.platform->fullname); + // seems like deviceinfo.platform->compatible is not really used. + //printf(" deviceinfo.compatible: %s\n", device->deviceinfo.platform->compatible); + } + + // we want a device that's DRM_NODE_PRIMARY and that we can call a drmModeGetResources on. + if (drm.has_device) continue; + if (!(device->available_nodes & (1 << DRM_NODE_PRIMARY))) continue; + + printf(" opening DRM device candidate at \"%s\"...\n", device->nodes[DRM_NODE_PRIMARY]); + fd = open(device->nodes[DRM_NODE_PRIMARY], O_RDWR); + if (fd < 0) { + printf(" could not open DRM device candidate at \"%s\": %s\n", device->nodes[DRM_NODE_PRIMARY], strerror(errno)); + continue; + } + + printf(" getting resources of DRM device candidate at \"%s\"...\n", device->nodes[DRM_NODE_PRIMARY]); + resources = drmModeGetResources(fd); + if (resources == NULL) { + printf(" could not query DRM resources for DRM device candidate at \"%s\":", device->nodes[DRM_NODE_PRIMARY]); + if ((errno = EOPNOTSUPP) || (errno = EINVAL)) printf("doesn't look like a modeset device.\n"); + else printf("%s\n", strerror(errno)); + close(fd); + continue; + } + + // we found our DRM device. + printf(" flutter-pi chose \"%s\" as its DRM device.\n", device->nodes[DRM_NODE_PRIMARY]); + drm.fd = fd; + drm.has_device = true; + snprintf(drm.device, sizeof(drm.device)-1, device->nodes[DRM_NODE_PRIMARY]); + } + + if (!drm.has_device) { + fprintf(stderr, "flutter-pi couldn't find a usable DRM device.\n" + "Please make sure you've enabled the Fake-KMS driver in raspi-config.\n" + "If you're not using a Raspberry Pi, please make sure there's KMS support for your graphics chip.\n"); + return false; + } } + if (drm.fd <= 0) { + printf("Opening DRM device...\n"); + drm.fd = open(drm.device, O_RDWR); + if (drm.fd < 0) { + fprintf(stderr, "Could not open DRM device\n"); + return false; + } + } - printf("Getting DRM resources...\n"); - resources = drmModeGetResources(drm.fd); - if (resources == NULL) { - if (errno == EOPNOTSUPP) fprintf(stderr, "%s doesn't look like a modeset device\n", drm.device); - else fprintf(stderr, "drmModeGetResources failed: %s\n", strerror(errno)); - - return false; + if (!resources) { + printf("Getting DRM resources...\n"); + resources = drmModeGetResources(drm.fd); + if (resources == NULL) { + if ((errno == EOPNOTSUPP) || (errno = EINVAL)) + fprintf(stderr, "%s doesn't look like a modeset device\n", drm.device); + else + fprintf(stderr, "drmModeGetResources failed: %s\n", strerror(errno)); + + return false; + } } @@ -577,6 +672,7 @@ bool init_display(void) { } printf("Choosing DRM mode from %d available modes...\n", connector->count_modes); + bool found_preferred = false; for (i = 0, area = 0; i < connector->count_modes; i++) { drmModeModeInfo *current_mode = &connector->modes[i]; @@ -586,6 +682,8 @@ bool init_display(void) { current_mode->vrefresh, current_mode->type, current_mode->flags ); + if (found_preferred) continue; + // we choose the highest resolution with the highest refresh rate, preferably non-interlaced (= progressive) here. int current_area = current_mode->hdisplay * current_mode->vdisplay; if (( current_area > area) || @@ -601,11 +699,12 @@ bool init_display(void) { // if the preferred DRM mode is bogus, we're screwed. if (current_mode->type & DRM_MODE_TYPE_PREFERRED) { - printf("the chosen DRM mode is preferred by DRM. (DRM_MODE_TYPE_PREFERRED)\n"); - break; + printf(" this mode is preferred by DRM. (DRM_MODE_TYPE_PREFERRED)\n"); + found_preferred = true; } } } + if (!drm.mode) { fprintf(stderr, "could not find a suitable DRM mode!\n"); return false; @@ -689,6 +788,10 @@ bool init_display(void) { const EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_ALPHA_SIZE, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; @@ -799,9 +902,11 @@ bool init_display(void) { return false; } + egl.renderer = (char*) glGetString(GL_RENDERER); + gl_exts = (char*) glGetString(GL_EXTENSIONS); printf("===================================\n"); - printf("OpenGL ES 2.x information:\n"); + printf("OpenGL ES information:\n"); printf(" version: \"%s\"\n", glGetString(GL_VERSION)); printf(" shading language version: \"%s\"\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); printf(" vendor: \"%s\"\n", glGetString(GL_VENDOR)); @@ -809,6 +914,8 @@ bool init_display(void) { printf(" extensions: \"%s\"\n", gl_exts); printf("===================================\n"); + + drm.evctx.version = 2; drm.evctx.page_flip_handler = page_flip_handler; From dde30d54021694ceaef4177ff1a7dfde9570b5da Mon Sep 17 00:00:00 2001 From: Hannes Winkler Date: Sun, 17 Nov 2019 01:50:03 +0100 Subject: [PATCH 2/4] added gbm format modifier print on present set EGL buffer samples to 0 --- src/flutter-pi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/flutter-pi.c b/src/flutter-pi.c index 0606baf0..72ca38d9 100644 --- a/src/flutter-pi.c +++ b/src/flutter-pi.c @@ -232,6 +232,8 @@ bool present(void* userdata) { next_bo = gbm_surface_lock_front_buffer(gbm.surface); fb = drm_fb_get_from_bo(next_bo); + printf("***PRESENT***\n"); + /* wait for vsync, ok = drmModePageFlip(drm.fd, drm.crtc_id, fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &drm.waiting_for_flip); if (ok) { @@ -758,13 +760,14 @@ bool init_display(void) { gbm.device = gbm_create_device(drm.fd); gbm.format = DRM_FORMAT_XRGB8888; gbm.surface = NULL; + gbm.modifier = DRM_FORMAT_MOD_LINEAR; if (gbm_surface_create_with_modifiers) { gbm.surface = gbm_surface_create_with_modifiers(gbm.device, width, height, gbm.format, &gbm.modifier, 1); } if (!gbm.surface) { - if (gbm.modifier != 0) { + if (gbm.modifier != DRM_FORMAT_MOD_LINEAR) { fprintf(stderr, "GBM Surface creation modifiers requested but not supported by GBM\n"); return false; } @@ -793,6 +796,7 @@ bool init_display(void) { EGL_BLUE_SIZE, 1, EGL_ALPHA_SIZE, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_SAMPLES, 0, EGL_NONE }; From 673590d779b168e2feda577fd4632dbbc6ab99a5 Mon Sep 17 00:00:00 2001 From: ardera <2488440+ardera@users.noreply.github.com> Date: Sun, 17 Nov 2019 21:18:43 +0100 Subject: [PATCH 3/4] report no extensions for VideoCore IV --- src/flutter-pi.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/flutter-pi.c b/src/flutter-pi.c index 72ca38d9..6a62e0b2 100644 --- a/src/flutter-pi.c +++ b/src/flutter-pi.c @@ -296,7 +296,7 @@ void cut_word_from_string(char* string, char* word) { } const GLubyte *hacked_glGetString(GLenum name) { if (name == GL_EXTENSIONS) { - static GLubyte* extensions; + static GLubyte* extensions = NULL; if (extensions == NULL) { GLubyte* orig_extensions = (GLubyte *) glGetString(GL_EXTENSIONS); @@ -373,21 +373,43 @@ const GLubyte *hacked_glGetString(GLenum name) { return glGetString(name); } } +const GLubyte *hacked2_glGetString(GLenum name) { + if (name == GL_EXTENSIONS) { + static GLubyte* extensions = NULL; + + // no extensions. + return ""; + } else { + return glGetString(name); + } +} void *proc_resolver(void* userdata, const char* name) { if (name == NULL) return NULL; static int is_videocore4 = -1; + static int is_videocore6 = -1; /* - * The mesa v3d driver reports some OpenGL ES extensions as supported and working + * The mesa V3D driver reports some OpenGL ES extensions as supported and working * even though they aren't. hacked_glGetString is a workaround for this, which will * cut out the non-working extensions from the list of supported extensions. */ - if (is_videocore4 == -1) is_videocore4 = strcmp(egl.renderer, "VC4 V3D 2.1") == 0; + if (is_videocore4 == -1) { + is_videocore4 = strcmp(egl.renderer, "VC4 V3D 2.1") == 0; + if (is_videocore4) printf("detected VideoCore IV as underlying graphics chip. Reporting modified GL_EXTENSIONS string that doesn't contain non-working extensions.\n"); + } + if (is_videocore6 == -1) { + is_videocore6 = strcmp(egl.renderer, "V3D 4.2") == 0; + if (is_videocore6) printf("detected VideoCore VI as underlying graphics chip. Reporting no GL Extensions.\n"); + } - if (is_videocore4 && (strcmp(name, "glGetString") == 0)) { - return hacked_glGetString; + if (strcmp(name, "glGetString") == 0) { + if (is_videocore4) { + return hacked_glGetString; + } else if (is_videocore6) { + return hacked2_glGetString; + } } void* address; From 15392a0c8545f861c28f170512d5d2de0d448eea Mon Sep 17 00:00:00 2001 From: Hannes Winkler Date: Mon, 18 Nov 2019 18:16:23 +0100 Subject: [PATCH 4/4] remove some debugging stuff ready to be merged to master for pi 4 support --- src/flutter-pi.c | 230 ++++++++++++++++++++++------------------------- 1 file changed, 105 insertions(+), 125 deletions(-) diff --git a/src/flutter-pi.c b/src/flutter-pi.c index 6a62e0b2..3e2c594c 100644 --- a/src/flutter-pi.c +++ b/src/flutter-pi.c @@ -137,7 +137,7 @@ pthread_cond_t task_added = PTHREAD_COND_INITIALIZER; /********************* * FLUTTER CALLBACKS * *********************/ -bool make_current(void* userdata) { +bool make_current(void* userdata) { if (eglMakeCurrent(egl.display, egl.surface, egl.surface, egl.context) != EGL_TRUE) { fprintf(stderr, "make_current: could not make the context current.\n"); return false; @@ -145,7 +145,7 @@ bool make_current(void* userdata) { return true; } -bool clear_current(void* userdata) { +bool clear_current(void* userdata) { if (eglMakeCurrent(egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) { fprintf(stderr, "clear_current: could not clear the current context.\n"); return false; @@ -153,11 +153,11 @@ bool clear_current(void* userdata) { return true; } -void page_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) { +void page_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) { int *waiting_for_flip = data; *waiting_for_flip = 0; } -void drm_fb_destroy_callback(struct gbm_bo *bo, void *data) { +void drm_fb_destroy_callback(struct gbm_bo *bo, void *data) { struct drm_fb *fb = data; if (fb->fb_id) @@ -165,7 +165,7 @@ void drm_fb_destroy_callback(struct gbm_bo *bo, void *data) { free(fb); } -struct drm_fb* drm_fb_get_from_bo(struct gbm_bo *bo) { +struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo) { uint32_t width, height, format, strides[4] = {0}, handles[4] = {0}, offsets[4] = {0}, flags = 0; int ok = -1; @@ -222,7 +222,7 @@ struct drm_fb* drm_fb_get_from_bo(struct gbm_bo *bo) { return fb; } -bool present(void* userdata) { +bool present(void* userdata) { fd_set fds; struct gbm_bo *next_bo; struct drm_fb *fb; @@ -232,8 +232,6 @@ bool present(void* userdata) { next_bo = gbm_surface_lock_front_buffer(gbm.surface); fb = drm_fb_get_from_bo(next_bo); - printf("***PRESENT***\n"); - /* wait for vsync, ok = drmModePageFlip(drm.fd, drm.crtc_id, fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &drm.waiting_for_flip); if (ok) { @@ -274,12 +272,12 @@ bool present(void* userdata) { return true; } -uint32_t fbo_callback(void* userdata) { +uint32_t fbo_callback(void* userdata) { return 0; } -void cut_word_from_string(char* string, char* word) { +void cut_word_from_string(char* string, char* word) { size_t word_length = strlen(word); - char* word_in_str = strstr(string, word); + char* word_in_str = strstr(string, word); // check if the given word is surrounded by spaces in the string if (word_in_str @@ -294,139 +292,123 @@ void cut_word_from_string(char* string, char* word) { } while (word_in_str[i++ + word_length] != 0); } } -const GLubyte *hacked_glGetString(GLenum name) { - if (name == GL_EXTENSIONS) { - static GLubyte* extensions = NULL; - - if (extensions == NULL) { - GLubyte* orig_extensions = (GLubyte *) glGetString(GL_EXTENSIONS); - size_t len_orig_extensions = strlen(orig_extensions); - - extensions = malloc(len_orig_extensions+1); - strcpy(extensions, orig_extensions); - - /* - * working (apparently) - */ - //cut_word_from_string(extensions, "GL_EXT_blend_minmax"); - //cut_word_from_string(extensions, "GL_EXT_multi_draw_arrays"); - //cut_word_from_string(extensions, "GL_EXT_texture_format_BGRA8888"); - //cut_word_from_string(extensions, "GL_OES_compressed_ETC1_RGB8_texture"); - //cut_word_from_string(extensions, "GL_OES_depth24"); - //cut_word_from_string(extensions, "GL_OES_texture_npot"); - //cut_word_from_string(extensions, "GL_OES_vertex_half_float"); - //cut_word_from_string(extensions, "GL_OES_EGL_image"); - //cut_word_from_string(extensions, "GL_OES_depth_texture"); - //cut_word_from_string(extensions, "GL_AMD_performance_monitor"); - //cut_word_from_string(extensions, "GL_OES_EGL_image_external"); - //cut_word_from_string(extensions, "GL_EXT_occlusion_query_boolean"); - //cut_word_from_string(extensions, "GL_KHR_texture_compression_astc_ldr"); - //cut_word_from_string(extensions, "GL_EXT_compressed_ETC1_RGB8_sub_texture"); - //cut_word_from_string(extensions, "GL_EXT_draw_elements_base_vertex"); - //cut_word_from_string(extensions, "GL_EXT_texture_border_clamp"); - //cut_word_from_string(extensions, "GL_OES_draw_elements_base_vertex"); - //cut_word_from_string(extensions, "GL_OES_texture_border_clamp"); - //cut_word_from_string(extensions, "GL_KHR_texture_compression_astc_sliced_3d"); - //cut_word_from_string(extensions, "GL_MESA_tile_raster_order"); - - /* - * should be working, but isn't - */ - cut_word_from_string(extensions, "GL_EXT_map_buffer_range"); - - /* - * definitely broken - */ - cut_word_from_string(extensions, "GL_OES_element_index_uint"); - cut_word_from_string(extensions, "GL_OES_fbo_render_mipmap"); - cut_word_from_string(extensions, "GL_OES_mapbuffer"); - cut_word_from_string(extensions, "GL_OES_rgb8_rgba8"); - cut_word_from_string(extensions, "GL_OES_stencil8"); - cut_word_from_string(extensions, "GL_OES_texture_3D"); - cut_word_from_string(extensions, "GL_OES_packed_depth_stencil"); - cut_word_from_string(extensions, "GL_OES_get_program_binary"); - cut_word_from_string(extensions, "GL_APPLE_texture_max_level"); - cut_word_from_string(extensions, "GL_EXT_discard_framebuffer"); - cut_word_from_string(extensions, "GL_EXT_read_format_bgra"); - cut_word_from_string(extensions, "GL_EXT_frag_depth"); - cut_word_from_string(extensions, "GL_NV_fbo_color_attachments"); - cut_word_from_string(extensions, "GL_OES_EGL_sync"); - cut_word_from_string(extensions, "GL_OES_vertex_array_object"); - cut_word_from_string(extensions, "GL_EXT_unpack_subimage"); - cut_word_from_string(extensions, "GL_NV_draw_buffers"); - cut_word_from_string(extensions, "GL_NV_read_buffer"); - cut_word_from_string(extensions, "GL_NV_read_depth"); - cut_word_from_string(extensions, "GL_NV_read_depth_stencil"); - cut_word_from_string(extensions, "GL_NV_read_stencil"); - cut_word_from_string(extensions, "GL_EXT_draw_buffers"); - cut_word_from_string(extensions, "GL_KHR_debug"); - cut_word_from_string(extensions, "GL_OES_required_internalformat"); - cut_word_from_string(extensions, "GL_OES_surfaceless_context"); - cut_word_from_string(extensions, "GL_EXT_separate_shader_objects"); - cut_word_from_string(extensions, "GL_KHR_context_flush_control"); - cut_word_from_string(extensions, "GL_KHR_no_error"); - cut_word_from_string(extensions, "GL_KHR_parallel_shader_compile"); - } +const GLubyte *hacked_glGetString(GLenum name) { + static GLubyte *extensions = NULL; - return extensions; - } else { + if (name != GL_EXTENSIONS) return glGetString(name); - } -} -const GLubyte *hacked2_glGetString(GLenum name) { - if (name == GL_EXTENSIONS) { - static GLubyte* extensions = NULL; - // no extensions. - return ""; - } else { - return glGetString(name); - } -} -void *proc_resolver(void* userdata, const char* name) { - if (name == NULL) return NULL; + if (extensions == NULL) { + GLubyte *orig_extensions = (GLubyte *) glGetString(GL_EXTENSIONS); + + extensions = malloc(strlen(orig_extensions) + 1); + if (!extensions) { + fprintf(stderr, "Could not allocate memory for modified GL_EXTENSIONS string\n"); + return NULL; + } - static int is_videocore4 = -1; - static int is_videocore6 = -1; + strcpy(extensions, orig_extensions); + + /* + * working (apparently) + */ + //cut_word_from_string(extensions, "GL_EXT_blend_minmax"); + //cut_word_from_string(extensions, "GL_EXT_multi_draw_arrays"); + //cut_word_from_string(extensions, "GL_EXT_texture_format_BGRA8888"); + //cut_word_from_string(extensions, "GL_OES_compressed_ETC1_RGB8_texture"); + //cut_word_from_string(extensions, "GL_OES_depth24"); + //cut_word_from_string(extensions, "GL_OES_texture_npot"); + //cut_word_from_string(extensions, "GL_OES_vertex_half_float"); + //cut_word_from_string(extensions, "GL_OES_EGL_image"); + //cut_word_from_string(extensions, "GL_OES_depth_texture"); + //cut_word_from_string(extensions, "GL_AMD_performance_monitor"); + //cut_word_from_string(extensions, "GL_OES_EGL_image_external"); + //cut_word_from_string(extensions, "GL_EXT_occlusion_query_boolean"); + //cut_word_from_string(extensions, "GL_KHR_texture_compression_astc_ldr"); + //cut_word_from_string(extensions, "GL_EXT_compressed_ETC1_RGB8_sub_texture"); + //cut_word_from_string(extensions, "GL_EXT_draw_elements_base_vertex"); + //cut_word_from_string(extensions, "GL_EXT_texture_border_clamp"); + //cut_word_from_string(extensions, "GL_OES_draw_elements_base_vertex"); + //cut_word_from_string(extensions, "GL_OES_texture_border_clamp"); + //cut_word_from_string(extensions, "GL_KHR_texture_compression_astc_sliced_3d"); + //cut_word_from_string(extensions, "GL_MESA_tile_raster_order"); + + /* + * should be working, but isn't + */ + cut_word_from_string(extensions, "GL_EXT_map_buffer_range"); + + /* + * definitely broken + */ + cut_word_from_string(extensions, "GL_OES_element_index_uint"); + cut_word_from_string(extensions, "GL_OES_fbo_render_mipmap"); + cut_word_from_string(extensions, "GL_OES_mapbuffer"); + cut_word_from_string(extensions, "GL_OES_rgb8_rgba8"); + cut_word_from_string(extensions, "GL_OES_stencil8"); + cut_word_from_string(extensions, "GL_OES_texture_3D"); + cut_word_from_string(extensions, "GL_OES_packed_depth_stencil"); + cut_word_from_string(extensions, "GL_OES_get_program_binary"); + cut_word_from_string(extensions, "GL_APPLE_texture_max_level"); + cut_word_from_string(extensions, "GL_EXT_discard_framebuffer"); + cut_word_from_string(extensions, "GL_EXT_read_format_bgra"); + cut_word_from_string(extensions, "GL_EXT_frag_depth"); + cut_word_from_string(extensions, "GL_NV_fbo_color_attachments"); + cut_word_from_string(extensions, "GL_OES_EGL_sync"); + cut_word_from_string(extensions, "GL_OES_vertex_array_object"); + cut_word_from_string(extensions, "GL_EXT_unpack_subimage"); + cut_word_from_string(extensions, "GL_NV_draw_buffers"); + cut_word_from_string(extensions, "GL_NV_read_buffer"); + cut_word_from_string(extensions, "GL_NV_read_depth"); + cut_word_from_string(extensions, "GL_NV_read_depth_stencil"); + cut_word_from_string(extensions, "GL_NV_read_stencil"); + cut_word_from_string(extensions, "GL_EXT_draw_buffers"); + cut_word_from_string(extensions, "GL_KHR_debug"); + cut_word_from_string(extensions, "GL_OES_required_internalformat"); + cut_word_from_string(extensions, "GL_OES_surfaceless_context"); + cut_word_from_string(extensions, "GL_EXT_separate_shader_objects"); + cut_word_from_string(extensions, "GL_KHR_context_flush_control"); + cut_word_from_string(extensions, "GL_KHR_no_error"); + cut_word_from_string(extensions, "GL_KHR_parallel_shader_compile"); + } + + return extensions; +} +void *proc_resolver(void* userdata, const char* name) { + static int is_VC4 = -1; + void *address; /* * The mesa V3D driver reports some OpenGL ES extensions as supported and working * even though they aren't. hacked_glGetString is a workaround for this, which will * cut out the non-working extensions from the list of supported extensions. - */ + */ - if (is_videocore4 == -1) { - is_videocore4 = strcmp(egl.renderer, "VC4 V3D 2.1") == 0; - if (is_videocore4) printf("detected VideoCore IV as underlying graphics chip. Reporting modified GL_EXTENSIONS string that doesn't contain non-working extensions.\n"); - } - if (is_videocore6 == -1) { - is_videocore6 = strcmp(egl.renderer, "V3D 4.2") == 0; - if (is_videocore6) printf("detected VideoCore VI as underlying graphics chip. Reporting no GL Extensions.\n"); - } + if (name == NULL) + return NULL; - if (strcmp(name, "glGetString") == 0) { - if (is_videocore4) { - return hacked_glGetString; - } else if (is_videocore6) { - return hacked2_glGetString; - } - } + // first detect if we're running on a VideoCore 4 / using the VC4 driver. + if ((is_VC4 == -1) && (is_VC4 = strcmp(egl.renderer, "VC4 V3D 2.1") == 0)) + printf( "detected VideoCore IV as underlying graphics chip, and VC4 as the driver.\n" + "Reporting modified GL_EXTENSIONS string that doesn't contain non-working extensions.\n"); + + // if we do, and the symbol to resolve is glGetString, we return our hacked_glGetString. + if (is_VC4 && (strcmp(name, "glGetString") == 0)) + return hacked_glGetString; - void* address; - if ((address = dlsym(RTLD_DEFAULT, name)) || (address = eglGetProcAddress(name))) { + if ((address = dlsym(RTLD_DEFAULT, name)) || (address = eglGetProcAddress(name))) return address; - } - printf("could not resolve symbol %s\n", name); + fprintf(stderr, "proc_resolver: could not resolve symbol \"%s\"\n", name); return NULL; } -void on_platform_message(const FlutterPlatformMessage* message, void* userdata) { +void on_platform_message(const FlutterPlatformMessage* message, void* userdata) { int ok; if ((ok = PluginRegistry_onPlatformMessage((FlutterPlatformMessage *)message)) != 0) fprintf(stderr, "PluginRegistry_onPlatformMessage failed: %s\n", strerror(ok)); } -void vsync_callback(void* userdata, intptr_t baton) { +void vsync_callback(void* userdata, intptr_t baton) { // not yet implemented fprintf(stderr, "flutter vsync callback not yet implemented\n"); } @@ -436,10 +418,8 @@ void vsync_callback(void* userdata, intptr_t baton) { /************************ * PLATFORM TASK-RUNNER * ************************/ -void handle_sigusr1(int _) {} bool init_message_loop() { platform_thread_id = pthread_self(); - return true; } bool message_loop(void) {