egl: Implement EGL_NOK_swap_region
This extension adds a new function which provides an alternative to eglSwapBuffers. eglSwapBuffersRegionNOK accepts two new parameters in addition to those in eglSwapBuffers. The new parameters consist of a pointer to a list of 4-integer blocks defining rectangles (x, y, width, height) and an integer specifying the number of rectangles in the list.
This commit is contained in:
@@ -227,6 +227,18 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLCont
|
||||
#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef EGL_NOK_swap_region
|
||||
#define EGL_NOK_swap_region 1
|
||||
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
|
||||
#endif
|
||||
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -51,6 +51,8 @@
|
||||
#include "eglsurface.h"
|
||||
#include "eglimage.h"
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
struct dri2_egl_driver
|
||||
{
|
||||
_EGLDriver base;
|
||||
@@ -778,6 +780,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
|
||||
disp->Extensions.KHR_image_pixmap = EGL_TRUE;
|
||||
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
|
||||
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
|
||||
disp->Extensions.NOK_swap_region = EGL_TRUE;
|
||||
|
||||
/* we're supporting EGL 1.4 */
|
||||
*major = 1;
|
||||
@@ -1067,7 +1070,8 @@ dri2_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
|
||||
}
|
||||
|
||||
static EGLBoolean
|
||||
dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
|
||||
dri2_copy_region(_EGLDriver *drv, _EGLDisplay *disp,
|
||||
_EGLSurface *draw, xcb_xfixes_region_t region)
|
||||
{
|
||||
struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
|
||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
@@ -1099,7 +1103,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
|
||||
|
||||
cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn,
|
||||
dri2_surf->drawable,
|
||||
dri2_surf->region,
|
||||
region,
|
||||
XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
|
||||
XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT);
|
||||
free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL));
|
||||
@@ -1107,6 +1111,44 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
static EGLBoolean
|
||||
dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
|
||||
{
|
||||
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
|
||||
|
||||
return dri2_copy_region(drv, disp, draw, dri2_surf->region);
|
||||
}
|
||||
|
||||
static EGLBoolean
|
||||
dri2_swap_buffers_region(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
|
||||
EGLint numRects, const EGLint *rects)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
|
||||
EGLBoolean ret;
|
||||
xcb_xfixes_region_t region;
|
||||
xcb_rectangle_t rectangles[16];
|
||||
int i;
|
||||
|
||||
if (numRects > ARRAY_SIZE(rectangles))
|
||||
return dri2_copy_region(drv, disp, draw, dri2_surf->region);
|
||||
|
||||
/* FIXME: Invert y here? */
|
||||
for (i = 0; i < numRects; i++) {
|
||||
rectangles[i].x = rects[i * 4];
|
||||
rectangles[i].y = rects[i * 4 + 1];
|
||||
rectangles[i].width = rects[i * 4 + 2];
|
||||
rectangles[i].height = rects[i * 4 + 3];
|
||||
}
|
||||
|
||||
region = xcb_generate_id(dri2_dpy->conn);
|
||||
xcb_xfixes_create_region(dri2_dpy->conn, region, numRects, rectangles);
|
||||
ret = dri2_copy_region(drv, disp, draw, region);
|
||||
xcb_xfixes_destroy_region(dri2_dpy->conn, region);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from eglGetProcAddress() via drv->API.GetProcAddress().
|
||||
*/
|
||||
@@ -1415,6 +1457,7 @@ _eglMain(const char *args)
|
||||
dri2_drv->base.API.ReleaseTexImage = dri2_release_tex_image;
|
||||
dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr;
|
||||
dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr;
|
||||
dri2_drv->base.API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
|
||||
|
||||
dri2_drv->base.Name = "DRI2";
|
||||
dri2_drv->base.Unload = dri2_unload;
|
||||
|
@@ -838,6 +838,9 @@ eglGetProcAddress(const char *procname)
|
||||
{ "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
|
||||
{ "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
|
||||
#endif /* EGL_KHR_image_base */
|
||||
#ifdef EGL_NOK_swap_region
|
||||
{ "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
|
||||
#endif
|
||||
{ NULL, NULL }
|
||||
};
|
||||
EGLint i;
|
||||
@@ -1246,3 +1249,32 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
|
||||
|
||||
|
||||
#endif /* EGL_KHR_image_base */
|
||||
|
||||
|
||||
#ifdef EGL_NOK_swap_region
|
||||
|
||||
EGLBoolean
|
||||
eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
|
||||
EGLint numRects, const EGLint *rects)
|
||||
{
|
||||
_EGLContext *ctx = _eglGetCurrentContext();
|
||||
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
||||
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
||||
_EGLDriver *drv;
|
||||
EGLBoolean ret;
|
||||
|
||||
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
||||
|
||||
/* surface must be bound to current context in EGL 1.4 */
|
||||
if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
|
||||
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
|
||||
|
||||
if (drv->API.SwapBuffersRegionNOK)
|
||||
ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
|
||||
else
|
||||
ret = drv->API.SwapBuffers(drv, disp, surf);
|
||||
|
||||
RETURN_EGL_EVAL(disp, ret);
|
||||
}
|
||||
|
||||
#endif /* EGL_NOK_swap_region */
|
||||
|
@@ -76,6 +76,9 @@ typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLCo
|
||||
typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
|
||||
#endif /* EGL_KHR_image_base */
|
||||
|
||||
#ifdef EGL_NOK_swap_region
|
||||
typedef EGLBoolean (*SwapBuffersRegionNOK_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The API dispatcher jumps through these functions
|
||||
@@ -134,6 +137,10 @@ struct _egl_api
|
||||
CreateImageKHR_t CreateImageKHR;
|
||||
DestroyImageKHR_t DestroyImageKHR;
|
||||
#endif /* EGL_KHR_image_base */
|
||||
|
||||
#ifdef EGL_NOK_swap_region
|
||||
SwapBuffersRegionNOK_t SwapBuffersRegionNOK;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* EGLAPI_INCLUDED */
|
||||
|
@@ -46,6 +46,7 @@ struct _egl_extensions
|
||||
EGLBoolean KHR_gl_texture_cubemap_image;
|
||||
EGLBoolean KHR_gl_texture_3D_image;
|
||||
EGLBoolean KHR_gl_renderbuffer_image;
|
||||
EGLBoolean NOK_swap_region;
|
||||
|
||||
char String[_EGL_MAX_EXTENSIONS_LEN];
|
||||
};
|
||||
|
@@ -96,6 +96,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
|
||||
_EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
|
||||
_EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
|
||||
|
||||
_EGL_CHECK_EXTENSION(NOK_swap_region);
|
||||
#undef _EGL_CHECK_EXTENSION
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user