VideoCore EGLImage, still needs EGLImage support in GL driver

This commit is contained in:
Toad King 2012-10-19 21:24:28 -04:00
parent 301848e037
commit faf1b47d61
11 changed files with 160 additions and 66 deletions

View File

@ -307,7 +307,7 @@ static bool gfx_ctx_has_focus(void)
return true; return true;
} }
static bool gfx_ctx_can_egl_image_buffer(void) static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
{ {
return false; return false;
} }
@ -332,7 +332,7 @@ const gfx_ctx_driver_t gfx_ctx_android = {
gfx_ctx_swap_buffers, gfx_ctx_swap_buffers,
gfx_ctx_input_driver, gfx_ctx_input_driver,
NULL, NULL,
gfx_ctx_can_egl_image_buffer, gfx_ctx_init_egl_image_buffer,
gfx_ctx_write_egl_image, gfx_ctx_write_egl_image,
"android", "android",
}; };

View File

@ -625,7 +625,7 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
} }
} }
static bool gfx_ctx_can_egl_image_buffer(void) static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
{ {
return false; return false;
} }
@ -650,7 +650,7 @@ const gfx_ctx_driver_t gfx_ctx_drm_egl = {
gfx_ctx_swap_buffers, gfx_ctx_swap_buffers,
gfx_ctx_input_driver, gfx_ctx_input_driver,
gfx_ctx_get_proc_address, gfx_ctx_get_proc_address,
gfx_ctx_can_egl_image_buffer, gfx_ctx_init_egl_image_buffer,
gfx_ctx_write_egl_image, gfx_ctx_write_egl_image,
"drm-egl", "drm-egl",
}; };

View File

@ -462,7 +462,7 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
return api == GFX_CTX_OPENGL_API; return api == GFX_CTX_OPENGL_API;
} }
static bool gfx_ctx_can_egl_image_buffer(void) static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
{ {
return false; return false;
} }
@ -487,7 +487,7 @@ const gfx_ctx_driver_t gfx_ctx_glx = {
gfx_ctx_swap_buffers, gfx_ctx_swap_buffers,
gfx_ctx_input_driver, gfx_ctx_input_driver,
gfx_ctx_get_proc_address, gfx_ctx_get_proc_address,
gfx_ctx_can_egl_image_buffer, gfx_ctx_init_egl_image_buffer,
gfx_ctx_write_egl_image, gfx_ctx_write_egl_image,
"glx", "glx",
}; };

View File

@ -378,7 +378,7 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
return api == GFX_CTX_OPENGL_API || GFX_CTX_OPENGL_ES_API; return api == GFX_CTX_OPENGL_API || GFX_CTX_OPENGL_ES_API;
} }
static bool gfx_ctx_can_egl_image_buffer(void) static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
{ {
return false; return false;
} }
@ -403,7 +403,7 @@ const gfx_ctx_driver_t gfx_ctx_ps3 = {
gfx_ctx_swap_buffers, gfx_ctx_swap_buffers,
gfx_ctx_input_driver, gfx_ctx_input_driver,
NULL, NULL,
gfx_ctx_can_egl_image_buffer, gfx_ctx_init_egl_image_buffer,
gfx_ctx_write_egl_image, gfx_ctx_write_egl_image,
"ps3", "ps3",

View File

@ -316,7 +316,7 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
return api == GFX_CTX_OPENGL_API; return api == GFX_CTX_OPENGL_API;
} }
static bool gfx_ctx_can_egl_image_buffer(void) static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
{ {
return false; return false;
} }
@ -341,7 +341,7 @@ const gfx_ctx_driver_t gfx_ctx_sdl_gl = {
gfx_ctx_swap_buffers, gfx_ctx_swap_buffers,
gfx_ctx_input_driver, gfx_ctx_input_driver,
gfx_ctx_get_proc_address, gfx_ctx_get_proc_address,
gfx_ctx_can_egl_image_buffer, gfx_ctx_init_egl_image_buffer,
gfx_ctx_write_egl_image, gfx_ctx_write_egl_image,
"sdl-gl", "sdl-gl",
}; };

View File

@ -34,6 +34,7 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EGL/eglext.h> #include <EGL/eglext.h>
#include <EGL/eglext_brcm.h> #include <EGL/eglext_brcm.h>
#include <VG/openvg.h>
#include <bcm_host.h> #include <bcm_host.h>
static EGLContext g_egl_ctx; static EGLContext g_egl_ctx;
@ -46,15 +47,13 @@ static bool g_inited;
static unsigned g_interval; static unsigned g_interval;
static enum gfx_ctx_api g_api; static enum gfx_ctx_api g_api;
static unsigned g_fb_width; // Just use something for now. static unsigned g_fb_width;
static unsigned g_fb_height; static unsigned g_fb_height;
/*static EGLImageKHR eglBuffer; static EGLImageKHR eglBuffer;
static DISPMANX_RESOURCE_HANDLE_T vcBuffer; static EGLContext g_eglimage_ctx;
static VC_RECT_T bufferRect; static EGLSurface g_pbuff_surf;
static unsigned bufferLastWidth; static VGImage g_egl_vgimage;
static unsigned bufferLastHeight;
static bool bufferLastRgb32;
PFNEGLCREATEIMAGEKHRPROC peglCreateImageKHR; PFNEGLCREATEIMAGEKHRPROC peglCreateImageKHR;
PFNEGLDESTROYIMAGEKHRPROC peglDestroyImageKHR; PFNEGLDESTROYIMAGEKHRPROC peglDestroyImageKHR;
@ -67,7 +66,7 @@ static inline bool gfx_ctx_egl_query_extension(const char *ext)
ext, ret ? "exists" : "doesn't exist"); ext, ret ? "exists" : "doesn't exist");
return ret; return ret;
}*/ }
static void sighandler(int sig) static void sighandler(int sig)
{ {
@ -238,22 +237,63 @@ static bool gfx_ctx_set_video_mode(
static void gfx_ctx_destroy(void) static void gfx_ctx_destroy(void)
{ {
if (g_egl_dpy) if (g_egl_dpy)
{ {
if (eglBuffer && peglDestroyImageKHR)
{
eglBindAPI(EGL_OPENGL_VG_API);
eglMakeCurrent(g_egl_dpy, g_pbuff_surf, g_pbuff_surf, g_eglimage_ctx);
peglDestroyImageKHR(e_egl_dpy, eglBuffer);
}
if (g_egl_vgimage)
{
eglBindAPI(EGL_OPENGL_VG_API);
eglMakeCurrent(g_egl_dpy, g_pbuff_surf, g_pbuff_surf, g_eglimage_ctx);
vgDestroyImage(g_egl_vgimage);
}
if (g_egl_ctx) if (g_egl_ctx)
{ {
gfx_ctx_bind_api(g_api);
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(g_egl_dpy, g_egl_ctx); eglDestroyContext(g_egl_dpy, g_egl_ctx);
} }
if (g_eglimage_ctx)
{
eglBindAPI(EGL_OPENGL_VG_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) if (g_egl_surf)
{
gfx_ctx_bind_api(g_api);
eglDestroySurface(g_egl_dpy, g_egl_surf); eglDestroySurface(g_egl_dpy, g_egl_surf);
}
if (g_pbuff_surf)
{
eglBindAPI(EGL_OPENGL_VG_API);
eglDestroySurface(g_egl_dpy, g_pbuff_surf);
}
eglBindAPI(EGL_OPENGL_VG_API);
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
gfx_ctx_bind_api(g_api);
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglTerminate(g_egl_dpy); eglTerminate(g_egl_dpy);
} }
g_egl_ctx = NULL; g_egl_ctx = NULL;
g_eglimage_ctx = NULL
g_egl_surf = NULL; g_egl_surf = NULL;
g_pbuff_surf = NULL;
g_egl_dpy = NULL; g_egl_dpy = NULL;
eglBuffer = NULL;
g_egl_vgimage = NULL;
g_config = 0; g_config = 0;
g_inited = false; g_inited = false;
} }
@ -300,49 +340,103 @@ static float gfx_ctx_translate_aspect(unsigned width, unsigned height)
return (float)width / height; return (float)width / height;
} }
static bool gfx_ctx_can_egl_image_buffer(void) static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
{ {
/*peglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)gfx_ctx_get_proc_address("eglCreateImageKHR"); if (g_api == GFX_CTX_OPENVG_API) // don't bother, we just use VGImages for our EGLImage anyway
{
return false;
}
peglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)gfx_ctx_get_proc_address("eglCreateImageKHR");
peglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)gfx_ctx_get_proc_address("eglDestroyImageKHR"); peglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)gfx_ctx_get_proc_address("eglDestroyImageKHR");
return peglCreateImageKHR && peglDestroyImageKHR && gfx_ctx_egl_query_extension("KHR_image");*/
if (!peglCreateImageKHR || !peglDestroyImageKHR || !gfx_ctx_egl_query_extension("KHR_image"))
{
return false;
}
unsigned res = video->input_scale * RARCH_SCALE_BASE;
EGLint pbufsurface_list[] =
{
EGL_WIDTH, res,
EGL_HEIGHT, res,
EGL_NONE
};
EGLBoolean result;
eglBindAPI(EGL_OPENVG_API);
g_pbuff_surf = eglCreatePbufferSurface(g_egl_dpy, g_config, pbufsurface_list);
if (g_pbuff_surf == EGL_NO_SURFACE)
{
RARCH_ERR("[VideoCore:EGLImage] failed to create PbufferSurface\n");
goto fail;
}
g_eglimage_ctx = eglCreateContext(g_egl_dpy, g_config, NULL, NULL);
if (g_eglimage_ctx == EGL_NO_CONTEXT)
{
RARCH_ERR("[VideoCore:EGLImage] failed to create context\n");
goto fail;
}
result = eglMakeCurrent(g_egl_dpy, g_pbuff_surf, g_pbuff_surf, g_eglimage_ctx);
if (result == EGL_FALSE)
{
RARCH_ERR("[VideoCore:EGLImage] failed to make context current\n");
goto fail;
}
g_egl_vgimage = vgCreateImage(VG_sXRGB_8888, res, res, video->smooth ? VG_IMAGE_QUALITY_BETTER : VG_IMAGE_QUALITY_NONANTIALIASED);
eglBuffer = peglCreateImageKHR(g_egl_dpy, g_eglimage_ctx, EGL_VG_PARENT_IMAGE_KHR, (EGLClientBuffer)g_egl_vgimage, NULL);
gfx_ctx_bind_api(g_api);
eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx);
return true;
fail:
if (g_pbuff_surf != EGL_NO_SURFACE)
{
eglDestroySurface(g_egl_dpy, g_pbuff_surf);
g_pbuff_surf = EGL_NO_SURFACE;
}
if (g_eglimage_ctx != EGL_NO_CONTEXT)
{
eglDestroyContext(g_egl_dpy, g_eglimage_ctx);
g_pbuff_surf = EGL_NO_CONTEXT;
}
gfx_ctx_bind_api(g_api);
eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx);
return false; return false;
} }
static bool gfx_ctx_write_egl_image(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, void **image_handle) static bool gfx_ctx_write_egl_image(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, void **image_handle)
{ {
/*bool ret = false; static bool first = true;
if (!eglBuffer || !vcBuffer || (width != bufferLastWidth && height != bufferLastHeight && rgb32 != bufferLastRgb32)) eglBindAPI(EGL_OPENVG_API);
{ eglMakeCurrent(g_egl_dpy, g_pbuff_surf, g_pbuff_surf, g_eglimage_ctx);
ret = true;
if (vcBuffer) vgImageSubData(g_egl_vgimage, frame, pitch, (rgb32 ? VG_sXRGB_8888 : VG_sARGB_1555), 0, 0, width, height);
{
vc_dispmanx_resource_delete(vcBuffer);
}
if (eglBuffer)
{
peglDestroyImageKHR(g_egl_dpy, eglBuffer);
}
uint32_t temp = 0xff;
vcBuffer = vc_dispmanx_resource_create((rgb32 ? VC_IMAGE_XRGB8888 : VC_IMAGE_RGB565), width, height, &temp);
rarch_assert(vcBuffer);
RARCH_LOG("temp: %08x\n", temp);
eglBuffer = peglCreateImageKHR(g_egl_dpy, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_CLIENT_SIDE_BRCM, (EGLClientBuffer) &vcBuffer, NULL);
RARCH_ERR("ERROR: %08x\n", eglGetError());
rarch_assert(eglBuffer);
vc_dispmanx_rect_set(&bufferRect, 0, 0, width, height);
}
vc_dispmanx_resource_write_data(vcBuffer, (rgb32 ? VC_IMAGE_XRGB8888 : VC_IMAGE_RGB565), pitch, (void *)frame, &bufferRect);
*image_handle = eglBuffer; *image_handle = eglBuffer;
return ret;*/ gfx_ctx_bind_api(g_api);
eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx);
if (first)
{
first = false;
return true;
}
else
{
return false; return false;
} }
}
const gfx_ctx_driver_t gfx_ctx_videocore = { const gfx_ctx_driver_t gfx_ctx_videocore = {
gfx_ctx_init, gfx_ctx_init,
@ -359,7 +453,7 @@ const gfx_ctx_driver_t gfx_ctx_videocore = {
gfx_ctx_swap_buffers, gfx_ctx_swap_buffers,
gfx_ctx_input_driver, gfx_ctx_input_driver,
gfx_ctx_get_proc_address, gfx_ctx_get_proc_address,
gfx_ctx_can_egl_image_buffer, gfx_ctx_init_egl_image_buffer,
gfx_ctx_write_egl_image, gfx_ctx_write_egl_image,
"videocore", "videocore",
}; };

View File

@ -404,7 +404,7 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
return api == GFX_CTX_OPENGL_API; return api == GFX_CTX_OPENGL_API;
} }
static bool gfx_ctx_can_egl_image_buffer(void) static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
{ {
return false; return false;
} }
@ -429,7 +429,7 @@ const gfx_ctx_driver_t gfx_ctx_wgl = {
gfx_ctx_swap_buffers, gfx_ctx_swap_buffers,
gfx_ctx_input_driver, gfx_ctx_input_driver,
gfx_ctx_get_proc_address, gfx_ctx_get_proc_address,
gfx_ctx_can_egl_image_buffer, gfx_ctx_init_egl_image_buffer,
gfx_ctx_write_egl_image, gfx_ctx_write_egl_image,
"wgl", "wgl",
}; };

View File

@ -525,7 +525,7 @@ int gfx_ctx_xdk_check_resolution(unsigned resolution_id)
return 0; return 0;
} }
static bool gfx_ctx_can_egl_image_buffer(void) static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
{ {
return false; return false;
} }
@ -550,7 +550,7 @@ const gfx_ctx_driver_t gfx_ctx_xdk = {
gfx_ctx_xdk_swap_buffers, gfx_ctx_xdk_swap_buffers,
gfx_ctx_xdk_input_driver, gfx_ctx_xdk_input_driver,
NULL, NULL,
gfx_ctx_can_egl_image_buffer, gfx_ctx_init_egl_image_buffer,
gfx_ctx_write_egl_image, gfx_ctx_write_egl_image,
"xdk", "xdk",

View File

@ -503,7 +503,7 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
} }
} }
static bool gfx_ctx_can_egl_image_buffer(void) static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
{ {
return false; return false;
} }
@ -528,7 +528,7 @@ const gfx_ctx_driver_t gfx_ctx_x_egl = {
gfx_ctx_swap_buffers, gfx_ctx_swap_buffers,
gfx_ctx_input_driver, gfx_ctx_input_driver,
gfx_ctx_get_proc_address, gfx_ctx_get_proc_address,
gfx_ctx_can_egl_image_buffer, gfx_ctx_init_egl_image_buffer,
gfx_ctx_write_egl_image, gfx_ctx_write_egl_image,
"x-egl", "x-egl",
}; };

View File

@ -80,8 +80,8 @@ typedef struct gfx_ctx_driver
// Wraps whatever gl_proc_address() there is. // Wraps whatever gl_proc_address() there is.
gfx_ctx_proc_t (*get_proc_address)(const char*); gfx_ctx_proc_t (*get_proc_address)(const char*);
// Returns true if this context supports EGL Image buffers for screen drawing. // Returns true if this context supports EGL Image buffers for screen drawing and was initalized correctly.
bool (*can_egl_image_buffer)(void); bool (*init_egl_image_buffer)(const video_info_t*);
// Writes the frame to the EGL Image and sets image_handle to it. Returns true if a new image handle is created. // Writes the frame to the EGL Image and sets image_handle to it. Returns true if a new image handle is created.
// Always returns true the first time it's called. The graphics core must handle a change in the handle correctly. // Always returns true the first time it's called. The graphics core must handle a change in the handle correctly.

View File

@ -174,7 +174,7 @@ static void *vg_init(const video_info_t *video, const input_driver_t **input, vo
} }
#endif #endif
if (vg_query_extension("KHR_EGL_image") && vg->driver->can_egl_image_buffer()) if (vg_query_extension("KHR_EGL_image") && vg->driver->init_egl_image_buffer(video))
{ {
pvgCreateEGLImageTargetKHR = (PFNVGCREATEEGLIMAGETARGETKHRPROC)vg->driver->get_proc_address("vgCreateEGLImageTargetKHR"); pvgCreateEGLImageTargetKHR = (PFNVGCREATEEGLIMAGETARGETKHRPROC)vg->driver->get_proc_address("vgCreateEGLImageTargetKHR");
@ -356,7 +356,7 @@ static void vg_copy_frame(void *data, const void *frame, unsigned width, unsigne
if (new_egl) if (new_egl)
{ {
vgDestroyImage(vg->mImage); vgDestroyImage(vg->mImage);
RARCH_LOG("[VG] %08x\n", img); RARCH_LOG("[VG] %08x\n", (unsigned) img);
vg->mImage = pvgCreateEGLImageTargetKHR((VGeglImageKHR) img); vg->mImage = pvgCreateEGLImageTargetKHR((VGeglImageKHR) img);
if (!vg->mImage) if (!vg->mImage)
{ {