st/egl: make native_buffer interface typed

Use a typed struct to describe the native buffer and let the backends
map the native buffer to winsys_handle for
resource_from_handle/resource_to_handle.
This commit is contained in:
Chia-I Wu 2011-06-24 13:30:35 +09:00
parent 875a1f8960
commit febf5e4147
6 changed files with 137 additions and 87 deletions

View File

@ -137,10 +137,9 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name,
_EGLImage *img, const EGLint *attribs)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct pipe_resource templ;
struct winsys_handle wsh;
_EGLImageAttribs attrs;
EGLint format;
struct native_buffer nbuf;
if (!dpy->Extensions.MESA_drm_image)
return NULL;
@ -166,21 +165,21 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name,
break;
}
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.format = format;
templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
templ.width0 = attrs.Width;
templ.height0 = attrs.Height;
templ.depth0 = 1;
templ.array_size = 1;
memset(&nbuf, 0, sizeof(nbuf));
nbuf.type = NATIVE_BUFFER_DRM;
nbuf.u.drm.templ.target = PIPE_TEXTURE_2D;
nbuf.u.drm.templ.format = format;
nbuf.u.drm.templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
nbuf.u.drm.templ.width0 = attrs.Width;
nbuf.u.drm.templ.height0 = attrs.Height;
nbuf.u.drm.templ.depth0 = 1;
nbuf.u.drm.templ.array_size = 1;
memset(&wsh, 0, sizeof(wsh));
wsh.handle = (unsigned) name;
wsh.stride =
attrs.DRMBufferStrideMESA * util_format_get_blocksize(templ.format);
nbuf.u.drm.name = name;
nbuf.u.drm.stride =
attrs.DRMBufferStrideMESA * util_format_get_blocksize(format);
return gdpy->native->buffer->import_buffer(gdpy->native, &templ, &wsh);
return gdpy->native->buffer->import_buffer(gdpy->native, &nbuf);
}
#endif /* EGL_MESA_drm_image */
@ -327,35 +326,26 @@ egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img,
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_image *gimg = egl_g3d_image(img);
struct winsys_handle wsh;
struct native_buffer nbuf;
if (!dpy->Extensions.MESA_drm_image)
return EGL_FALSE;
/* get shared handle */
if (name) {
memset(&handle, 0, sizeof(handle));
wsh.type = DRM_API_HANDLE_TYPE_SHARED;
if (!gdpy->native->buffer->export_buffer(gdpy->native,
gimg->texture, &wsh))
return EGL_FALSE;
memset(&nbuf, 0, sizeof(nbuf));
nbuf.type = NATIVE_BUFFER_DRM;
if (name)
nbuf.u.drm.templ.bind |= PIPE_BIND_SHARED;
*name = wsh.handle;
}
if (!gdpy->native->buffer->export_buffer(gdpy->native,
gimg->texture, &nbuf))
return EGL_FALSE;
/* get KMS handle */
if (handle || stride) {
memset(&wsh, 0, sizeof(wsh));
wsh.type = DRM_API_HANDLE_TYPE_KMS;
if (!gdpy->native->buffer->export_buffer(gdpy->native,
gimg->texture, &wsh))
return EGL_FALSE;
if (handle)
*handle = wsh.handle;
if (stride)
*stride = wsh.stride;
}
if (name)
*name = nbuf.u.drm.name;
if (handle)
*handle = nbuf.u.drm.handle;
if (stride)
*stride = nbuf.u.drm.stride;
return EGL_TRUE;
}

View File

@ -30,30 +30,43 @@
#define _NATIVE_BUFFER_H_
#include "pipe/p_compiler.h"
#include "pipe/p_state.h"
struct native_display;
struct pipe_resource;
enum native_buffer_type {
NATIVE_BUFFER_DRM,
NUM_NATIVE_BUFFERS
};
struct native_buffer {
enum native_buffer_type type;
union {
struct {
struct pipe_resource templ;
unsigned name; /**< the name of the GEM object */
unsigned handle; /**< the handle of the GEM object */
unsigned stride;
} drm;
} u;
};
/**
* Buffer interface of the native display. It allows native buffers to be
* imported and exported.
*
* Just like a native window or a native pixmap, a native buffer is another
* native type. Its definition depends on the native display.
*
* For DRM platform, the type of a native buffer is struct winsys_handle.
*/
struct native_display_buffer {
struct pipe_resource *(*import_buffer)(struct native_display *ndpy,
const struct pipe_resource *templ,
void *buf);
struct native_buffer *buf);
/**
* The resource must be creatred with PIPE_BIND_SHARED.
*/
boolean (*export_buffer)(struct native_display *ndpy,
struct pipe_resource *res,
void *buf);
struct native_buffer *nbuf);
};
#endif /* _NATIVE_BUFFER_H_ */

View File

@ -367,3 +367,75 @@ resource_surface_wait(struct resource_surface *rsurf)
{
while (resource_surface_throttle(rsurf));
}
#include "state_tracker/drm_driver.h"
struct pipe_resource *
drm_display_import_native_buffer(struct native_display *ndpy,
struct native_buffer *nbuf)
{
struct pipe_screen *screen = ndpy->screen;
struct pipe_resource *res = NULL;
switch (nbuf->type) {
case NATIVE_BUFFER_DRM:
{
struct winsys_handle wsh;
memset(&wsh, 0, sizeof(wsh));
wsh.handle = nbuf->u.drm.name;
wsh.stride = nbuf->u.drm.stride;
res = screen->resource_from_handle(screen, &nbuf->u.drm.templ, &wsh);
}
break;
default:
break;
}
return res;
}
boolean
drm_display_export_native_buffer(struct native_display *ndpy,
struct pipe_resource *res,
struct native_buffer *nbuf)
{
struct pipe_screen *screen = ndpy->screen;
boolean ret = FALSE;
switch (nbuf->type) {
case NATIVE_BUFFER_DRM:
{
struct winsys_handle wsh;
if ((nbuf->u.drm.templ.bind & res->bind) != nbuf->u.drm.templ.bind)
break;
memset(&wsh, 0, sizeof(wsh));
wsh.type = DRM_API_HANDLE_TYPE_KMS;
if (!screen->resource_get_handle(screen, res, &wsh))
break;
nbuf->u.drm.handle = wsh.handle;
nbuf->u.drm.stride = wsh.stride;
/* get the name of the GEM object */
if (nbuf->u.drm.templ.bind & PIPE_BIND_SHARED) {
memset(&wsh, 0, sizeof(wsh));
wsh.type = DRM_API_HANDLE_TYPE_SHARED;
if (!screen->resource_get_handle(screen, res, &wsh))
break;
nbuf->u.drm.name = wsh.handle;
}
nbuf->u.drm.templ = *res;
ret = TRUE;
}
break;
default:
break;
}
return ret;
}

View File

@ -105,3 +105,12 @@ resource_surface_flush(struct resource_surface *rsurf,
*/
void
resource_surface_wait(struct resource_surface *rsurf);
struct pipe_resource *
drm_display_import_native_buffer(struct native_display *ndpy,
struct native_buffer *nbuf);
boolean
drm_display_export_native_buffer(struct native_display *ndpy,
struct pipe_resource *res,
struct native_buffer *nbuf);

View File

@ -138,27 +138,10 @@ drm_display_destroy(struct native_display *ndpy)
FREE(drmdpy);
}
static struct pipe_resource *
drm_display_import_buffer(struct native_display *ndpy,
const struct pipe_resource *templ,
void *buf)
{
return ndpy->screen->resource_from_handle(ndpy->screen,
templ, (struct winsys_handle *) buf);
}
static boolean
drm_display_export_buffer(struct native_display *ndpy,
struct pipe_resource *res,
void *buf)
{
return ndpy->screen->resource_get_handle(ndpy->screen,
res, (struct winsys_handle *) buf);
}
static struct native_display_buffer drm_display_buffer = {
drm_display_import_buffer,
drm_display_export_buffer
/* use the helpers */
drm_display_import_native_buffer,
drm_display_export_native_buffer
};
static int

View File

@ -212,27 +212,10 @@ wayland_drm_display_init_screen(struct native_display *ndpy)
return TRUE;
}
static struct pipe_resource *
wayland_drm_display_import_buffer(struct native_display *ndpy,
const struct pipe_resource *templ,
void *buf)
{
return ndpy->screen->resource_from_handle(ndpy->screen,
templ, (struct winsys_handle *) buf);
}
static boolean
wayland_drm_display_export_buffer(struct native_display *ndpy,
struct pipe_resource *res,
void *buf)
{
return ndpy->screen->resource_get_handle(ndpy->screen,
res, (struct winsys_handle *) buf);
}
static struct native_display_buffer wayland_drm_display_buffer = {
wayland_drm_display_import_buffer,
wayland_drm_display_export_buffer
/* use the helpers */
drm_display_import_native_buffer,
drm_display_export_native_buffer
};
static int