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
|
#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
|
||||||
#endif
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -51,6 +51,8 @@
|
|||||||
#include "eglsurface.h"
|
#include "eglsurface.h"
|
||||||
#include "eglimage.h"
|
#include "eglimage.h"
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||||
|
|
||||||
struct dri2_egl_driver
|
struct dri2_egl_driver
|
||||||
{
|
{
|
||||||
_EGLDriver base;
|
_EGLDriver base;
|
||||||
@@ -778,6 +780,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
|
|||||||
disp->Extensions.KHR_image_pixmap = EGL_TRUE;
|
disp->Extensions.KHR_image_pixmap = EGL_TRUE;
|
||||||
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
|
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
|
||||||
disp->Extensions.KHR_gl_texture_2D_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 */
|
/* we're supporting EGL 1.4 */
|
||||||
*major = 1;
|
*major = 1;
|
||||||
@@ -1067,7 +1070,8 @@ dri2_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static EGLBoolean
|
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_driver *dri2_drv = dri2_egl_driver(drv);
|
||||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
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,
|
cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn,
|
||||||
dri2_surf->drawable,
|
dri2_surf->drawable,
|
||||||
dri2_surf->region,
|
region,
|
||||||
XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
|
XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
|
||||||
XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT);
|
XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT);
|
||||||
free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL));
|
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;
|
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().
|
* 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.ReleaseTexImage = dri2_release_tex_image;
|
||||||
dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr;
|
dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr;
|
||||||
dri2_drv->base.API.DestroyImageKHR = dri2_destroy_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.Name = "DRI2";
|
||||||
dri2_drv->base.Unload = dri2_unload;
|
dri2_drv->base.Unload = dri2_unload;
|
||||||
|
@@ -838,6 +838,9 @@ eglGetProcAddress(const char *procname)
|
|||||||
{ "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
|
{ "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
|
||||||
{ "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
|
{ "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
|
||||||
#endif /* EGL_KHR_image_base */
|
#endif /* EGL_KHR_image_base */
|
||||||
|
#ifdef EGL_NOK_swap_region
|
||||||
|
{ "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
|
||||||
|
#endif
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
EGLint i;
|
EGLint i;
|
||||||
@@ -1246,3 +1249,32 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
|
|||||||
|
|
||||||
|
|
||||||
#endif /* EGL_KHR_image_base */
|
#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);
|
typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
|
||||||
#endif /* EGL_KHR_image_base */
|
#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
|
* The API dispatcher jumps through these functions
|
||||||
@@ -134,6 +137,10 @@ struct _egl_api
|
|||||||
CreateImageKHR_t CreateImageKHR;
|
CreateImageKHR_t CreateImageKHR;
|
||||||
DestroyImageKHR_t DestroyImageKHR;
|
DestroyImageKHR_t DestroyImageKHR;
|
||||||
#endif /* EGL_KHR_image_base */
|
#endif /* EGL_KHR_image_base */
|
||||||
|
|
||||||
|
#ifdef EGL_NOK_swap_region
|
||||||
|
SwapBuffersRegionNOK_t SwapBuffersRegionNOK;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* EGLAPI_INCLUDED */
|
#endif /* EGLAPI_INCLUDED */
|
||||||
|
@@ -46,6 +46,7 @@ struct _egl_extensions
|
|||||||
EGLBoolean KHR_gl_texture_cubemap_image;
|
EGLBoolean KHR_gl_texture_cubemap_image;
|
||||||
EGLBoolean KHR_gl_texture_3D_image;
|
EGLBoolean KHR_gl_texture_3D_image;
|
||||||
EGLBoolean KHR_gl_renderbuffer_image;
|
EGLBoolean KHR_gl_renderbuffer_image;
|
||||||
|
EGLBoolean NOK_swap_region;
|
||||||
|
|
||||||
char String[_EGL_MAX_EXTENSIONS_LEN];
|
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_texture_3D_image);
|
||||||
_EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
|
_EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
|
||||||
|
|
||||||
|
_EGL_CHECK_EXTENSION(NOK_swap_region);
|
||||||
#undef _EGL_CHECK_EXTENSION
|
#undef _EGL_CHECK_EXTENSION
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user