summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/egl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/egl')
-rw-r--r--src/gallium/state_trackers/egl/Makefile3
-rw-r--r--src/gallium/state_trackers/egl/SConscript5
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c60
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h8
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c141
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.c73
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_loader.h1
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.c2
-rw-r--r--src/gallium/state_trackers/egl/common/native.h50
-rw-r--r--src/gallium/state_trackers/egl/common/native_buffer.h31
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.c117
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.h14
-rw-r--r--src/gallium/state_trackers/egl/drm/modeset.c36
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.c124
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.h6
-rw-r--r--src/gallium/state_trackers/egl/fbdev/native_fbdev.c384
-rw-r--r--src/gallium/state_trackers/egl/gdi/native_gdi.c58
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_drm.c36
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_shm.c14
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_wayland.c48
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_wayland.h8
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c45
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c20
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.h6
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c109
25 files changed, 787 insertions, 612 deletions
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index 763e7b58a49..1c970222c1f 100644
--- a/src/gallium/state_trackers/egl/Makefile
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -33,7 +33,8 @@ wayland_INCLUDES = \
wayland_SOURCES = $(wildcard wayland/*.c)
wayland_OBJECTS = $(wayland_SOURCES:.c=.o)
-drm_INCLUDES = -I$(TOP)/src/gallium/winsys $(shell pkg-config --cflags-only-I libdrm)
+drm_INCLUDES = -I$(TOP)/src/gallium/winsys $(shell pkg-config --cflags-only-I libdrm) \
+ -I$(TOP)/src/gbm/main -I$(TOP)/src/gallium/state_trackers/gbm
drm_SOURCES = $(wildcard drm/*.c)
drm_OBJECTS = $(drm_SOURCES:.c=.o)
diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript
index 9ade76ecbb2..c04fec637c1 100644
--- a/src/gallium/state_trackers/egl/SConscript
+++ b/src/gallium/state_trackers/egl/SConscript
@@ -40,7 +40,12 @@ else:
env.Append(CPPDEFINES = ['GLX_DIRECT_RENDERING'])
sources.append(['#/src/glx/dri2.c'])
if env['drm']:
+ env.PkgUseModules('DRM')
env.Append(CPPDEFINES = ['HAVE_DRM_BACKEND'])
+ env.Append(CPPPATH = [
+ '#/src/gbm/main',
+ '#/src/gallium/state_trackers/gbm',
+ ])
sources.append(['drm/native_drm.c', 'drm/modeset.c'])
st_egl = env.ConvenienceLibrary(
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 29dbbefbf48..6649f02b244 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -31,6 +31,7 @@
#include "util/u_memory.h"
#include "util/u_format.h"
#include "util/u_string.h"
+#include "util/u_atomic.h"
#include "egl_g3d.h"
#include "egl_g3d_api.h"
@@ -45,15 +46,9 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
{
/* XXX not thread safe? */
struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
- struct egl_g3d_context *gctx;
-
- /*
- * Some functions such as egl_g3d_copy_buffers create a temporary native
- * surface. There is no gsurf associated with it.
- */
- gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
- if (gctx)
- gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
+
+ if (gsurf && gsurf->stfbi)
+ p_atomic_inc(&gsurf->stfbi->stamp);
}
static struct pipe_screen *
@@ -72,10 +67,26 @@ egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
return gdpy->loader->create_sw_screen(ws);
}
-static struct native_event_handler egl_g3d_native_event_handler = {
+static struct pipe_resource *
+egl_g3d_lookup_egl_image(struct native_display *ndpy, void *egl_image)
+{
+ _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct st_egl_image img;
+ struct pipe_resource *resource = NULL;
+
+ memset(&img, 0, sizeof(img));
+ if (gdpy->smapi->get_egl_image(gdpy->smapi, egl_image, &img))
+ resource = img.texture;
+
+ return resource;
+}
+
+static const struct native_event_handler egl_g3d_native_event_handler = {
egl_g3d_invalid_surface,
egl_g3d_new_drm_screen,
- egl_g3d_new_sw_screen
+ egl_g3d_new_sw_screen,
+ egl_g3d_lookup_egl_image
};
/**
@@ -94,40 +105,38 @@ egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat)
case _EGL_PLATFORM_WINDOWS:
plat_name = "Windows";
#ifdef HAVE_GDI_BACKEND
- nplat = native_get_gdi_platform();
+ nplat = native_get_gdi_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_X11:
plat_name = "X11";
#ifdef HAVE_X11_BACKEND
- nplat = native_get_x11_platform();
+ nplat = native_get_x11_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_WAYLAND:
plat_name = "wayland";
#ifdef HAVE_WAYLAND_BACKEND
- nplat = native_get_wayland_platform();
+ nplat = native_get_wayland_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_DRM:
plat_name = "DRM";
#ifdef HAVE_DRM_BACKEND
- nplat = native_get_drm_platform();
+ nplat = native_get_drm_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_FBDEV:
plat_name = "FBDEV";
#ifdef HAVE_FBDEV_BACKEND
- nplat = native_get_fbdev_platform();
+ nplat = native_get_fbdev_platform(&egl_g3d_native_event_handler);
#endif
break;
default:
break;
}
- if (nplat)
- nplat->set_event_handler(&egl_g3d_native_event_handler);
- else
+ if (!nplat)
_eglLog(_EGL_WARNING, "unsupported platform %s", plat_name);
gdrv->platforms[plat] = nplat;
@@ -504,13 +513,20 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
gdpy->loader = gdrv->loader;
dpy->DriverData = gdpy;
- _eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay);
- gdpy->native = nplat->create_display(dpy->PlatformDisplay,
- dpy->Options.UseFallback, (void *) dpy);
+ _eglLog(_EGL_INFO, "use %s for display %p",
+ nplat->name, dpy->PlatformDisplay);
+ gdpy->native =
+ nplat->create_display(dpy->PlatformDisplay, dpy->Options.UseFallback);
if (!gdpy->native) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
goto fail;
}
+ gdpy->native->user_data = (void *) dpy;
+ if (!gdpy->native->init_screen(gdpy->native)) {
+ _eglError(EGL_NOT_INITIALIZED,
+ "eglInitialize(failed to initialize screen)");
+ goto fail;
+ }
if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK)
dpy->ClientAPIs |= EGL_OPENGL_BIT;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index 301db3128ff..5989a023573 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -126,4 +126,12 @@ _EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj)
#endif /* EGL_MESA_screen_surface */
+static INLINE struct st_api *
+egl_g3d_get_st_api(_EGLDriver *drv, enum st_api_type api)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+
+ return gdrv->loader->get_st_api(api);
+}
+
#endif /* _EGL_G3D_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index 8b1821e0055..f897054a540 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -37,7 +37,6 @@
#include "egl_g3d_image.h"
#include "egl_g3d_sync.h"
#include "egl_g3d_st.h"
-#include "egl_g3d_loader.h"
#include "native.h"
/**
@@ -47,7 +46,6 @@ static struct st_api *
egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx,
enum st_profile_type *profile)
{
- struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct st_api *stapi;
EGLint api = -1;
@@ -81,96 +79,66 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx,
break;
}
- switch (api) {
- case ST_API_OPENGL:
- stapi = gdrv->loader->guess_gl_api(*profile);
- break;
- case ST_API_OPENVG:
- stapi = gdrv->loader->get_st_api(api);
- break;
- default:
- stapi = NULL;
- break;
- }
+ stapi = egl_g3d_get_st_api(drv, api);
if (stapi && !(stapi->profile_mask & (1 << *profile)))
stapi = NULL;
return stapi;
}
+struct egl_g3d_choose_config_data {
+ _EGLConfig criteria;
+ enum pipe_format format;
+};
+
static int
egl_g3d_compare_config(const _EGLConfig *conf1, const _EGLConfig *conf2,
void *priv_data)
{
- const _EGLConfig *criteria = (const _EGLConfig *) priv_data;
+ struct egl_g3d_choose_config_data *data =
+ (struct egl_g3d_choose_config_data *) priv_data;
+ const _EGLConfig *criteria = &data->criteria;;
/* EGL_NATIVE_VISUAL_TYPE ignored? */
return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE);
}
static EGLBoolean
-egl_g3d_match_config(const _EGLConfig *conf, const _EGLConfig *criteria)
+egl_g3d_match_config(const _EGLConfig *conf, void *priv_data)
{
- if (!_eglMatchConfig(conf, criteria))
- return EGL_FALSE;
-
- if (criteria->MatchNativePixmap != EGL_NONE &&
- criteria->MatchNativePixmap != EGL_DONT_CARE) {
- struct egl_g3d_display *gdpy = egl_g3d_display(conf->Display);
- struct egl_g3d_config *gconf = egl_g3d_config(conf);
- EGLNativePixmapType pix =
- (EGLNativePixmapType) criteria->MatchNativePixmap;
+ struct egl_g3d_choose_config_data *data =
+ (struct egl_g3d_choose_config_data *) priv_data;
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
- if (!gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native))
- return EGL_FALSE;
- }
+ if (data->format != PIPE_FORMAT_NONE &&
+ data->format != gconf->native->color_format)
+ return EGL_FALSE;
- return EGL_TRUE;
+ return _eglMatchConfig(conf, &data->criteria);
}
static EGLBoolean
egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
EGLConfig *configs, EGLint size, EGLint *num_configs)
{
- _EGLConfig **tmp_configs, criteria;
- EGLint tmp_size, i;
-
- if (!num_configs)
- return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs");
+ struct egl_g3d_choose_config_data data;
- if (!_eglParseConfigAttribList(&criteria, dpy, attribs))
+ if (!_eglParseConfigAttribList(&data.criteria, dpy, attribs))
return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
- /* get the number of matched configs */
- tmp_size = _eglFilterArray(dpy->Configs, NULL, 0,
- (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
- if (!tmp_size) {
- *num_configs = tmp_size;
- return EGL_TRUE;
- }
-
- tmp_configs = MALLOC(sizeof(tmp_configs[0]) * tmp_size);
- if (!tmp_configs)
- return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");
+ data.format = PIPE_FORMAT_NONE;
+ if (data.criteria.MatchNativePixmap != EGL_NONE &&
+ data.criteria.MatchNativePixmap != EGL_DONT_CARE) {
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- /* get the matched configs */
- _eglFilterArray(dpy->Configs, (void **) tmp_configs, tmp_size,
- (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
-
- /* perform sorting of configs */
- if (configs && tmp_size) {
- _eglSortConfigs((const _EGLConfig **) tmp_configs, tmp_size,
- egl_g3d_compare_config, (void *) &criteria);
- tmp_size = MIN2(tmp_size, size);
- for (i = 0; i < tmp_size; i++)
- configs[i] = _eglGetConfigHandle(tmp_configs[i]);
+ if (!gdpy->native->get_pixmap_format(gdpy->native,
+ (EGLNativePixmapType) data.criteria.MatchNativePixmap,
+ &data.format))
+ return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglChooseConfig");
}
- FREE(tmp_configs);
-
- *num_configs = tmp_size;
-
- return EGL_TRUE;
+ return _eglFilterConfigArray(dpy->Configs, configs, size, num_configs,
+ egl_g3d_match_config, egl_g3d_compare_config, &data);
}
static _EGLContext *
@@ -536,19 +504,12 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
(gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
if (ok) {
if (gdraw) {
- gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
- gdraw->stfbi);
-
if (gdraw->base.Type == EGL_WINDOW_BIT) {
gctx->base.WindowRenderBuffer =
(gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
}
}
- if (gread && gread != gdraw) {
- gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
- gread->stfbi);
- }
}
}
else if (old_gctx) {
@@ -614,21 +575,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)
@@ -636,43 +582,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
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
index ce72e27c3d5..7e9a29b0284 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -37,9 +37,6 @@
#include "egl_g3d.h"
#include "egl_g3d_image.h"
-/* for struct winsys_handle */
-#include "state_tracker/drm_driver.h"
-
/**
* Reference and return the front left buffer of the native pixmap.
*/
@@ -137,10 +134,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 +162,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(&wsh, 0, sizeof(wsh));
- wsh.handle = (unsigned) name;
- wsh.stride =
- attrs.DRMBufferStrideMESA * util_format_get_blocksize(templ.format);
-
- return gdpy->native->buffer->import_buffer(gdpy->native, &templ, &wsh);
+ 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;
+
+ nbuf.u.drm.name = name;
+ nbuf.u.drm.stride =
+ attrs.DRMBufferStrideMESA * util_format_get_blocksize(format);
+
+ return gdpy->native->buffer->import_buffer(gdpy->native, &nbuf);
}
#endif /* EGL_MESA_drm_image */
@@ -327,35 +323,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;
}
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_loader.h b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
index 78bfe2131ef..e9403fa293b 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
@@ -39,7 +39,6 @@ struct sw_winsys;
struct egl_g3d_loader {
uint profile_masks[ST_API_COUNT];
struct st_api *(*get_st_api)(enum st_api_type api);
- struct st_api *(*guess_gl_api)(enum st_profile_type profile);
struct pipe_screen *(*create_drm_screen)(const char *name, int fd);
struct pipe_screen *(*create_sw_screen)(struct sw_winsys *ws);
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
index 2b944b521a4..60c3e332ac9 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -292,6 +292,8 @@ egl_g3d_create_st_framebuffer(_EGLSurface *surf)
return NULL;
stfbi->visual = &gsurf->stvis;
+ p_atomic_set(&stfbi->stamp, 1);
+
if (gsurf->base.Type != EGL_PBUFFER_BIT) {
stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
stfbi->validate = egl_g3d_st_framebuffer_validate;
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 8646e52ed7c..fc50ee485fe 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -152,6 +152,11 @@ struct native_display {
*/
void *user_data;
+ /**
+ * Initialize and create the pipe screen.
+ */
+ boolean (*init_screen)(struct native_display *ndpy);
+
void (*destroy)(struct native_display *ndpy);
/**
@@ -170,16 +175,21 @@ struct native_display {
int *num_configs);
/**
- * Test if a pixmap is supported by the given config. Required unless no
- * config has pixmap_bit set.
- *
- * 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.
+ * Get the color format of the pixmap. Required unless no config has
+ * pixmap_bit set.
*/
- boolean (*is_pixmap_supported)(struct native_display *ndpy,
- EGLNativePixmapType pix,
- const struct native_config *nconf);
+ boolean (*get_pixmap_format)(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ enum pipe_format *format);
+ /**
+ * 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.
@@ -219,6 +229,9 @@ struct native_event_handler {
const char *name, int fd);
struct pipe_screen *(*new_sw_screen)(struct native_display *ndpy,
struct sw_winsys *ws);
+
+ struct pipe_resource *(*lookup_egl_image)(struct native_display *ndpy,
+ void *egl_image);
};
/**
@@ -256,26 +269,29 @@ ndpy_uninit(struct native_display *ndpy)
struct native_platform {
const char *name;
- void (*set_event_handler)(struct native_event_handler *handler);
- struct native_display *(*create_display)(void *dpy,
- boolean use_sw,
- void *user_data);
+ /**
+ * Create the native display and usually establish a connection to the
+ * display server.
+ *
+ * No event should be generated at this stage.
+ */
+ struct native_display *(*create_display)(void *dpy, boolean use_sw);
};
const struct native_platform *
-native_get_gdi_platform(void);
+native_get_gdi_platform(const struct native_event_handler *event_handler);
const struct native_platform *
-native_get_x11_platform(void);
+native_get_x11_platform(const struct native_event_handler *event_handler);
const struct native_platform *
-native_get_wayland_platform(void);
+native_get_wayland_platform(const struct native_event_handler *event_handler);
const struct native_platform *
-native_get_drm_platform(void);
+native_get_drm_platform(const struct native_event_handler *event_handler);
const struct native_platform *
-native_get_fbdev_platform(void);
+native_get_fbdev_platform(const struct native_event_handler *event_handler);
#ifdef __cplusplus
}
diff --git a/src/gallium/state_trackers/egl/common/native_buffer.h b/src/gallium/state_trackers/egl/common/native_buffer.h
index 5c29ab97411..b8a66d17e12 100644
--- a/src/gallium/state_trackers/egl/common/native_buffer.h
+++ b/src/gallium/state_trackers/egl/common/native_buffer.h
@@ -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_ */
diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c
index ee18cb2025b..cca1e1c6295 100644
--- a/src/gallium/state_trackers/egl/common/native_helper.c
+++ b/src/gallium/state_trackers/egl/common/native_helper.c
@@ -282,9 +282,9 @@ resource_surface_copy_swap(struct resource_surface *rsurf,
btex, 0, &src_box);
ret = TRUE;
- out_no_ftex:
- pipe_resource_reference(&btex, NULL);
out_no_btex:
+ pipe_resource_reference(&btex, NULL);
+ out_no_ftex:
pipe_resource_reference(&ftex, NULL);
return ret;
@@ -367,3 +367,116 @@ 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,
+ 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;
+}
diff --git a/src/gallium/state_trackers/egl/common/native_helper.h b/src/gallium/state_trackers/egl/common/native_helper.h
index 39564a04365..e8d91ccb02a 100644
--- a/src/gallium/state_trackers/egl/common/native_helper.h
+++ b/src/gallium/state_trackers/egl/common/native_helper.h
@@ -105,3 +105,17 @@ 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);
+
+boolean
+drm_display_export_native_buffer(struct native_display *ndpy,
+ struct pipe_resource *res,
+ struct native_buffer *nbuf);
diff --git a/src/gallium/state_trackers/egl/drm/modeset.c b/src/gallium/state_trackers/egl/drm/modeset.c
index 3fff9540905..73968d1343b 100644
--- a/src/gallium/state_trackers/egl/drm/modeset.c
+++ b/src/gallium/state_trackers/egl/drm/modeset.c
@@ -290,6 +290,42 @@ drm_display_create_surface(struct native_display *ndpy,
return drmsurf;
}
+struct native_surface *
+drm_display_create_surface_from_resource(struct native_display *ndpy,
+ struct pipe_resource *resource)
+{
+ struct drm_display *drmdpy = drm_display(ndpy);
+ struct drm_surface *drmsurf;
+ enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+
+ drmsurf = CALLOC_STRUCT(drm_surface);
+ if (!drmsurf)
+ return NULL;
+
+ drmsurf->drmdpy = drmdpy;
+ drmsurf->color_format = resource->format;
+ drmsurf->width = resource->width0;
+ drmsurf->height = resource->height0;
+ drmsurf->have_pageflip = FALSE;
+
+ drmsurf->rsurf = resource_surface_create(drmdpy->base.screen,
+ drmsurf->color_format,
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT);
+
+ resource_surface_import_resource(drmsurf->rsurf, natt, resource);
+
+ drmsurf->base.destroy = drm_surface_destroy;
+ drmsurf->base.present = drm_surface_present;
+ drmsurf->base.validate = drm_surface_validate;
+ drmsurf->base.wait = drm_surface_wait;
+
+ return &drmsurf->base;
+}
+
+
/**
* Choose a CRTC that supports all given connectors.
*/
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c
index 725fe28e4e2..47910de8d3c 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.c
+++ b/src/gallium/state_trackers/egl/drm/native_drm.c
@@ -33,6 +33,8 @@
#include "native_drm.h"
+#include "gbm_gallium_drmint.h"
+
#ifdef HAVE_LIBUDEV
#include <libudev.h>
#endif
@@ -125,6 +127,8 @@ drm_display_destroy(struct native_display *ndpy)
drm_display_fini_modeset(&drmdpy->base);
+ /* gbm owns screen */
+ ndpy->screen = NULL;
ndpy_uninit(ndpy);
if (drmdpy->device_name)
@@ -136,54 +140,10 @@ drm_display_destroy(struct native_display *ndpy)
FREE(drmdpy);
}
-/**
- * Initialize KMS and pipe screen.
- */
-static boolean
-drm_display_init_screen(struct native_display *ndpy)
-{
- struct drm_display *drmdpy = drm_display(ndpy);
- drmVersionPtr version;
-
- version = drmGetVersion(drmdpy->fd);
- if (!version) {
- _eglLog(_EGL_WARNING, "invalid fd %d", drmdpy->fd);
- return FALSE;
- }
-
- drmdpy->base.screen =
- drmdpy->event_handler->new_drm_screen(&drmdpy->base, NULL, drmdpy->fd);
- drmFreeVersion(version);
-
- if (!drmdpy->base.screen) {
- _eglLog(_EGL_DEBUG, "failed to create DRM screen");
- return FALSE;
- }
-
- return TRUE;
-}
-
-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
@@ -281,9 +241,25 @@ static struct native_display_wayland_bufmgr drm_display_wayland_bufmgr = {
#endif /* HAVE_WAYLAND_BACKEND */
+static struct native_surface *
+drm_create_pixmap_surface(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct gbm_gallium_drm_bo *bo = (void *) pix;
+
+ return drm_display_create_surface_from_resource(ndpy, bo->resource);
+}
+
+static boolean
+drm_display_init_screen(struct native_display *ndpy)
+{
+ return TRUE;
+}
+
static struct native_display *
-drm_create_display(int fd, struct native_event_handler *event_handler,
- void *user_data)
+drm_create_display(struct gbm_gallium_drm_device *gbmdrm,
+ const struct native_event_handler *event_handler)
{
struct drm_display *drmdpy;
@@ -291,20 +267,24 @@ drm_create_display(int fd, struct native_event_handler *event_handler,
if (!drmdpy)
return NULL;
- drmdpy->fd = fd;
- drmdpy->device_name = drm_get_device_name(fd);
+ drmdpy->fd = gbmdrm->base.base.fd;
+ drmdpy->device_name = drm_get_device_name(drmdpy->fd);
+
+ gbmdrm->lookup_egl_image = (struct pipe_resource *(*)(void *, void *))
+ event_handler->lookup_egl_image;
+ gbmdrm->lookup_egl_image_data = &drmdpy->base;
+
drmdpy->event_handler = event_handler;
- drmdpy->base.user_data = user_data;
- if (!drm_display_init_screen(&drmdpy->base)) {
- drm_display_destroy(&drmdpy->base);
- return NULL;
- }
+ drmdpy->base.screen = gbmdrm->screen;
+ drmdpy->base.init_screen = drm_display_init_screen;
drmdpy->base.destroy = drm_display_destroy;
drmdpy->base.get_param = drm_display_get_param;
drmdpy->base.get_configs = drm_display_get_configs;
+ drmdpy->base.create_pixmap_surface = drm_create_pixmap_surface;
+
drmdpy->base.buffer = &drm_display_buffer;
#ifdef HAVE_WAYLAND_BACKEND
if (drmdpy->device_name)
@@ -315,39 +295,39 @@ drm_create_display(int fd, struct native_event_handler *event_handler,
return &drmdpy->base;
}
-static struct native_event_handler *drm_event_handler;
-
-static void
-native_set_event_handler(struct native_event_handler *event_handler)
-{
- drm_event_handler = event_handler;
-}
+static const struct native_event_handler *drm_event_handler;
static struct native_display *
-native_create_display(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw)
{
+ struct gbm_gallium_drm_device *gbm;
int fd;
- if (dpy) {
- fd = dup((int) pointer_to_intptr(dpy));
- }
- else {
+ gbm = dpy;
+
+ if (gbm == NULL) {
fd = open("/dev/dri/card0", O_RDWR);
+ gbm = gbm_gallium_drm_device(gbm_create_device(fd));
}
- if (fd < 0)
+
+ if (gbm == NULL)
+ return NULL;
+
+ if (strcmp(gbm_device_get_backend_name(&gbm->base.base), "drm") != 0 ||
+ gbm->base.type != GBM_DRM_DRIVER_TYPE_GALLIUM)
return NULL;
- return drm_create_display(fd, drm_event_handler, user_data);
+ return drm_create_display(gbm, drm_event_handler);
}
static const struct native_platform drm_platform = {
"DRM", /* name */
- native_set_event_handler,
native_create_display
};
const struct native_platform *
-native_get_drm_platform(void)
+native_get_drm_platform(const struct native_event_handler *event_handler)
{
+ drm_event_handler = event_handler;
return &drm_platform;
}
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.h b/src/gallium/state_trackers/egl/drm/native_drm.h
index 41cdc4f9d04..675a58a1922 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.h
+++ b/src/gallium/state_trackers/egl/drm/native_drm.h
@@ -50,7 +50,7 @@ struct drm_surface;
struct drm_display {
struct native_display base;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
int fd;
char *device_name;
@@ -154,4 +154,8 @@ drm_display_init_modeset(struct native_display *ndpy);
void
drm_display_fini_modeset(struct native_display *ndpy);
+struct native_surface *
+drm_display_create_surface_from_resource(struct native_display *ndpy,
+ struct pipe_resource *resource);
+
#endif /* _NATIVE_DRM_H_ */
diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
index e2fde00e975..6772d379f73 100644
--- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
+++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
@@ -26,6 +26,21 @@
* Chia-I Wu <[email protected]>
*/
+/**
+ * Considering fbdev as an in-kernel window system,
+ *
+ * - opening a device opens a connection
+ * - there is only one window: the framebuffer
+ * - fb_var_screeninfo decides window position, size, and even color format
+ * - there is no pixmap
+ *
+ * Now EGL is built on top of this window system. So we should have
+ *
+ * - the fd as the handle of the native display
+ * - reject all but one native window: NULL
+ * - no pixmap support
+ */
+
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -45,16 +60,13 @@ struct fbdev_display {
struct native_display base;
int fd;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct fb_fix_screeninfo finfo;
- struct fb_var_screeninfo vinfo;
-
+ struct fb_var_screeninfo config_vinfo;
struct native_config config;
- struct native_connector connector;
- struct native_mode mode;
- struct fbdev_surface *current_surface;
+ boolean assume_fixed_vinfo;
};
struct fbdev_surface {
@@ -66,7 +78,7 @@ struct fbdev_surface {
unsigned int sequence_number;
- boolean is_current;
+ struct fbdev_sw_drawable drawable;
};
static INLINE struct fbdev_display *
@@ -103,38 +115,70 @@ fbdev_surface_validate(struct native_surface *nsurf, uint attachment_mask,
return TRUE;
}
-static boolean
-fbdev_surface_flush_frontbuffer(struct native_surface *nsurf)
+static enum pipe_format
+vinfo_to_format(const struct fb_var_screeninfo *vinfo)
{
- struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
+ enum pipe_format format = PIPE_FORMAT_NONE;
- if (!fbsurf->is_current)
- return TRUE;
+ /* should also check channel offsets... */
+ switch (vinfo->bits_per_pixel) {
+ case 32:
+ if (vinfo->red.length == 8 &&
+ vinfo->green.length == 8 &&
+ vinfo->blue.length == 8) {
+ format = (vinfo->transp.length == 8) ?
+ PIPE_FORMAT_B8G8R8A8_UNORM : PIPE_FORMAT_B8G8R8X8_UNORM;
+ }
+ break;
+ case 16:
+ if (vinfo->red.length == 5 &&
+ vinfo->green.length == 6 &&
+ vinfo->blue.length == 5 &&
+ vinfo->transp.length == 0)
+ format = PIPE_FORMAT_B5G6R5_UNORM;
+ break;
+ default:
+ break;
+ }
- return resource_surface_present(fbsurf->rsurf,
- NATIVE_ATTACHMENT_FRONT_LEFT, NULL);
+ return format;
}
static boolean
-fbdev_surface_swap_buffers(struct native_surface *nsurf)
+fbdev_surface_update_drawable(struct native_surface *nsurf,
+ const struct fb_var_screeninfo *vinfo)
{
struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
- struct fbdev_display *fbdpy = fbsurf->fbdpy;
- boolean ret = TRUE;
-
- if (fbsurf->is_current) {
- ret = resource_surface_present(fbsurf->rsurf,
- NATIVE_ATTACHMENT_BACK_LEFT, NULL);
+ unsigned x, y, width, height;
+
+ x = vinfo->xoffset;
+ y = vinfo->yoffset;
+ width = MIN2(vinfo->xres, fbsurf->width);
+ height = MIN2(vinfo->yres, fbsurf->height);
+
+ /* sanitize the values */
+ if (x + width > vinfo->xres_virtual) {
+ if (x > vinfo->xres_virtual)
+ width = 0;
+ else
+ width = vinfo->xres_virtual - x;
+ }
+ if (y + height > vinfo->yres_virtual) {
+ if (y > vinfo->yres_virtual)
+ height = 0;
+ else
+ height = vinfo->yres_virtual - y;
}
- resource_surface_swap_buffers(fbsurf->rsurf,
- NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
- /* the front/back textures are swapped */
- fbsurf->sequence_number++;
- fbdpy->event_handler->invalid_surface(&fbdpy->base,
- &fbsurf->base, fbsurf->sequence_number);
+ fbsurf->drawable.format = vinfo_to_format(vinfo);
+ fbsurf->drawable.x = vinfo->xoffset;
+ fbsurf->drawable.y = vinfo->yoffset;
+ fbsurf->drawable.width = vinfo->xres;
+ fbsurf->drawable.height = vinfo->yres;
- return ret;
+ return (fbsurf->drawable.format != PIPE_FORMAT_NONE &&
+ fbsurf->drawable.width &&
+ fbsurf->drawable.height);
}
static boolean
@@ -143,21 +187,43 @@ fbdev_surface_present(struct native_surface *nsurf,
boolean preserve,
uint swap_interval)
{
- boolean ret;
+ struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
+ struct fbdev_display *fbdpy = fbsurf->fbdpy;
+ boolean ret = FALSE;
- if (preserve || swap_interval)
+ if (swap_interval)
+ return FALSE;
+ if (natt != NATIVE_ATTACHMENT_BACK_LEFT)
return FALSE;
- switch (natt) {
- case NATIVE_ATTACHMENT_FRONT_LEFT:
- ret = fbdev_surface_flush_frontbuffer(nsurf);
- break;
- case NATIVE_ATTACHMENT_BACK_LEFT:
- ret = fbdev_surface_swap_buffers(nsurf);
- break;
- default:
- ret = FALSE;
- break;
+ if (!fbdpy->assume_fixed_vinfo) {
+ struct fb_var_screeninfo vinfo;
+
+ memset(&vinfo, 0, sizeof(vinfo));
+ if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &vinfo))
+ return FALSE;
+
+ /* present the surface */
+ if (fbdev_surface_update_drawable(&fbsurf->base, &vinfo)) {
+ ret = resource_surface_present(fbsurf->rsurf,
+ natt, (void *) &fbsurf->drawable);
+ }
+
+ fbsurf->width = vinfo.xres;
+ fbsurf->height = vinfo.yres;
+
+ if (resource_surface_set_size(fbsurf->rsurf,
+ fbsurf->width, fbsurf->height)) {
+ /* surface resized */
+ fbsurf->sequence_number++;
+ fbdpy->event_handler->invalid_surface(&fbdpy->base,
+ &fbsurf->base, fbsurf->sequence_number);
+ }
+ }
+ else {
+ /* the drawable never changes */
+ ret = resource_surface_present(fbsurf->rsurf,
+ natt, (void *) &fbsurf->drawable);
}
return ret;
@@ -179,26 +245,48 @@ fbdev_surface_destroy(struct native_surface *nsurf)
}
static struct native_surface *
-fbdev_display_create_scanout_surface(struct native_display *ndpy,
- const struct native_config *nconf,
- uint width, uint height)
+fbdev_display_create_window_surface(struct native_display *ndpy,
+ EGLNativeWindowType win,
+ const struct native_config *nconf)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
struct fbdev_surface *fbsurf;
+ struct fb_var_screeninfo vinfo;
+
+ /* there is only one native window: NULL */
+ if (win)
+ return NULL;
fbsurf = CALLOC_STRUCT(fbdev_surface);
if (!fbsurf)
return NULL;
fbsurf->fbdpy = fbdpy;
- fbsurf->width = width;
- fbsurf->height = height;
+
+ /* get current vinfo */
+ if (fbdpy->assume_fixed_vinfo) {
+ vinfo = fbdpy->config_vinfo;
+ }
+ else {
+ memset(&vinfo, 0, sizeof(vinfo));
+ if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &vinfo)) {
+ FREE(fbsurf);
+ return NULL;
+ }
+ }
+
+ fbsurf->width = vinfo.xres;
+ fbsurf->height = vinfo.yres;
+
+ if (!fbdev_surface_update_drawable(&fbsurf->base, &vinfo)) {
+ FREE(fbsurf);
+ return NULL;
+ }
fbsurf->rsurf = resource_surface_create(fbdpy->base.screen,
nconf->color_format,
PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SCANOUT);
+ PIPE_BIND_DISPLAY_TARGET);
if (!fbsurf->rsurf) {
FREE(fbsurf);
return NULL;
@@ -214,42 +302,43 @@ fbdev_display_create_scanout_surface(struct native_display *ndpy,
return &fbsurf->base;
}
+static struct native_surface *
+fbdev_display_create_scanout_surface(struct native_display *ndpy,
+ const struct native_config *nconf,
+ uint width, uint height)
+{
+ return fbdev_display_create_window_surface(ndpy,
+ (EGLNativeWindowType) NULL, nconf);
+}
+
static boolean
fbdev_display_program(struct native_display *ndpy, int crtc_idx,
struct native_surface *nsurf, uint x, uint y,
const struct native_connector **nconns, int num_nconns,
const struct native_mode *nmode)
{
- struct fbdev_display *fbdpy = fbdev_display(ndpy);
- struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
-
- if (x || y)
- return FALSE;
-
- if (fbdpy->current_surface) {
- if (fbdpy->current_surface == fbsurf)
- return TRUE;
- fbdpy->current_surface->is_current = FALSE;
- }
-
- if (fbsurf)
- fbsurf->is_current = TRUE;
- fbdpy->current_surface = fbsurf;
-
return TRUE;
}
static const struct native_mode **
fbdev_display_get_modes(struct native_display *ndpy,
- const struct native_connector *nconn,
- int *num_modes)
+ const struct native_connector *nconn,
+ int *num_modes)
{
- struct fbdev_display *fbdpy = fbdev_display(ndpy);
+ static struct native_mode mode;
const struct native_mode **modes;
+ if (!mode.desc) {
+ struct fbdev_display *fbdpy = fbdev_display(ndpy);
+ mode.desc = "Current Mode";
+ mode.width = fbdpy->config_vinfo.xres;
+ mode.height = fbdpy->config_vinfo.yres;
+ mode.refresh_rate = 60 * 1000; /* dummy */
+ }
+
modes = MALLOC(sizeof(*modes));
if (modes) {
- modes[0] = &fbdpy->mode;
+ modes[0] = &mode;
if (num_modes)
*num_modes = 1;
}
@@ -261,12 +350,12 @@ static const struct native_connector **
fbdev_display_get_connectors(struct native_display *ndpy, int *num_connectors,
int *num_crtc)
{
- struct fbdev_display *fbdpy = fbdev_display(ndpy);
+ static struct native_connector connector;
const struct native_connector **connectors;
connectors = MALLOC(sizeof(*connectors));
if (connectors) {
- connectors[0] = &fbdpy->connector;
+ connectors[0] = &connector;
if (num_connectors)
*num_connectors = 1;
}
@@ -274,7 +363,8 @@ fbdev_display_get_connectors(struct native_display *ndpy, int *num_connectors,
return connectors;
}
-static struct native_display_modeset fbdev_display_modeset = {
+/* remove modeset support one day! */
+static const struct native_display_modeset fbdev_display_modeset = {
.get_connectors = fbdev_display_get_connectors,
.get_modes = fbdev_display_get_modes,
.create_scanout_surface = fbdev_display_create_scanout_surface,
@@ -304,8 +394,10 @@ fbdev_display_get_param(struct native_display *ndpy,
int val;
switch (param) {
- case NATIVE_PARAM_USE_NATIVE_BUFFER:
case NATIVE_PARAM_PRESERVE_BUFFER:
+ val = 1;
+ break;
+ case NATIVE_PARAM_USE_NATIVE_BUFFER:
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
@@ -326,114 +418,55 @@ fbdev_display_destroy(struct native_display *ndpy)
}
static boolean
-fbdev_display_init_modes(struct native_display *ndpy)
+fbdev_display_init_screen(struct native_display *ndpy)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
- struct native_mode *nmode = &fbdpy->mode;
-
- nmode->desc = "Current Mode";
- nmode->width = fbdpy->vinfo.xres;
- nmode->height = fbdpy->vinfo.yres;
- nmode->refresh_rate = 60 * 1000; /* dummy */
-
- return TRUE;
-}
-
-static boolean
-fbdev_display_init_connectors(struct native_display *ndpy)
-{
- return TRUE;
-}
+ struct sw_winsys *ws;
-static enum pipe_format
-vinfo_to_format(const struct fb_var_screeninfo *vinfo)
-{
- enum pipe_format format = PIPE_FORMAT_NONE;
+ ws = fbdev_create_sw_winsys(fbdpy->fd);
+ if (!ws)
+ return FALSE;
- switch (vinfo->bits_per_pixel) {
- case 32:
- if (vinfo->red.length == 8 &&
- vinfo->green.length == 8 &&
- vinfo->blue.length == 8) {
- format = (vinfo->transp.length == 8) ?
- PIPE_FORMAT_B8G8R8A8_UNORM : PIPE_FORMAT_B8G8R8X8_UNORM;
- }
- break;
- case 16:
- if (vinfo->red.length == 5 &&
- vinfo->green.length == 6 &&
- vinfo->blue.length == 5 &&
- vinfo->transp.length == 0)
- format = PIPE_FORMAT_B5G6R5_UNORM;
- break;
- default:
- break;
+ fbdpy->base.screen = fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws);
+ if (!fbdpy->base.screen) {
+ if (ws->destroy)
+ ws->destroy(ws);
+ return FALSE;
}
- return format;
-}
-
-static boolean
-fbdev_display_init_configs(struct native_display *ndpy)
-{
- struct fbdev_display *fbdpy = fbdev_display(ndpy);
- struct native_config *nconf = &fbdpy->config;
-
- nconf->color_format = vinfo_to_format(&fbdpy->vinfo);
- if (nconf->color_format == PIPE_FORMAT_NONE)
+ if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen,
+ fbdpy->config.color_format, PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET)) {
+ fbdpy->base.screen->destroy(fbdpy->base.screen);
+ fbdpy->base.screen = NULL;
return FALSE;
-
- nconf->buffer_mask =
- (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
- (1 << NATIVE_ATTACHMENT_BACK_LEFT);
-
- nconf->scanout_bit = TRUE;
+ }
return TRUE;
}
static boolean
-fbdev_display_init(struct native_display *ndpy)
+fbdev_display_init_config(struct native_display *ndpy)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
- struct sw_winsys *ws;
-
- if (ioctl(fbdpy->fd, FBIOGET_FSCREENINFO, &fbdpy->finfo))
- return FALSE;
+ struct native_config *nconf = &fbdpy->config;
- if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &fbdpy->vinfo))
+ if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &fbdpy->config_vinfo))
return FALSE;
- if (fbdpy->finfo.visual != FB_VISUAL_TRUECOLOR ||
- fbdpy->finfo.type != FB_TYPE_PACKED_PIXELS)
+ nconf->color_format = vinfo_to_format(&fbdpy->config_vinfo);
+ if (nconf->color_format == PIPE_FORMAT_NONE)
return FALSE;
- if (!fbdev_display_init_configs(&fbdpy->base) ||
- !fbdev_display_init_connectors(&fbdpy->base) ||
- !fbdev_display_init_modes(&fbdpy->base))
- return FALSE;
+ nconf->buffer_mask = (1 << NATIVE_ATTACHMENT_BACK_LEFT);
- ws = fbdev_create_sw_winsys(fbdpy->fd, fbdpy->config.color_format);
- if (ws) {
- fbdpy->base.screen =
- fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws);
- }
+ nconf->window_bit = TRUE;
- if (fbdpy->base.screen) {
- if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen,
- fbdpy->config.color_format, PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET)) {
- fbdpy->base.screen->destroy(fbdpy->base.screen);
- fbdpy->base.screen = NULL;
- }
- }
-
- return (fbdpy->base.screen != NULL);
+ return TRUE;
}
static struct native_display *
-fbdev_display_create(int fd, struct native_event_handler *event_handler,
- void *user_data)
+fbdev_display_create(int fd, const struct native_event_handler *event_handler)
{
struct fbdev_display *fbdpy;
@@ -443,32 +476,41 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler,
fbdpy->fd = fd;
fbdpy->event_handler = event_handler;
- fbdpy->base.user_data = user_data;
- if (!fbdev_display_init(&fbdpy->base)) {
- FREE(fbdpy);
- return NULL;
- }
+ if (ioctl(fbdpy->fd, FBIOGET_FSCREENINFO, &fbdpy->finfo))
+ goto fail;
+
+ if (fbdpy->finfo.visual != FB_VISUAL_TRUECOLOR ||
+ fbdpy->finfo.type != FB_TYPE_PACKED_PIXELS)
+ goto fail;
+
+ if (!fbdev_display_init_config(&fbdpy->base))
+ goto fail;
+ fbdpy->assume_fixed_vinfo = TRUE;
+
+ fbdpy->base.init_screen = fbdev_display_init_screen;
fbdpy->base.destroy = fbdev_display_destroy;
fbdpy->base.get_param = fbdev_display_get_param;
fbdpy->base.get_configs = fbdev_display_get_configs;
+ fbdpy->base.create_window_surface = fbdev_display_create_window_surface;
+
+ /* we'd like to remove modeset support one day */
+ fbdpy->config.scanout_bit = TRUE;
fbdpy->base.modeset = &fbdev_display_modeset;
return &fbdpy->base;
-}
-static struct native_event_handler *fbdev_event_handler;
-
-static void
-native_set_event_handler(struct native_event_handler *event_handler)
-{
- fbdev_event_handler = event_handler;
+fail:
+ FREE(fbdpy);
+ return NULL;
}
+static const struct native_event_handler *fbdev_event_handler;
+
static struct native_display *
-native_create_display(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw)
{
struct native_display *ndpy;
int fd;
@@ -483,7 +525,7 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
if (fd < 0)
return NULL;
- ndpy = fbdev_display_create(fd, fbdev_event_handler, user_data);
+ ndpy = fbdev_display_create(fd, fbdev_event_handler);
if (!ndpy)
close(fd);
@@ -492,12 +534,12 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
static const struct native_platform fbdev_platform = {
"FBDEV", /* name */
- native_set_event_handler,
native_create_display
};
const struct native_platform *
-native_get_fbdev_platform(void)
+native_get_fbdev_platform(const struct native_event_handler *event_handler)
{
+ fbdev_event_handler = event_handler;
return &fbdev_platform;
}
diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c
index 5d0045f92ee..6bf0d4e4668 100644
--- a/src/gallium/state_trackers/egl/gdi/native_gdi.c
+++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c
@@ -41,7 +41,7 @@ struct gdi_display {
struct native_display base;
HDC hDC;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct native_config *configs;
int num_configs;
@@ -368,35 +368,39 @@ gdi_display_destroy(struct native_display *ndpy)
FREE(gdpy);
}
-static struct native_display *
-gdi_create_display(HDC hDC, struct native_event_handler *event_handler,
- void *user_data)
+static boolean
+gdi_display_init_screen(struct native_display *ndpy)
{
- struct gdi_display *gdpy;
+ struct gdi_display *gdpy = gdi_display(ndpy);
struct sw_winsys *winsys;
- gdpy = CALLOC_STRUCT(gdi_display);
- if (!gdpy)
- return NULL;
-
- gdpy->hDC = hDC;
- gdpy->event_handler = event_handler;
- gdpy->base.user_data = user_data;
-
winsys = gdi_create_sw_winsys();
- if (!winsys) {
- FREE(gdpy);
- return NULL;
- }
+ if (!winsys)
+ return FALSE;
gdpy->base.screen = gdpy->event_handler->new_sw_screen(&gdpy->base, winsys);
if (!gdpy->base.screen) {
if (winsys->destroy)
winsys->destroy(winsys);
- FREE(gdpy);
- return NULL;
+ return FALSE;
}
+ return TRUE;
+}
+
+static struct native_display *
+gdi_create_display(HDC hDC, const struct native_event_handler *event_handler)
+{
+ struct gdi_display *gdpy;
+
+ gdpy = CALLOC_STRUCT(gdi_display);
+ if (!gdpy)
+ return NULL;
+
+ gdpy->hDC = hDC;
+ gdpy->event_handler = event_handler;
+
+ gdpy->base.init_screen = gdi_display_init_screen;
gdpy->base.destroy = gdi_display_destroy;
gdpy->base.get_param = gdi_display_get_param;
@@ -406,28 +410,22 @@ gdi_create_display(HDC hDC, struct native_event_handler *event_handler,
return &gdpy->base;
}
-static struct native_event_handler *gdi_event_handler;
-
-static void
-native_set_event_handler(struct native_event_handler *event_handler)
-{
- gdi_event_handler = event_handler;
-}
+static const struct native_event_handler *gdi_event_handler;
static struct native_display *
-native_create_display(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw)
{
- return gdi_create_display((HDC) dpy, gdi_event_handler, user_data);
+ return gdi_create_display((HDC) dpy, gdi_event_handler);
}
static const struct native_platform gdi_platform = {
"GDI", /* name */
- native_set_event_handler,
native_create_display
};
const struct native_platform *
-native_get_gdi_platform(void)
+native_get_gdi_platform(const struct native_event_handler *event_handler)
{
+ gdi_event_handler = event_handler;
return &gdi_platform;
}
diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c
index 15383e89301..e34b24b58b1 100644
--- a/src/gallium/state_trackers/egl/wayland/native_drm.c
+++ b/src/gallium/state_trackers/egl/wayland/native_drm.c
@@ -51,7 +51,7 @@
struct wayland_drm_display {
struct wayland_display base;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct wl_drm *wl_drm;
struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */
@@ -98,6 +98,8 @@ wayland_drm_display_destroy(struct native_display *ndpy)
FREE(drmdpy->device_name);
if (drmdpy->base.config)
FREE(drmdpy->base.config);
+ if (drmdpy->base.own_dpy)
+ wl_display_destroy(drmdpy->base.dpy);
ndpy_uninit(ndpy);
@@ -210,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
@@ -300,8 +285,7 @@ static struct native_display_wayland_bufmgr wayland_drm_display_wayland_bufmgr =
struct wayland_display *
wayland_create_drm_display(struct wl_display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
struct wayland_drm_display *drmdpy;
@@ -310,7 +294,6 @@ wayland_create_drm_display(struct wl_display *dpy,
return NULL;
drmdpy->event_handler = event_handler;
- drmdpy->base.base.user_data = user_data;
drmdpy->base.dpy = dpy;
if (!drmdpy->base.dpy) {
@@ -318,10 +301,7 @@ wayland_create_drm_display(struct wl_display *dpy,
return NULL;
}
- if (!wayland_drm_display_init_screen(&drmdpy->base.base)) {
- wayland_drm_display_destroy(&drmdpy->base.base);
- return NULL;
- }
+ drmdpy->base.base.init_screen = wayland_drm_display_init_screen;
drmdpy->base.base.destroy = wayland_drm_display_destroy;
drmdpy->base.base.buffer = &wayland_drm_display_buffer;
drmdpy->base.base.wayland_bufmgr = &wayland_drm_display_wayland_bufmgr;
diff --git a/src/gallium/state_trackers/egl/wayland/native_shm.c b/src/gallium/state_trackers/egl/wayland/native_shm.c
index 609fc0cd04a..1c0799528fe 100644
--- a/src/gallium/state_trackers/egl/wayland/native_shm.c
+++ b/src/gallium/state_trackers/egl/wayland/native_shm.c
@@ -47,7 +47,7 @@
struct wayland_shm_display {
struct wayland_display base;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct wl_shm *wl_shm;
};
@@ -65,6 +65,8 @@ wayland_shm_display_destroy(struct native_display *ndpy)
if (shmdpy->base.config)
FREE(shmdpy->base.config);
+ if (shmdpy->base.own_dpy)
+ wl_display_destroy(shmdpy->base.dpy);
ndpy_uninit(ndpy);
@@ -142,8 +144,7 @@ wayland_shm_display_init_screen(struct native_display *ndpy)
struct wayland_display *
wayland_create_shm_display(struct wl_display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
struct wayland_shm_display *shmdpy;
@@ -152,7 +153,6 @@ wayland_create_shm_display(struct wl_display *dpy,
return NULL;
shmdpy->event_handler = event_handler;
- shmdpy->base.base.user_data = user_data;
shmdpy->base.dpy = dpy;
if (!shmdpy->base.dpy) {
@@ -160,11 +160,7 @@ wayland_create_shm_display(struct wl_display *dpy,
return NULL;
}
- if (!wayland_shm_display_init_screen(&shmdpy->base.base)) {
- wayland_shm_display_destroy(&shmdpy->base.base);
- return NULL;
- }
-
+ shmdpy->base.base.init_screen = wayland_shm_display_init_screen;
shmdpy->base.base.destroy = wayland_shm_display_destroy;
shmdpy->base.create_buffer = wayland_create_shm_buffer;
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c
index 0292d5631d6..544d4be215a 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.c
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c
@@ -35,7 +35,7 @@
#include "native_wayland.h"
-static struct native_event_handler *wayland_event_handler;
+static const struct native_event_handler *wayland_event_handler;
static void
sync_callback(void *data)
@@ -114,11 +114,12 @@ wayland_display_get_param(struct native_display *ndpy,
}
static boolean
-wayland_display_is_pixmap_supported(struct native_display *ndpy,
- EGLNativePixmapType pix,
- const struct native_config *nconf)
+wayland_display_get_pixmap_format(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ enum pipe_format *format)
{
/* all wl_egl_pixmaps are supported */
+ *format = PIPE_FORMAT_NONE;
return TRUE;
}
@@ -195,13 +196,11 @@ wayland_window_surface_handle_resize(struct wayland_surface *surface)
wl_buffer_destroy(surface->buffer[i]);
surface->buffer[i] = NULL;
}
+
+ surface->dx = surface->win->dx;
+ surface->dy = surface->win->dy;
}
pipe_resource_reference(&front_resource, NULL);
-
- surface->dx = surface->win->dx;
- surface->dy = surface->win->dy;
- surface->win->dx = 0;
- surface->win->dy = 0;
}
static boolean
@@ -449,28 +448,28 @@ wayland_create_window_surface(struct native_display *ndpy,
return &surface->base;
}
-static void
-native_set_event_handler(struct native_event_handler *event_handler)
-{
- wayland_event_handler = event_handler;
-}
-
static struct native_display *
-native_create_display(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw)
{
struct wayland_display *display = NULL;
+ boolean own_dpy = FALSE;
use_sw = use_sw || debug_get_bool_option("EGL_SOFTWARE", FALSE);
+ if (dpy == NULL) {
+ dpy = wl_display_connect(NULL);
+ if (dpy == NULL)
+ return NULL;
+ own_dpy = TRUE;
+ }
+
if (use_sw) {
_eglLog(_EGL_INFO, "use software fallback");
display = wayland_create_shm_display((struct wl_display *) dpy,
- wayland_event_handler,
- user_data);
+ wayland_event_handler);
} else {
display = wayland_create_drm_display((struct wl_display *) dpy,
- wayland_event_handler,
- user_data);
+ wayland_event_handler);
}
if (!display)
@@ -478,22 +477,25 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
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.get_pixmap_format = wayland_display_get_pixmap_format;
+ 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;
+ display->own_dpy = own_dpy;
+
return &display->base;
}
static const struct native_platform wayland_platform = {
"wayland", /* name */
- native_set_event_handler,
native_create_display
};
const struct native_platform *
-native_get_wayland_platform(void)
+native_get_wayland_platform(const struct native_event_handler *event_handler)
{
+ wayland_event_handler = event_handler;
return &wayland_platform;
}
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h b/src/gallium/state_trackers/egl/wayland/native_wayland.h
index e69a8f00f82..5390f2f08c9 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.h
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h
@@ -41,6 +41,7 @@ struct wayland_display {
struct wayland_config *config;
struct wl_display *dpy;
+ boolean own_dpy;
struct wl_buffer *(*create_buffer)(struct wayland_display *display,
struct wayland_surface *surface,
@@ -102,11 +103,10 @@ wayland_config(const struct native_config *nconf)
struct wayland_display *
wayland_create_shm_display(struct wl_display *display,
- struct native_event_handler *event_handler,
- void *user_data);
+ const struct native_event_handler *event_handler);
+
struct wayland_display *
wayland_create_drm_display(struct wl_display *display,
- struct native_event_handler *event_handler,
- void *user_data);
+ const struct native_event_handler *event_handler);
#endif /* _NATIVE_WAYLAND_H_ */
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index a56d43428fc..4b8be7bc759 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -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
@@ -49,7 +50,7 @@ struct dri2_display {
Display *dpy;
boolean own_dpy;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct x11_screen *xscr;
int xscr_number;
@@ -682,18 +683,30 @@ dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
}
static boolean
-dri2_display_is_pixmap_supported(struct native_display *ndpy,
- EGLNativePixmapType pix,
- const struct native_config *nconf)
+dri2_display_get_pixmap_format(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ enum pipe_format *format)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
- uint depth, nconf_depth;
+ boolean ret = EGL_TRUE;
+ uint depth;
depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
- nconf_depth = util_format_get_blocksizebits(nconf->color_format);
+ switch (depth) {
+ case 32:
+ case 24:
+ *format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ case 16:
+ *format = PIPE_FORMAT_B5G6R5_UNORM;
+ break;
+ default:
+ *format = PIPE_FORMAT_NONE;
+ ret = EGL_FALSE;
+ break;
+ }
- /* simple depth match for now */
- return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth));
+ return ret;
}
static int
@@ -870,8 +883,7 @@ static struct native_display_wayland_bufmgr dri2_display_wayland_bufmgr = {
struct native_display *
x11_create_dri2_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
struct dri2_display *dri2dpy;
@@ -880,7 +892,6 @@ x11_create_dri2_display(Display *dpy,
return NULL;
dri2dpy->event_handler = event_handler;
- dri2dpy->base.user_data = user_data;
dri2dpy->dpy = dpy;
if (!dri2dpy->dpy) {
@@ -899,11 +910,6 @@ x11_create_dri2_display(Display *dpy,
return NULL;
}
- if (!dri2_display_init_screen(&dri2dpy->base)) {
- dri2_display_destroy(&dri2dpy->base);
- return NULL;
- }
-
dri2dpy->surfaces = util_hash_table_create(dri2_display_hash_table_hash,
dri2_display_hash_table_compare);
if (!dri2dpy->surfaces) {
@@ -911,10 +917,12 @@ x11_create_dri2_display(Display *dpy,
return NULL;
}
+ dri2dpy->base.init_screen = dri2_display_init_screen;
dri2dpy->base.destroy = dri2_display_destroy;
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.get_pixmap_format = dri2_display_get_pixmap_format;
+ 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
@@ -928,8 +936,7 @@ x11_create_dri2_display(Display *dpy,
struct native_display *
x11_create_dri2_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
return NULL;
}
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index a0bcad4c734..ef038b52152 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -30,16 +30,10 @@
#include "native_x11.h"
-static struct native_event_handler *x11_event_handler;
-
-static void
-native_set_event_handler(struct native_event_handler *event_handler)
-{
- x11_event_handler = event_handler;
-}
+static const struct native_event_handler *x11_event_handler;
static struct native_display *
-native_create_display(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw)
{
struct native_display *ndpy = NULL;
boolean force_sw;
@@ -48,12 +42,10 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
if (force_sw || use_sw) {
_eglLog(_EGL_INFO, "use software fallback");
- ndpy = x11_create_ximage_display((Display *) dpy,
- x11_event_handler, user_data);
+ ndpy = x11_create_ximage_display((Display *) dpy, x11_event_handler);
}
else {
- ndpy = x11_create_dri2_display((Display *) dpy,
- x11_event_handler, user_data);
+ ndpy = x11_create_dri2_display((Display *) dpy, x11_event_handler);
}
return ndpy;
@@ -61,12 +53,12 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
static const struct native_platform x11_platform = {
"X11", /* name */
- native_set_event_handler,
native_create_display
};
const struct native_platform *
-native_get_x11_platform(void)
+native_get_x11_platform(const struct native_event_handler *event_handler)
{
+ x11_event_handler = event_handler;
return &x11_platform;
}
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
index 8945117276e..d3c9270a667 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -31,12 +31,10 @@
struct native_display *
x11_create_ximage_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data);
+ const struct native_event_handler *event_handler);
struct native_display *
x11_create_dri2_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data);
+ const struct native_event_handler *event_handler);
#endif /* _NATIVE_X11_H_ */
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 8e32c6ff0c4..e7794f0d3d7 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -43,7 +43,7 @@ struct ximage_display {
Display *dpy;
boolean own_dpy;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct x11_screen *xscr;
int xscr_number;
@@ -437,14 +437,54 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
}
static boolean
-ximage_display_is_pixmap_supported(struct native_display *ndpy,
- EGLNativePixmapType pix,
- const struct native_config *nconf)
+ximage_display_get_pixmap_format(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ enum pipe_format *format)
{
struct ximage_display *xdpy = ximage_display(ndpy);
- enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
- return (fmt == nconf->color_format);
+ *format = get_pixmap_format(&xdpy->base, pix);
+
+ return (*format != PIPE_FORMAT_NONE);
+}
+
+static boolean
+ximage_display_copy_to_pixmap(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ struct pipe_resource *src)
+{
+ /* fast path to avoid unnecessary allocation and resource_copy_region */
+ if (src->bind & PIPE_BIND_DISPLAY_TARGET) {
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
+ const struct ximage_config *xconf;
+ struct xlib_drawable xdraw;
+ int i;
+
+ if (fmt == PIPE_FORMAT_NONE || src->format != fmt)
+ return FALSE;
+
+ for (i = 0; i < xdpy->num_configs; i++) {
+ if (xdpy->configs[i].base.color_format == fmt) {
+ xconf = &xdpy->configs[i];
+ break;
+ }
+ }
+ if (!xconf)
+ return FALSE;
+
+ memset(&xdraw, 0, sizeof(xdraw));
+ xdraw.visual = xconf->visual->visual;
+ xdraw.depth = xconf->visual->depth;
+ xdraw.drawable = (Drawable) pix;
+
+ xdpy->base.screen->flush_frontbuffer(xdpy->base.screen,
+ src, 0, 0, &xdraw);
+
+ return TRUE;
+ }
+
+ return native_display_copy_to_pixmap(ndpy, pix, src);
}
static int
@@ -484,13 +524,32 @@ ximage_display_destroy(struct native_display *ndpy)
FREE(xdpy);
}
+static boolean
+ximage_display_init_screen(struct native_display *ndpy)
+{
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ struct sw_winsys *winsys;
+
+ winsys = xlib_create_sw_winsys(xdpy->dpy);
+ if (!winsys)
+ return FALSE;
+
+ xdpy->base.screen =
+ xdpy->event_handler->new_sw_screen(&xdpy->base, winsys);
+ if (!xdpy->base.screen) {
+ if (winsys->destroy)
+ winsys->destroy(winsys);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
struct native_display *
x11_create_ximage_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
struct ximage_display *xdpy;
- struct sw_winsys *winsys = NULL;
xdpy = CALLOC_STRUCT(ximage_display);
if (!xdpy)
@@ -507,39 +566,25 @@ x11_create_ximage_display(Display *dpy,
}
xdpy->event_handler = event_handler;
- xdpy->base.user_data = user_data;
xdpy->xscr_number = DefaultScreen(xdpy->dpy);
xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
- if (!xdpy->xscr)
- goto fail;
-
- winsys = xlib_create_sw_winsys(xdpy->dpy);
- if (!winsys)
- goto fail;
-
- xdpy->base.screen =
- xdpy->event_handler->new_sw_screen(&xdpy->base, winsys);
- if (!xdpy->base.screen)
- goto fail;
+ if (!xdpy->xscr) {
+ if (xdpy->own_dpy)
+ XCloseDisplay(xdpy->dpy);
+ FREE(xdpy);
+ return NULL;
+ }
+ xdpy->base.init_screen = ximage_display_init_screen;
xdpy->base.destroy = ximage_display_destroy;
xdpy->base.get_param = ximage_display_get_param;
xdpy->base.get_configs = ximage_display_get_configs;
- xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported;
+ xdpy->base.get_pixmap_format = ximage_display_get_pixmap_format;
+ xdpy->base.copy_to_pixmap = ximage_display_copy_to_pixmap;
xdpy->base.create_window_surface = ximage_display_create_window_surface;
xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
return &xdpy->base;
-
-fail:
- if (winsys && winsys->destroy)
- winsys->destroy(winsys);
- if (xdpy->xscr)
- x11_screen_destroy(xdpy->xscr);
- if (xdpy->dpy && xdpy->own_dpy)
- XCloseDisplay(xdpy->dpy);
- FREE(xdpy);
- return NULL;
}