Add copy_to_pixmap method to native_display and use it for eglCopyBuffers.tags/mesa-8.0-rc1
@@ -602,21 +602,6 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) | |||
gsurf->base.SwapInterval); | |||
} | |||
/** | |||
* Get the pipe surface of the given attachment of the native surface. | |||
*/ | |||
static struct pipe_resource * | |||
get_pipe_resource(struct native_display *ndpy, struct native_surface *nsurf, | |||
enum native_attachment natt) | |||
{ | |||
struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS]; | |||
textures[natt] = NULL; | |||
nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL); | |||
return textures[natt]; | |||
} | |||
static EGLBoolean | |||
egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, | |||
EGLNativePixmapType target) | |||
@@ -624,43 +609,18 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, | |||
struct egl_g3d_display *gdpy = egl_g3d_display(dpy); | |||
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); | |||
_EGLContext *ctx = _eglGetCurrentContext(); | |||
struct native_surface *nsurf; | |||
struct pipe_resource *ptex; | |||
struct pipe_context *pipe; | |||
if (!gsurf->render_texture) | |||
return EGL_TRUE; | |||
nsurf = gdpy->native->create_pixmap_surface(gdpy->native, target, NULL); | |||
if (!nsurf) | |||
return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); | |||
/* flush if the surface is current */ | |||
if (ctx && ctx->DrawSurface == &gsurf->base) { | |||
struct egl_g3d_context *gctx = egl_g3d_context(ctx); | |||
gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL); | |||
} | |||
pipe = ndpy_get_copy_context(gdpy->native); | |||
if (!pipe) | |||
return EGL_FALSE; | |||
ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); | |||
if (ptex) { | |||
struct pipe_box src_box; | |||
u_box_origin_2d(ptex->width0, ptex->height0, &src_box); | |||
pipe->resource_copy_region(pipe, ptex, 0, 0, 0, 0, | |||
gsurf->render_texture, 0, &src_box); | |||
pipe->flush(pipe, NULL); | |||
nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0); | |||
pipe_resource_reference(&ptex, NULL); | |||
} | |||
nsurf->destroy(nsurf); | |||
return EGL_TRUE; | |||
return gdpy->native->copy_to_pixmap(gdpy->native, | |||
target, gsurf->render_texture); | |||
} | |||
static EGLBoolean |
@@ -180,11 +180,22 @@ struct native_display { | |||
* | |||
* This function is usually called to find a config that supports a given | |||
* pixmap. Thus, it is usually called with the same pixmap in a row. | |||
* | |||
* TODO should be get_pixmap_format() and return the pipe format of the | |||
* pixmap. | |||
*/ | |||
boolean (*is_pixmap_supported)(struct native_display *ndpy, | |||
EGLNativePixmapType pix, | |||
const struct native_config *nconf); | |||
/** | |||
* Copy the contents of the resource to the pixmap's front-left attachment. | |||
* This is used to implement eglCopyBuffers. Required unless no config has | |||
* pixmap_bit set. | |||
*/ | |||
boolean (*copy_to_pixmap)(struct native_display *ndpy, | |||
EGLNativePixmapType pix, | |||
struct pipe_resource *src); | |||
/** | |||
* Create a window surface. Required unless no config has window_bit set. |
@@ -368,6 +368,47 @@ resource_surface_wait(struct resource_surface *rsurf) | |||
while (resource_surface_throttle(rsurf)); | |||
} | |||
boolean | |||
native_display_copy_to_pixmap(struct native_display *ndpy, | |||
EGLNativePixmapType pix, | |||
struct pipe_resource *src) | |||
{ | |||
struct pipe_context *pipe; | |||
struct native_surface *nsurf; | |||
struct pipe_resource *dst; | |||
struct pipe_resource *tmp[NUM_NATIVE_ATTACHMENTS]; | |||
const enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT; | |||
pipe = ndpy_get_copy_context(ndpy); | |||
if (!pipe) | |||
return FALSE; | |||
nsurf = ndpy->create_pixmap_surface(ndpy, pix, NULL); | |||
if (!nsurf) | |||
return FALSE; | |||
/* get the texutre */ | |||
tmp[natt] = NULL; | |||
nsurf->validate(nsurf, 1 << natt, NULL, tmp, NULL, NULL); | |||
dst = tmp[natt]; | |||
if (dst && dst->format == src->format) { | |||
struct pipe_box src_box; | |||
u_box_origin_2d(src->width0, src->height0, &src_box); | |||
pipe->resource_copy_region(pipe, dst, 0, 0, 0, 0, src, 0, &src_box); | |||
pipe->flush(pipe, NULL); | |||
nsurf->present(nsurf, natt, FALSE, 0); | |||
} | |||
if (dst) | |||
pipe_resource_reference(&dst, NULL); | |||
nsurf->destroy(nsurf); | |||
return TRUE; | |||
} | |||
#include "state_tracker/drm_driver.h" | |||
struct pipe_resource * | |||
drm_display_import_native_buffer(struct native_display *ndpy, |
@@ -106,6 +106,11 @@ resource_surface_flush(struct resource_surface *rsurf, | |||
void | |||
resource_surface_wait(struct resource_surface *rsurf); | |||
boolean | |||
native_display_copy_to_pixmap(struct native_display *ndpy, | |||
EGLNativePixmapType pix, | |||
struct pipe_resource *src); | |||
struct pipe_resource * | |||
drm_display_import_native_buffer(struct native_display *ndpy, | |||
struct native_buffer *nbuf); |
@@ -477,6 +477,7 @@ native_create_display(void *dpy, boolean use_sw) | |||
display->base.get_param = wayland_display_get_param; | |||
display->base.get_configs = wayland_display_get_configs; | |||
display->base.is_pixmap_supported = wayland_display_is_pixmap_supported; | |||
display->base.copy_to_pixmap = native_display_copy_to_pixmap; | |||
display->base.create_window_surface = wayland_create_window_surface; | |||
display->base.create_pixmap_surface = wayland_create_pixmap_surface; | |||
@@ -38,6 +38,7 @@ | |||
#include "native_x11.h" | |||
#include "x11_screen.h" | |||
#include "common/native_helper.h" | |||
#ifdef HAVE_WAYLAND_BACKEND | |||
#include "common/native_wayland_drm_bufmgr_helper.h" | |||
#endif | |||
@@ -909,6 +910,7 @@ x11_create_dri2_display(Display *dpy, | |||
dri2dpy->base.get_param = dri2_display_get_param; | |||
dri2dpy->base.get_configs = dri2_display_get_configs; | |||
dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported; | |||
dri2dpy->base.copy_to_pixmap = native_display_copy_to_pixmap; | |||
dri2dpy->base.create_window_surface = dri2_display_create_window_surface; | |||
dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface; | |||
#ifdef HAVE_WAYLAND_BACKEND |
@@ -542,6 +542,7 @@ x11_create_ximage_display(Display *dpy, | |||
xdpy->base.get_configs = ximage_display_get_configs; | |||
xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported; | |||
xdpy->base.copy_to_pixmap = native_display_copy_to_pixmap; | |||
xdpy->base.create_window_surface = ximage_display_create_window_surface; | |||
xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface; | |||