static bool gfx_ctx_vc_image_buffer_write(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle) { bool ret = false; vc_ctx_data_t *vc = (vc_ctx_data_t*)data; if (!vc || index >= MAX_EGLIMAGE_TEXTURES) goto error; eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, vc->pbuff_surf, vc->pbuff_surf, vc->eglimage_ctx); if (!vc->eglBuffer[index] || !vc->vgimage[index]) { vc->vgimage[index] = vgCreateImage( rgb32 ? VG_sXRGB_8888 : VG_sRGB_565, vc->res, vc->res, VG_IMAGE_QUALITY_NONANTIALIASED); vc->eglBuffer[index] = peglCreateImageKHR( vc->egl.dpy, vc->eglimage_ctx, EGL_VG_PARENT_IMAGE_KHR, (EGLClientBuffer)vc->vgimage[index], NULL); ret = true; } vgImageSubData( vc->vgimage[index], frame, pitch, (rgb32 ? VG_sXRGB_8888 : VG_sRGB_565), 0, 0, width, height); *image_handle = vc->eglBuffer[index]; gfx_ctx_vc_bind_api(NULL, vc_api, 0, 0); eglMakeCurrent(vc->egl.dpy, vc->egl.surf, vc->egl.surf, vc->egl.ctx); return ret; error: *image_handle = NULL; return false; }
static bool gfx_ctx_vc_image_buffer_write(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle) { bool ret = false; if (index >= MAX_EGLIMAGE_TEXTURES) { *image_handle = NULL; return false; } eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(g_egl_dpy, g_pbuff_surf, g_pbuff_surf, g_eglimage_ctx); if (!eglBuffer[index] || !g_egl_vgimage[index]) { g_egl_vgimage[index] = vgCreateImage( rgb32 ? VG_sXRGB_8888 : VG_sRGB_565, g_egl_res, g_egl_res, VG_IMAGE_QUALITY_NONANTIALIASED); eglBuffer[index] = peglCreateImageKHR( g_egl_dpy, g_eglimage_ctx, EGL_VG_PARENT_IMAGE_KHR, (EGLClientBuffer)g_egl_vgimage[index], NULL); ret = true; } vgImageSubData( g_egl_vgimage[index], frame, pitch, (rgb32 ? VG_sXRGB_8888 : VG_sRGB_565), 0, 0, width, height); *image_handle = eglBuffer[index]; gfx_ctx_vc_bind_api(data, g_api, 0, 0); eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx); return ret; }
static bool gfx_ctx_vc_image_buffer_init(void *data, const video_info_t *video) { EGLBoolean result; vc_ctx_data_t *vc = (vc_ctx_data_t*)data; EGLint pbufsurface_list[] = { EGL_WIDTH, vc->res, EGL_HEIGHT, vc->res, EGL_NONE }; /* Don't bother, we just use VGImages for our EGLImage anyway. */ if (vc_api == GFX_CTX_OPENVG_API) return false; peglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)egl_get_proc_address("eglCreateImageKHR"); peglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)egl_get_proc_address("eglDestroyImageKHR"); if ( !peglCreateImageKHR || !peglDestroyImageKHR || !gfx_ctx_vc_egl_query_extension(vc, "KHR_image") ) return false; vc->res = video->input_scale * RARCH_SCALE_BASE; eglBindAPI(EGL_OPENVG_API); vc->pbuff_surf = eglCreatePbufferSurface(vc->egl.dpy, vc->egl.config, pbufsurface_list); if (vc->pbuff_surf == EGL_NO_SURFACE) { RARCH_ERR("[VideoCore:EGLImage] failed to create PbufferSurface\n"); goto fail; } vc->eglimage_ctx = eglCreateContext(vc->egl.dpy, vc->egl.config, NULL, NULL); if (vc->eglimage_ctx == EGL_NO_CONTEXT) { RARCH_ERR("[VideoCore:EGLImage] failed to create context\n"); goto fail; } /* Test to make sure we can switch context. */ result = eglMakeCurrent(vc->egl.dpy, vc->pbuff_surf, vc->pbuff_surf, vc->eglimage_ctx); if (result == EGL_FALSE) { RARCH_ERR("[VideoCore:EGLImage] failed to make context current\n"); goto fail; } gfx_ctx_vc_bind_api(NULL, vc_api, 0, 0); eglMakeCurrent(vc->egl.dpy, vc->egl.surf, vc->egl.surf, vc->egl.ctx); vc->smooth = video->smooth; return true; fail: if (vc->pbuff_surf != EGL_NO_SURFACE) { eglDestroySurface(vc->egl.dpy, vc->pbuff_surf); vc->pbuff_surf = EGL_NO_SURFACE; } if (vc->eglimage_ctx != EGL_NO_CONTEXT) { eglDestroyContext(vc->egl.dpy, vc->eglimage_ctx); vc->pbuff_surf = EGL_NO_CONTEXT; } gfx_ctx_vc_bind_api(NULL, vc_api, 0, 0); eglMakeCurrent(vc->egl.dpy, vc->egl.surf, vc->egl.surf, vc->egl.ctx); return false; }
static void gfx_ctx_vc_destroy(void *data) { vc_ctx_data_t *vc = (vc_ctx_data_t*)data; unsigned i; if (!vc) { g_egl_inited = false; return; } if (vc->egl.dpy) { for (i = 0; i < MAX_EGLIMAGE_TEXTURES; i++) { if (vc->eglBuffer[i] && peglDestroyImageKHR) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, vc->pbuff_surf, vc->pbuff_surf, vc->eglimage_ctx); peglDestroyImageKHR(vc->egl.dpy, vc->eglBuffer[i]); } if (vc->vgimage[i]) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, vc->pbuff_surf, vc->pbuff_surf, vc->eglimage_ctx); vgDestroyImage(vc->vgimage[i]); } } if (vc->egl.ctx) { gfx_ctx_vc_bind_api(data, vc_api, 0, 0); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(vc->egl.dpy, vc->egl.ctx); } if (vc->egl.hw_ctx) eglDestroyContext(vc->egl.dpy, vc->egl.hw_ctx); if (vc->eglimage_ctx) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(vc->egl.dpy, vc->eglimage_ctx); } if (vc->egl.surf) { gfx_ctx_vc_bind_api(data, vc_api, 0, 0); eglDestroySurface(vc->egl.dpy, vc->egl.surf); } if (vc->pbuff_surf) { eglBindAPI(EGL_OPENVG_API); eglDestroySurface(vc->egl.dpy, vc->pbuff_surf); } eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); gfx_ctx_vc_bind_api(data, vc_api, 0, 0); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglTerminate(vc->egl.dpy); } vc->egl.ctx = NULL; vc->egl.hw_ctx = NULL; vc->eglimage_ctx = NULL; vc->egl.surf = NULL; vc->pbuff_surf = NULL; vc->egl.dpy = NULL; vc->egl.config = 0; g_egl_inited = false; for (i = 0; i < MAX_EGLIMAGE_TEXTURES; i++) { vc->eglBuffer[i] = NULL; vc->vgimage[i] = 0; } /* Stop generating vsync callbacks if we are doing so. * Don't destroy the context while cbs are being generated! */ if (vc->vsync_callback_set) vc_dispmanx_vsync_callback(vc->dispman_display, NULL, NULL); /* Destroy mutexes and conditions. */ slock_free(vc->vsync_condition_mutex); scond_free(vc->vsync_condition); }
static void gfx_ctx_vc_destroy(void *data) { vc_ctx_data_t *vc = (vc_ctx_data_t*)data; unsigned i; if (!vc) { g_egl_inited = false; return; } if (vc->egl.dpy) { for (i = 0; i < MAX_EGLIMAGE_TEXTURES; i++) { if (vc->eglBuffer[i] && peglDestroyImageKHR) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, vc->pbuff_surf, vc->pbuff_surf, vc->eglimage_ctx); peglDestroyImageKHR(vc->egl.dpy, vc->eglBuffer[i]); } if (vc->vgimage[i]) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, vc->pbuff_surf, vc->pbuff_surf, vc->eglimage_ctx); vgDestroyImage(vc->vgimage[i]); } } if (vc->egl.ctx) { gfx_ctx_vc_bind_api(data, vc_api, 0, 0); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(vc->egl.dpy, vc->egl.ctx); } if (vc->egl.hw_ctx) eglDestroyContext(vc->egl.dpy, vc->egl.hw_ctx); if (vc->eglimage_ctx) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(vc->egl.dpy, vc->eglimage_ctx); } if (vc->egl.surf) { gfx_ctx_vc_bind_api(data, vc_api, 0, 0); eglDestroySurface(vc->egl.dpy, vc->egl.surf); } if (vc->pbuff_surf) { eglBindAPI(EGL_OPENVG_API); eglDestroySurface(vc->egl.dpy, vc->pbuff_surf); } eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); gfx_ctx_vc_bind_api(data, vc_api, 0, 0); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglTerminate(vc->egl.dpy); } vc->egl.ctx = NULL; vc->egl.hw_ctx = NULL; vc->eglimage_ctx = NULL; vc->egl.surf = NULL; vc->pbuff_surf = NULL; vc->egl.dpy = NULL; vc->egl.config = 0; g_egl_inited = false; for (i = 0; i < MAX_EGLIMAGE_TEXTURES; i++) { vc->eglBuffer[i] = NULL; vc->vgimage[i] = 0; } }
static void gfx_ctx_vc_destroy(void *data) { (void)data; unsigned i; if (g_egl_dpy) { for (i = 0; i < MAX_EGLIMAGE_TEXTURES; i++) { if (eglBuffer[i] && peglDestroyImageKHR) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(g_egl_dpy, g_pbuff_surf, g_pbuff_surf, g_eglimage_ctx); peglDestroyImageKHR(g_egl_dpy, eglBuffer[i]); } if (g_egl_vgimage[i]) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(g_egl_dpy, g_pbuff_surf, g_pbuff_surf, g_eglimage_ctx); vgDestroyImage(g_egl_vgimage[i]); } } if (g_egl_ctx) { gfx_ctx_vc_bind_api(data, g_api, 0, 0); eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(g_egl_dpy, g_egl_ctx); } if (g_egl_hw_ctx) eglDestroyContext(g_egl_dpy, g_egl_hw_ctx); if (g_eglimage_ctx) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(g_egl_dpy, g_eglimage_ctx); } if (g_egl_surf) { gfx_ctx_vc_bind_api(data, g_api, 0, 0); eglDestroySurface(g_egl_dpy, g_egl_surf); } if (g_pbuff_surf) { eglBindAPI(EGL_OPENVG_API); eglDestroySurface(g_egl_dpy, g_pbuff_surf); } eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); gfx_ctx_vc_bind_api(data, g_api, 0, 0); eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglTerminate(g_egl_dpy); } g_egl_ctx = NULL; g_egl_hw_ctx = NULL; g_eglimage_ctx = NULL; g_egl_surf = NULL; g_pbuff_surf = NULL; g_egl_dpy = NULL; g_egl_config = 0; g_inited = false; for (i = 0; i < MAX_EGLIMAGE_TEXTURES; i++) { eglBuffer[i] = NULL; g_egl_vgimage[i] = 0; } }