summaryrefslogtreecommitdiff
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/Makefile15
-rw-r--r--src/gallium/state_trackers/egl/SConscript38
-rw-r--r--src/gallium/state_trackers/egl/android/native_android.cpp162
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c173
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h1
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c87
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.h3
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.c18
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_sync.c4
-rw-r--r--src/gallium/state_trackers/egl/common/native.h40
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.c150
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.h36
-rw-r--r--src/gallium/state_trackers/egl/drm/modeset.c48
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.c21
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.h2
-rw-r--r--src/gallium/state_trackers/egl/fbdev/native_fbdev.c18
-rw-r--r--src/gallium/state_trackers/egl/gdi/native_gdi.c19
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_wayland.c626
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_wayland.h97
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c91
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c28
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c83
22 files changed, 1425 insertions, 335 deletions
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index 8cfcef968e..53673a78a9 100644
--- a/src/gallium/state_trackers/egl/Makefile
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -23,6 +23,14 @@ x11_SOURCES = $(wildcard x11/*.c) \
$(TOP)/src/glx/dri2.c
x11_OBJECTS = $(x11_SOURCES:.c=.o)
+wayland_INCLUDES = \
+ -I$(TOP)/src/gallium/winsys \
+ -I$(TOP)/src/egl/wayland/wayland-egl \
+ -I$(TOP)/src/egl/wayland/wayland-drm \
+ $(shell pkg-config --cflags-only-I libdrm wayland-client)
+
+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_SOURCES = $(wildcard drm/*.c)
@@ -45,6 +53,10 @@ ifneq ($(findstring x11, $(EGL_PLATFORMS)),)
EGL_OBJECTS += $(x11_OBJECTS)
EGL_CPPFLAGS += -DHAVE_X11_BACKEND
endif
+ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
+EGL_OBJECTS += $(wayland_OBJECTS)
+EGL_CPPFLAGS += -DHAVE_WAYLAND_BACKEND
+endif
ifneq ($(findstring drm, $(EGL_PLATFORMS)),)
EGL_OBJECTS += $(drm_OBJECTS)
EGL_CPPFLAGS += -DHAVE_DRM_BACKEND
@@ -87,6 +99,9 @@ $(common_OBJECTS): %.o: %.c
$(x11_OBJECTS): %.o: %.c
$(call egl-cc,x11)
+$(wayland_OBJECTS): %.o: %.c
+ $(call egl-cc,wayland)
+
$(drm_OBJECTS): %.o: %.c
$(call egl-cc,drm)
diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript
index 50c7681995..9ade76ecbb 100644
--- a/src/gallium/state_trackers/egl/SConscript
+++ b/src/gallium/state_trackers/egl/SConscript
@@ -10,11 +10,8 @@ env.Append(CPPPATH = [
'#/src/gallium/winsys/sw',
'.',
])
-env.Append(CPPDEFINES = [
- 'HAVE_GDI_BACKEND',
-])
-common_sources = [
+sources = [
'common/egl_g3d.c',
'common/egl_g3d_api.c',
'common/egl_g3d_image.c',
@@ -23,12 +20,31 @@ common_sources = [
'common/native_helper.c',
]
-gdi_sources = common_sources + [
- 'gdi/native_gdi.c',
-]
+if env['platform'] == 'windows':
+ env.Append(CPPDEFINES = ['HAVE_GDI_BACKEND'])
+ sources.append('gdi/native_gdi.c')
+else:
+ if env['x11']:
+ env.Append(CPPDEFINES = ['HAVE_X11_BACKEND'])
+ env.Prepend(CPPPATH = [
+ '#/src/glx',
+ '#/src/mapi',
+ ])
+ sources.append([
+ 'x11/native_x11.c',
+ 'x11/native_dri2.c',
+ 'x11/native_ximage.c',
+ 'x11/x11_screen.c',
+ 'x11/glxinit.c'])
+ if env['dri']:
+ env.Append(CPPDEFINES = ['GLX_DIRECT_RENDERING'])
+ sources.append(['#/src/glx/dri2.c'])
+ if env['drm']:
+ env.Append(CPPDEFINES = ['HAVE_DRM_BACKEND'])
+ sources.append(['drm/native_drm.c', 'drm/modeset.c'])
-st_egl_gdi = env.ConvenienceLibrary(
- target = 'st_egl_gdi',
- source = gdi_sources,
+st_egl = env.ConvenienceLibrary(
+ target = 'st_egl',
+ source = sources,
)
-Export('st_egl_gdi')
+Export('st_egl')
diff --git a/src/gallium/state_trackers/egl/android/native_android.cpp b/src/gallium/state_trackers/egl/android/native_android.cpp
index 450eae3868..a584d54db4 100644
--- a/src/gallium/state_trackers/egl/android/native_android.cpp
+++ b/src/gallium/state_trackers/egl/android/native_android.cpp
@@ -34,7 +34,13 @@
extern "C" {
#include "egllog.h"
+
+/* see get_drm_screen_name */
+#include <xf86drm.h>
+#include <radeon_drm.h>
+#include "radeon/drm/radeon_drm_public.h"
}
+
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
@@ -157,12 +163,12 @@ import_buffer(struct android_display *adpy, const struct pipe_resource *templ,
if (templ->bind & PIPE_BIND_RENDER_TARGET) {
if (!screen->is_format_supported(screen, templ->format,
- templ->target, 0, PIPE_BIND_RENDER_TARGET, 0))
+ templ->target, 0, PIPE_BIND_RENDER_TARGET))
LOGW("importing unsupported buffer as render target");
}
if (templ->bind & PIPE_BIND_SAMPLER_VIEW) {
if (!screen->is_format_supported(screen, templ->format,
- templ->target, 0, PIPE_BIND_SAMPLER_VIEW, 0))
+ templ->target, 0, PIPE_BIND_SAMPLER_VIEW))
LOGW("importing unsupported buffer as sampler view");
}
@@ -399,7 +405,7 @@ android_display_create_window_surface(struct native_display *ndpy,
LOGW("native window format 0x%x != config format 0x%x",
format, nconf->color_format);
if (!adpy->base.screen->is_format_supported(adpy->base.screen,
- format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0)) {
+ format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) {
LOGE("and the native window cannot be used as a render target");
return NULL;
}
@@ -452,7 +458,7 @@ android_display_init_configs(struct native_display *ndpy)
color_format = get_pipe_format(native_formats[i]);
if (color_format == PIPE_FORMAT_NONE ||
!adpy->base.screen->is_format_supported(adpy->base.screen,
- color_format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0)) {
+ color_format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) {
LOGI("skip unsupported native format 0x%x", native_formats[i]);
continue;
}
@@ -461,8 +467,6 @@ android_display_init_configs(struct native_display *ndpy)
aconf->base.buffer_mask = 1 << NATIVE_ATTACHMENT_BACK_LEFT;
aconf->base.color_format = color_format;
aconf->base.window_bit = TRUE;
- if (!adpy->use_drm)
- aconf->base.slow_config = TRUE;
aconf->base.native_visual_type = native_formats[i];
}
@@ -470,66 +474,94 @@ android_display_init_configs(struct native_display *ndpy)
return TRUE;
}
+static const char *
+get_drm_screen_name(int fd, drmVersionPtr version)
+{
+ const char *name = version->name;
+
+ if (name && !strcmp(name, "radeon")) {
+ int chip_id;
+ struct drm_radeon_info info;
+
+ memset(&info, 0, sizeof(info));
+ info.request = RADEON_INFO_DEVICE_ID;
+ info.value = pointer_to_intptr(&chip_id);
+ if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0)
+ return NULL;
+
+ name = is_r3xx(chip_id) ? "r300" : "r600";
+ }
+
+ return name;
+}
+
static boolean
-android_display_init(struct native_display *ndpy)
+android_display_init_drm(struct native_display *ndpy)
{
struct android_display *adpy = android_display(ndpy);
const hw_module_t *mod;
int fd, err;
- boolean force_sw;
- char value[PROPERTY_VALUE_MAX];
-
- if (property_get("debug.mesa.software", value, NULL))
- force_sw = (atoi(value) != 0);
- else
- force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
- /* try DRM first */
- if (!force_sw) {
- err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod);
- if (!err) {
- const gralloc_module_t *gr = (gralloc_module_t *) mod;
+ err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod);
+ if (!err) {
+ const gralloc_module_t *gr = (gralloc_module_t *) mod;
- err = -EINVAL;
- if (gr->perform)
- err = gr->perform(gr, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd);
+ err = -EINVAL;
+ if (gr->perform)
+ err = gr->perform(gr, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd);
+ }
+ if (!err && fd >= 0) {
+ drmVersionPtr version;
+ const char *name;
+
+ version = drmGetVersion(fd);
+ if (version) {
+ name = get_drm_screen_name(fd, version);
+ if (name) {
+ adpy->base.screen =
+ adpy->event_handler->new_drm_screen(&adpy->base, name, fd);
+ }
+ drmFreeVersion(version);
}
- if (!err && fd >= 0) {
- adpy->base.screen =
- adpy->event_handler->new_drm_screen(&adpy->base, "i915", fd);
- if (adpy->base.screen)
- adpy->use_drm = TRUE;
+ else {
+ _eglLog(_EGL_WARNING, "invalid fd %d", fd);
+ err = -EINVAL;
}
if (adpy->base.screen)
- LOGI("using DRM screen");
- else
- LOGE("failed to create DRM screen");
+ adpy->use_drm = TRUE;
}
- /* try SW screen */
- if (!adpy->base.screen) {
- struct sw_winsys *ws = android_create_sw_winsys();
+ if (adpy->base.screen) {
+ LOGI("using DRM screen");
+ return TRUE;
+ }
+ else {
+ LOGE("failed to create DRM screen");
+ return FALSE;
+ }
+}
- if (ws) {
- adpy->base.screen =
- adpy->event_handler->new_sw_screen(&adpy->base, ws);
- }
+static boolean
+android_display_init_sw(struct native_display *ndpy)
+{
+ struct android_display *adpy = android_display(ndpy);
+ struct sw_winsys *ws;
- if (adpy->base.screen)
- LOGI("using SW screen");
- else
- LOGE("failed to create SW screen");
+ ws = android_create_sw_winsys();
+ if (ws) {
+ adpy->base.screen =
+ adpy->event_handler->new_sw_screen(&adpy->base, ws);
}
if (adpy->base.screen) {
- if (!android_display_init_configs(&adpy->base)) {
- adpy->base.screen->destroy(adpy->base.screen);
- adpy->base.screen = NULL;
- }
+ LOGI("using SW screen");
+ return TRUE;
+ }
+ else {
+ LOGE("failed to create SW screen");
+ return FALSE;
}
-
- return (adpy->base.screen != NULL);
}
static void
@@ -603,9 +635,11 @@ static struct native_display_buffer android_display_buffer = {
static struct android_display *
android_display_create(struct native_event_handler *event_handler,
- void *user_data)
+ boolean use_sw, void *user_data)
{
struct android_display *adpy;
+ char value[PROPERTY_VALUE_MAX];
+ boolean force_sw;
adpy = CALLOC_STRUCT(android_display);
if (!adpy)
@@ -614,7 +648,23 @@ android_display_create(struct native_event_handler *event_handler,
adpy->event_handler = event_handler;
adpy->base.user_data = user_data;
- if (!android_display_init(&adpy->base)) {
+ if (property_get("debug.mesa.software", value, NULL))
+ force_sw = (atoi(value) != 0);
+ else
+ force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
+
+ if (force_sw || use_sw)
+ android_display_init_sw(&adpy->base);
+ else
+ android_display_init_drm(&adpy->base);
+
+ if (!adpy->base.screen) {
+ FREE(adpy);
+ return NULL;
+ }
+
+ if (!android_display_init_configs(&adpy->base)) {
+ adpy->base.screen->destroy(adpy->base.screen);
FREE(adpy);
return NULL;
}
@@ -629,19 +679,27 @@ android_display_create(struct native_event_handler *event_handler,
return adpy;
}
+static struct native_event_handler *android_event_handler;
+
+static void
+native_set_event_handler(struct native_event_handler *event_handler)
+{
+ android_event_handler = event_handler;
+}
+
static struct native_display *
-native_create_display(void *dpy, struct native_event_handler *event_handler,
- void *user_data)
+native_create_display(void *dpy, boolean use_sw, void *user_data)
{
struct android_display *adpy;
- adpy = android_display_create(event_handler, user_data);
+ adpy = android_display_create(android_event_handler, use_sw, user_data);
return (adpy) ? &adpy->base : NULL;
}
static const struct native_platform android_platform = {
"Android", /* name */
+ native_set_event_handler,
native_create_display
};
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 604091aac0..e455167473 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -38,6 +38,46 @@
#include "egl_g3d_loader.h"
#include "native.h"
+static void
+egl_g3d_invalid_surface(struct native_display *ndpy,
+ struct native_surface *nsurf,
+ unsigned int seq_num)
+{
+ /* 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);
+}
+
+static struct pipe_screen *
+egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
+{
+ _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ return gdpy->loader->create_drm_screen(name, fd);
+}
+
+static struct pipe_screen *
+egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
+{
+ _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ return gdpy->loader->create_sw_screen(ws);
+}
+
+static struct native_event_handler egl_g3d_native_event_handler = {
+ egl_g3d_invalid_surface,
+ egl_g3d_new_drm_screen,
+ egl_g3d_new_sw_screen
+};
+
/**
* Get the native platform.
*/
@@ -62,6 +102,12 @@ egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat)
#ifdef HAVE_X11_BACKEND
nplat = native_get_x11_platform();
#endif
+ break;
+ case _EGL_PLATFORM_WAYLAND:
+ plat_name = "wayland";
+#ifdef HAVE_WAYLAND_BACKEND
+ nplat = native_get_wayland_platform();
+#endif
break;
case _EGL_PLATFORM_DRM:
plat_name = "DRM";
@@ -85,7 +131,9 @@ egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat)
break;
}
- if (!nplat)
+ if (nplat)
+ nplat->set_event_handler(&egl_g3d_native_event_handler);
+ else
_eglLog(_EGL_WARNING, "unsupported platform %s", plat_name);
gdrv->platforms[plat] = nplat;
@@ -189,17 +237,21 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
}
surface_type = 0x0;
- if (nconf->window_bit)
- surface_type |= EGL_WINDOW_BIT;
- if (nconf->pixmap_bit)
- surface_type |= EGL_PIXMAP_BIT;
+ /* pixmap surfaces should be EGL_SINGLE_BUFFER */
+ if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT)) {
+ if (nconf->pixmap_bit)
+ surface_type |= EGL_PIXMAP_BIT;
+ }
+ /* the others surfaces should be EGL_BACK_BUFFER (or settable) */
+ if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)) {
+ if (nconf->window_bit)
+ surface_type |= EGL_WINDOW_BIT;
#ifdef EGL_MESA_screen_surface
- if (nconf->scanout_bit)
- surface_type |= EGL_SCREEN_BIT_MESA;
+ if (nconf->scanout_bit)
+ surface_type |= EGL_SCREEN_BIT_MESA;
#endif
-
- if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT))
surface_type |= EGL_PBUFFER_BIT;
+ }
conf->Conformant = api_mask;
conf->RenderableType = api_mask;
@@ -232,11 +284,6 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
}
conf->Level = nconf->level;
- conf->Samples = nconf->samples;
- conf->SampleBuffers = 0;
-
- if (nconf->slow_config)
- conf->ConfigCaveat = EGL_SLOW_CONFIG;
if (nconf->transparent_rgb) {
conf->TransparentType = EGL_TRANSPARENT_RGB;
@@ -263,13 +310,9 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
int preserve_buffer, int max_swap_interval)
{
struct egl_g3d_config *gconf = egl_g3d_config(conf);
- EGLint buffer_mask, api_mask;
+ EGLint buffer_mask;
EGLBoolean valid;
- /* skip single-buffered configs */
- if (!(nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)))
- return EGL_FALSE;
-
buffer_mask = 0x0;
if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT))
buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
@@ -284,24 +327,14 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
gconf->stvis.color_format = nconf->color_format;
gconf->stvis.depth_stencil_format = depth_stencil_format;
gconf->stvis.accum_format = PIPE_FORMAT_NONE;
- gconf->stvis.samples = nconf->samples;
+ gconf->stvis.samples = 0;
+ /* will be overridden per surface */
gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ?
ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;
- api_mask = dpy->ClientAPIsMask;
- /* this is required by EGL, not by OpenGL ES */
- if (nconf->window_bit &&
- gconf->stvis.render_buffer != ST_ATTACHMENT_BACK_LEFT)
- api_mask &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
-
- if (!api_mask) {
- _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
- nconf->native_visual_id);
- }
-
valid = init_config_attributes(&gconf->base,
- nconf, api_mask, depth_stencil_format,
+ nconf, dpy->ClientAPIs, depth_stencil_format,
preserve_buffer, max_swap_interval);
if (!valid) {
_eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id);
@@ -341,7 +374,7 @@ egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy,
/* pick the first supported format */
for (i = 0; i < n; i++) {
if (screen->is_format_supported(screen, fmt[i],
- PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) {
+ PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) {
formats[count++] = fmt[i];
break;
}
@@ -405,46 +438,6 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
}
static void
-egl_g3d_invalid_surface(struct native_display *ndpy,
- struct native_surface *nsurf,
- unsigned int seq_num)
-{
- /* 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);
-}
-
-static struct pipe_screen *
-egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
-{
- _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- return gdpy->loader->create_drm_screen(name, fd);
-}
-
-static struct pipe_screen *
-egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
-{
- _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- return gdpy->loader->create_sw_screen(ws);
-}
-
-static struct native_event_handler egl_g3d_native_event_handler = {
- egl_g3d_invalid_surface,
- egl_g3d_new_drm_screen,
- egl_g3d_new_sw_screen
-};
-
-static void
egl_g3d_free_config(void *conf)
{
struct egl_g3d_config *gconf = egl_g3d_config((_EGLConfig *) conf);
@@ -468,9 +461,6 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
_eglReleaseDisplayResources(drv, dpy);
- if (gdpy->pipe)
- gdpy->pipe->destroy(gdpy->pipe);
-
if (dpy->Configs) {
_eglDestroyArray(dpy->Configs, egl_g3d_free_config);
dpy->Configs = NULL;
@@ -495,8 +485,7 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
}
static EGLBoolean
-egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
- EGLint *major, EGLint *minor)
+egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct egl_g3d_display *gdpy;
@@ -506,6 +495,9 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
if (!nplat)
return EGL_FALSE;
+ if (dpy->Options.TestOnly)
+ return EGL_TRUE;
+
gdpy = CALLOC_STRUCT(egl_g3d_display);
if (!gdpy) {
_eglError(EGL_BAD_ALLOC, "eglInitialize");
@@ -516,20 +508,20 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
_eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay);
gdpy->native = nplat->create_display(dpy->PlatformDisplay,
- &egl_g3d_native_event_handler, (void *) dpy);
+ dpy->Options.UseFallback, (void *) dpy);
if (!gdpy->native) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
goto fail;
}
if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK)
- dpy->ClientAPIsMask |= EGL_OPENGL_BIT;
+ dpy->ClientAPIs |= EGL_OPENGL_BIT;
if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES1_MASK)
- dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
+ dpy->ClientAPIs |= EGL_OPENGL_ES_BIT;
if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES2_MASK)
- dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
+ dpy->ClientAPIs |= EGL_OPENGL_ES2_BIT;
if (gdpy->loader->profile_masks[ST_API_OPENVG] & ST_PROFILE_DEFAULT_MASK)
- dpy->ClientAPIsMask |= EGL_OPENVG_BIT;
+ dpy->ClientAPIs |= EGL_OPENVG_BIT;
gdpy->smapi = egl_g3d_create_st_manager(dpy);
if (!gdpy->smapi) {
@@ -563,6 +555,9 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
dpy->Extensions.MESA_drm_image = EGL_TRUE;
}
+ if (dpy->Platform == _EGL_PLATFORM_WAYLAND && gdpy->native->buffer)
+ dpy->Extensions.MESA_drm_image = EGL_TRUE;
+
#ifdef EGL_ANDROID_image_native_buffer
if (dpy->Platform == _EGL_PLATFORM_ANDROID && gdpy->native->buffer)
dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
@@ -573,8 +568,8 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
goto fail;
}
- *major = 1;
- *minor = 4;
+ dpy->VersionMajor = 1;
+ dpy->VersionMinor = 4;
return EGL_TRUE;
@@ -599,12 +594,6 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
stapi->get_proc_address(stapi, procname) : NULL);
}
-static EGLint
-egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
-{
- return (egl_g3d_get_platform(drv, dpy->Platform)) ? 90 : 0;
-}
-
_EGLDriver *
egl_g3d_create_driver(const struct egl_g3d_loader *loader)
{
@@ -621,8 +610,6 @@ egl_g3d_create_driver(const struct egl_g3d_loader *loader)
gdrv->base.API.Terminate = egl_g3d_terminate;
gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
- gdrv->base.Probe = egl_g3d_probe;
-
/* to be filled by the caller */
gdrv->base.Name = NULL;
gdrv->base.Unload = NULL;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index a5850635b2..2292d611fc 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -56,7 +56,6 @@ struct egl_g3d_display {
const struct egl_g3d_loader *loader;
struct st_manager *smapi;
- struct pipe_context *pipe;
};
struct egl_g3d_context {
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 8e53e1dccb..f1568329ec 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -158,17 +158,17 @@ egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
(_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
/* perform sorting of configs */
- if (tmp_configs && tmp_size) {
+ if (configs && tmp_size) {
_eglSortConfigs((const _EGLConfig **) tmp_configs, tmp_size,
egl_g3d_compare_config, (void *) &criteria);
- size = MIN2(tmp_size, size);
- for (i = 0; i < size; i++)
+ tmp_size = MIN2(tmp_size, size);
+ for (i = 0; i < tmp_size; i++)
configs[i] = _eglGetConfigHandle(tmp_configs[i]);
}
FREE(tmp_configs);
- *num_configs = size;
+ *num_configs = tmp_size;
return EGL_TRUE;
}
@@ -324,7 +324,8 @@ egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
}
gsurf->stvis = gconf->stvis;
- if (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER)
+ if (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER &&
+ gconf->stvis.buffer_mask & ST_ATTACHMENT_FRONT_LEFT_MASK)
gsurf->stvis.render_buffer = ST_ATTACHMENT_FRONT_LEFT;
gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base);
@@ -402,7 +403,6 @@ egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLConfig *conf, const EGLint *attribs)
{
struct egl_g3d_surface *gsurf;
- struct pipe_resource *ptex = NULL;
gsurf = create_pbuffer_surface(dpy, conf, attribs,
"eglCreatePbufferSurface");
@@ -411,13 +411,6 @@ egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
gsurf->client_buffer_type = EGL_NONE;
- if (!gsurf->stfbi->validate(gsurf->stfbi,
- &gsurf->stvis.render_buffer, 1, &ptex)) {
- egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
- FREE(gsurf);
- return NULL;
- }
-
return &gsurf->base;
}
@@ -477,12 +470,14 @@ egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver *drv, _EGLDisplay *dpy,
gsurf->client_buffer_type = buftype;
gsurf->client_buffer = buffer;
+ /* validate now so that it fails if the client buffer is invalid */
if (!gsurf->stfbi->validate(gsurf->stfbi,
&gsurf->stvis.render_buffer, 1, &ptex)) {
egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
FREE(gsurf);
return NULL;
}
+ pipe_resource_reference(&ptex, NULL);
return &gsurf->base;
}
@@ -533,8 +528,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
old_gctx = egl_g3d_context(old_ctx);
if (old_gctx) {
/* flush old context */
- old_gctx->stctxi->flush(old_gctx->stctxi,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ old_gctx->stctxi->flush(old_gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
if (gctx) {
@@ -611,8 +605,7 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
/* flush if the surface is current */
if (gctx) {
- gctx->stctxi->flush(gctx->stctxi,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
return gsurf->native->present(gsurf->native,
@@ -643,47 +636,36 @@ 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 egl_g3d_config *gconf;
struct native_surface *nsurf;
struct pipe_resource *ptex;
+ struct pipe_context *pipe;
if (!gsurf->render_texture)
return EGL_TRUE;
- gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, target));
- if (!gconf)
- return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
-
- nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
- target, gconf->native);
+ 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,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
- /* create a pipe context to copy surfaces */
- if (!gdpy->pipe) {
- gdpy->pipe =
- gdpy->native->screen->context_create(gdpy->native->screen, NULL);
- if (!gdpy->pipe)
- return EGL_FALSE;
- }
+ 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_resource *psrc = gsurf->render_texture;
struct pipe_box src_box;
+
u_box_origin_2d(ptex->width0, ptex->height0, &src_box);
- if (psrc) {
- gdpy->pipe->resource_copy_region(gdpy->pipe, ptex, 0, 0, 0, 0,
- gsurf->render_texture, 0, &src_box);
- nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0);
- }
+ 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);
}
@@ -701,10 +683,9 @@ egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_fence_handle *fence = NULL;
- gctx->stctxi->flush(gctx->stctxi,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
+ gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, &fence);
if (fence) {
- screen->fence_finish(screen, fence, 0);
+ screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
screen->fence_reference(screen, &fence, NULL);
}
@@ -773,8 +754,7 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
/* flush properly if the surface is bound */
if (gsurf->base.CurrentContext) {
gctx = egl_g3d_context(gsurf->base.CurrentContext);
- gctx->stctxi->flush(gctx->stctxi,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
gctx = egl_g3d_context(es1);
@@ -888,25 +868,6 @@ egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
#endif /* EGL_MESA_screen_surface */
-/**
- * Find a config that supports the pixmap.
- */
-_EGLConfig *
-egl_g3d_find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix)
-{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct egl_g3d_config *gconf;
- EGLint i;
-
- for (i = 0; i < dpy->Configs->Size; i++) {
- gconf = egl_g3d_config((_EGLConfig *) dpy->Configs->Elements[i]);
- if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native))
- break;
- }
-
- return (i < dpy->Configs->Size) ? &gconf->base : NULL;
-}
-
void
egl_g3d_init_driver_api(_EGLDriver *drv)
{
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.h b/src/gallium/state_trackers/egl/common/egl_g3d_api.h
index d5196c12fe..17fd7958aa 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.h
@@ -31,7 +31,4 @@
void
egl_g3d_init_driver_api(_EGLDriver *drv);
-_EGLConfig *
-egl_g3d_find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix);
-
#endif /* _EGL_G3D_API_H_ */
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 b53b121005..1d23305402 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -35,7 +35,6 @@
#include "native.h"
#include "egl_g3d.h"
-#include "egl_g3d_api.h"
#include "egl_g3d_image.h"
/* for struct winsys_handle */
@@ -53,17 +52,11 @@ static struct pipe_resource *
egl_g3d_reference_native_pixmap(_EGLDisplay *dpy, EGLNativePixmapType pix)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct egl_g3d_config *gconf;
struct native_surface *nsurf;
struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
enum native_attachment natt;
- gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, pix));
- if (!gconf)
- return NULL;
-
- nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
- pix, gconf->native);
+ nsurf = gdpy->native->create_pixmap_surface(gdpy->native, pix, NULL);
if (!nsurf)
return NULL;
@@ -123,6 +116,7 @@ egl_g3d_create_drm_buffer(_EGLDisplay *dpy, _EGLImage *img,
templ.width0 = attrs.Width;
templ.height0 = attrs.Height;
templ.depth0 = 1;
+ templ.array_size = 1;
/*
* XXX fix apps (e.g. wayland) and pipe drivers (e.g. i915) and remove the
@@ -147,7 +141,7 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name,
_EGLImageAttribs attrs;
EGLint format;
- if (dpy->Platform != _EGL_PLATFORM_DRM)
+ if (!dpy->Extensions.MESA_drm_image)
return NULL;
if (_eglParseImageAttribList(&attrs, dpy, attribs) != EGL_SUCCESS)
@@ -236,10 +230,12 @@ egl_g3d_reference_android_native_buffer(_EGLDisplay *dpy,
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.format = format;
- templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ /* assume for texturing only */
+ templ.bind = PIPE_BIND_SAMPLER_VIEW;
templ.width0 = buf->width;
templ.height0 = buf->height;
templ.depth0 = 1;
+ templ.array_size = 1;
res = gdpy->native->buffer->import_buffer(gdpy->native,
&templ, (void *) buf);
@@ -385,7 +381,7 @@ egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img,
struct egl_g3d_image *gimg = egl_g3d_image(img);
struct winsys_handle wsh;
- if (dpy->Platform != _EGL_PLATFORM_DRM)
+ if (!dpy->Extensions.MESA_drm_image)
return EGL_FALSE;
/* get shared handle */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
index 4e6d944c15..dd07af140a 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
@@ -109,7 +109,7 @@ egl_g3d_wait_fence_sync(struct egl_g3d_sync *gsync, EGLTimeKHR timeout)
_eglUnlockMutex(&dpy->Mutex);
/* no timed finish? */
- screen->fence_finish(screen, fence, 0x0);
+ screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
ret = EGL_CONDITION_SATISFIED_KHR;
_eglLockMutex(&dpy->Mutex);
@@ -234,7 +234,7 @@ egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
if (gctx)
- gctx->stctxi->flush(gctx->stctxi, PIPE_FLUSH_RENDER_CACHE , NULL);
+ gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
if (timeout) {
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index ca8cb97f71..9e9cd3fd05 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -126,8 +126,6 @@ struct native_config {
int native_visual_id;
int native_visual_type;
int level;
- int samples;
- boolean slow_config;
boolean transparent_rgb;
int transparent_rgb_values[3];
};
@@ -144,6 +142,11 @@ struct native_display {
struct pipe_screen *screen;
/**
+ * Context used for copy operations.
+ */
+ struct pipe_context *pipe;
+
+ /**
* Available for caller's use.
*/
void *user_data;
@@ -185,7 +188,9 @@ struct native_display {
const struct native_config *nconf);
/**
- * Create a pixmap surface. Required unless no config has pixmap_bit set.
+ * Create a pixmap surface. The native config may be NULL. In that case, a
+ * "best config" will be picked. Required unless no config has pixmap_bit
+ * set.
*/
struct native_surface *(*create_pixmap_surface)(struct native_display *ndpy,
EGLNativePixmapType pix,
@@ -223,11 +228,35 @@ native_attachment_mask_test(uint mask, enum native_attachment att)
return !!(mask & (1 << att));
}
+/**
+ * Get the display copy context
+ */
+static INLINE struct pipe_context *
+ndpy_get_copy_context(struct native_display *ndpy)
+{
+ if (!ndpy->pipe)
+ ndpy->pipe = ndpy->screen->context_create(ndpy->screen, NULL);
+ return ndpy->pipe;
+}
+
+/**
+ * Free display screen and context resources
+ */
+static INLINE void
+ndpy_uninit(struct native_display *ndpy)
+{
+ if (ndpy->pipe)
+ ndpy->pipe->destroy(ndpy->pipe);
+ if (ndpy->screen)
+ ndpy->screen->destroy(ndpy->screen);
+}
+
struct native_platform {
const char *name;
+ void (*set_event_handler)(struct native_event_handler *handler);
struct native_display *(*create_display)(void *dpy,
- struct native_event_handler *handler,
+ boolean use_sw,
void *user_data);
};
@@ -238,6 +267,9 @@ const struct native_platform *
native_get_x11_platform(void);
const struct native_platform *
+native_get_wayland_platform(void);
+
+const struct native_platform *
native_get_drm_platform(void);
const struct native_platform *
diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c
index 0f2d02032b..ee18cb2025 100644
--- a/src/gallium/state_trackers/egl/common/native_helper.c
+++ b/src/gallium/state_trackers/egl/common/native_helper.c
@@ -3,6 +3,7 @@
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
+ * Copyright (C) 2011 VMware Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -24,6 +25,7 @@
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
+ * Thomas Hellstrom <thellstrom@vmware.com>
*/
#include "util/u_inlines.h"
@@ -34,6 +36,14 @@
#include "native_helper.h"
+/**
+ * Number of swap fences and mask
+ */
+
+#define EGL_SWAP_FENCES_MAX 4
+#define EGL_SWAP_FENCES_MASK 3
+#define EGL_SWAP_FENCES_DEFAULT 1
+
struct resource_surface {
struct pipe_screen *screen;
enum pipe_format format;
@@ -42,6 +52,15 @@ struct resource_surface {
struct pipe_resource *resources[NUM_NATIVE_ATTACHMENTS];
uint resource_mask;
uint width, height;
+
+ /**
+ * Swap fences.
+ */
+ struct pipe_fence_handle *swap_fences[EGL_SWAP_FENCES_MAX];
+ unsigned int cur_fences;
+ unsigned int head;
+ unsigned int tail;
+ unsigned int desired_fences;
};
struct resource_surface *
@@ -49,11 +68,16 @@ resource_surface_create(struct pipe_screen *screen,
enum pipe_format format, uint bind)
{
struct resource_surface *rsurf = CALLOC_STRUCT(resource_surface);
+ char *swap_fences = getenv("EGL_THROTTLE_FENCES");
if (rsurf) {
rsurf->screen = screen;
rsurf->format = format;
rsurf->bind = bind;
+ rsurf->desired_fences = (swap_fences) ? atoi(swap_fences) :
+ EGL_SWAP_FENCES_DEFAULT;
+ if (rsurf->desired_fences > EGL_SWAP_FENCES_MAX)
+ rsurf->desired_fences = EGL_SWAP_FENCES_MAX;
}
return rsurf;
@@ -143,6 +167,14 @@ resource_surface_add_resources(struct resource_surface *rsurf,
return ((rsurf->resource_mask & resource_mask) == resource_mask);
}
+void
+resource_surface_import_resource(struct resource_surface *rsurf,
+ enum native_attachment which,
+ struct pipe_resource *pres)
+{
+ pipe_resource_reference(&rsurf->resources[which], pres);
+ rsurf->resource_mask |= 1 << which;
+}
void
resource_surface_get_resources(struct resource_surface *rsurf,
@@ -217,3 +249,121 @@ resource_surface_present(struct resource_surface *rsurf,
return TRUE;
}
+
+/**
+ * Schedule a copy swap from the back to the front buffer using the
+ * native display's copy context.
+ */
+boolean
+resource_surface_copy_swap(struct resource_surface *rsurf,
+ struct native_display *ndpy)
+{
+ struct pipe_resource *ftex;
+ struct pipe_resource *btex;
+ struct pipe_context *pipe;
+ struct pipe_box src_box;
+ boolean ret = FALSE;
+
+ pipe = ndpy_get_copy_context(ndpy);
+ if (!pipe)
+ return FALSE;
+
+ ftex = resource_surface_get_single_resource(rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT);
+ if (!ftex)
+ goto out_no_ftex;
+ btex = resource_surface_get_single_resource(rsurf,
+ NATIVE_ATTACHMENT_BACK_LEFT);
+ if (!btex)
+ goto out_no_btex;
+
+ u_box_origin_2d(ftex->width0, ftex->height0, &src_box);
+ pipe->resource_copy_region(pipe, ftex, 0, 0, 0, 0,
+ btex, 0, &src_box);
+ ret = TRUE;
+
+ out_no_ftex:
+ pipe_resource_reference(&btex, NULL);
+ out_no_btex:
+ pipe_resource_reference(&ftex, NULL);
+
+ return ret;
+}
+
+static struct pipe_fence_handle *
+swap_fences_pop_front(struct resource_surface *rsurf)
+{
+ struct pipe_screen *screen = rsurf->screen;
+ struct pipe_fence_handle *fence = NULL;
+
+ if (rsurf->desired_fences == 0)
+ return NULL;
+
+ if (rsurf->cur_fences >= rsurf->desired_fences) {
+ screen->fence_reference(screen, &fence, rsurf->swap_fences[rsurf->tail]);
+ screen->fence_reference(screen, &rsurf->swap_fences[rsurf->tail++], NULL);
+ rsurf->tail &= EGL_SWAP_FENCES_MASK;
+ --rsurf->cur_fences;
+ }
+ return fence;
+}
+
+static void
+swap_fences_push_back(struct resource_surface *rsurf,
+ struct pipe_fence_handle *fence)
+{
+ struct pipe_screen *screen = rsurf->screen;
+
+ if (!fence || rsurf->desired_fences == 0)
+ return;
+
+ while(rsurf->cur_fences == rsurf->desired_fences)
+ swap_fences_pop_front(rsurf);
+
+ rsurf->cur_fences++;
+ screen->fence_reference(screen, &rsurf->swap_fences[rsurf->head++],
+ fence);
+ rsurf->head &= EGL_SWAP_FENCES_MASK;
+}
+
+boolean
+resource_surface_throttle(struct resource_surface *rsurf)
+{
+ struct pipe_screen *screen = rsurf->screen;
+ struct pipe_fence_handle *fence = swap_fences_pop_front(rsurf);
+
+ if (fence) {
+ (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
+ screen->fence_reference(screen, &fence, NULL);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+boolean
+resource_surface_flush(struct resource_surface *rsurf,
+ struct native_display *ndpy)
+{
+ struct pipe_fence_handle *fence = NULL;
+ struct pipe_screen *screen = rsurf->screen;
+ struct pipe_context *pipe= ndpy_get_copy_context(ndpy);
+
+ if (!pipe)
+ return FALSE;
+
+ pipe->flush(pipe, &fence);
+ if (fence == NULL)
+ return FALSE;
+
+ swap_fences_push_back(rsurf, fence);
+ screen->fence_reference(screen, &fence, NULL);
+
+ return TRUE;
+}
+
+void
+resource_surface_wait(struct resource_surface *rsurf)
+{
+ while (resource_surface_throttle(rsurf));
+}
diff --git a/src/gallium/state_trackers/egl/common/native_helper.h b/src/gallium/state_trackers/egl/common/native_helper.h
index d1569ac3ea..39564a0436 100644
--- a/src/gallium/state_trackers/egl/common/native_helper.h
+++ b/src/gallium/state_trackers/egl/common/native_helper.h
@@ -3,6 +3,7 @@
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
+ * Copyright (C) 2011 VMware Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -24,6 +25,7 @@
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
+ * Thomas Hellstrom <thellstrom@vmware.com>
*/
#include "native.h"
@@ -51,6 +53,11 @@ resource_surface_add_resources(struct resource_surface *rsurf,
uint resource_mask);
void
+resource_surface_import_resource(struct resource_surface *rsurf,
+ enum native_attachment which,
+ struct pipe_resource *pres);
+
+void
resource_surface_get_resources(struct resource_surface *rsurf,
struct pipe_resource **resources,
uint resource_mask);
@@ -69,3 +76,32 @@ boolean
resource_surface_present(struct resource_surface *rsurf,
enum native_attachment which,
void *winsys_drawable_handle);
+
+/**
+ * Perform a gallium copy blit between the back left and front left
+ * surfaces. Needs to be followed by a call to resource_surface_flush.
+ */
+boolean
+resource_surface_copy_swap(struct resource_surface *rsurf,
+ struct native_display *ndpy);
+
+/**
+ * Throttle on outstanding rendering using the copy context. For example
+ * copy swaps.
+ */
+boolean
+resource_surface_throttle(struct resource_surface *rsurf);
+
+/**
+ * Flush pending rendering using the copy context. This function saves a
+ * marker for upcoming throttles.
+ */
+boolean
+resource_surface_flush(struct resource_surface *rsurf,
+ struct native_display *ndpy);
+/**
+ * Wait for all rendering using the copy context to be complete. Frees all
+ * throttle markers saved using resource_surface_flush.
+ */
+void
+resource_surface_wait(struct resource_surface *rsurf);
diff --git a/src/gallium/state_trackers/egl/drm/modeset.c b/src/gallium/state_trackers/egl/drm/modeset.c
index 0cc06caa2a..3fff954090 100644
--- a/src/gallium/state_trackers/egl/drm/modeset.c
+++ b/src/gallium/state_trackers/egl/drm/modeset.c
@@ -3,6 +3,7 @@
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
+ * Copyright (C) 2011 VMware Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -24,6 +25,7 @@
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
+ * Thomas Hellstrom <thellstrom@vmware.com>
*/
#include "util/u_memory.h"
@@ -131,6 +133,25 @@ drm_surface_flush_frontbuffer(struct native_surface *nsurf)
}
static boolean
+drm_surface_copy_swap(struct native_surface *nsurf)
+{
+ struct drm_surface *drmsurf = drm_surface(nsurf);
+ struct drm_display *drmdpy = drmsurf->drmdpy;
+
+ (void) resource_surface_throttle(drmsurf->rsurf);
+ if (!resource_surface_copy_swap(drmsurf->rsurf, &drmdpy->base))
+ return FALSE;
+
+ (void) resource_surface_flush(drmsurf->rsurf, &drmdpy->base);
+ if (!drm_surface_flush_frontbuffer(nsurf))
+ return FALSE;
+
+ drmsurf->sequence_number++;
+
+ return TRUE;
+}
+
+static boolean
drm_surface_swap_buffers(struct native_surface *nsurf)
{
struct drm_surface *drmsurf = drm_surface(nsurf);
@@ -139,17 +160,21 @@ drm_surface_swap_buffers(struct native_surface *nsurf)
struct drm_framebuffer tmp_fb;
int err;
+ if (!drmsurf->have_pageflip)
+ return drm_surface_copy_swap(nsurf);
+
if (!drmsurf->back_fb.buffer_id) {
if (!drm_surface_init_framebuffers(&drmsurf->base, TRUE))
return FALSE;
}
if (drmsurf->is_shown && drmcrtc->crtc) {
- err = drmModeSetCrtc(drmdpy->fd, drmcrtc->crtc->crtc_id,
- drmsurf->back_fb.buffer_id, drmcrtc->crtc->x, drmcrtc->crtc->y,
- drmcrtc->connectors, drmcrtc->num_connectors, &drmcrtc->crtc->mode);
- if (err)
- return FALSE;
+ err = drmModePageFlip(drmdpy->fd, drmcrtc->crtc->crtc_id,
+ drmsurf->back_fb.buffer_id, 0, NULL);
+ if (err) {
+ drmsurf->have_pageflip = FALSE;
+ return drm_surface_copy_swap(nsurf);
+ }
}
/* swap the buffers */
@@ -175,7 +200,7 @@ drm_surface_present(struct native_surface *nsurf,
{
boolean ret;
- if (preserve || swap_interval)
+ if (swap_interval)
return FALSE;
switch (natt) {
@@ -183,7 +208,10 @@ drm_surface_present(struct native_surface *nsurf,
ret = drm_surface_flush_frontbuffer(nsurf);
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
- ret = drm_surface_swap_buffers(nsurf);
+ if (preserve)
+ ret = drm_surface_copy_swap(nsurf);
+ else
+ ret = drm_surface_swap_buffers(nsurf);
break;
default:
ret = FALSE;
@@ -196,7 +224,9 @@ drm_surface_present(struct native_surface *nsurf,
static void
drm_surface_wait(struct native_surface *nsurf)
{
- /* no-op */
+ struct drm_surface *drmsurf = drm_surface(nsurf);
+
+ resource_surface_wait(drmsurf->rsurf);
}
static void
@@ -204,6 +234,7 @@ drm_surface_destroy(struct native_surface *nsurf)
{
struct drm_surface *drmsurf = drm_surface(nsurf);
+ resource_surface_wait(drmsurf->rsurf);
if (drmsurf->current_crtc.crtc)
drmModeFreeCrtc(drmsurf->current_crtc.crtc);
@@ -236,6 +267,7 @@ drm_display_create_surface(struct native_display *ndpy,
drmsurf->color_format = drmconf->base.color_format;
drmsurf->width = width;
drmsurf->height = height;
+ drmsurf->have_pageflip = TRUE;
drmsurf->rsurf = resource_surface_create(drmdpy->base.screen,
drmsurf->color_format,
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c
index 2441b43fd8..9863329ff4 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.c
+++ b/src/gallium/state_trackers/egl/drm/native_drm.c
@@ -43,7 +43,7 @@ drm_display_is_format_supported(struct native_display *ndpy,
return ndpy->screen->is_format_supported(ndpy->screen,
fmt, PIPE_TEXTURE_2D, 0,
(is_color) ? PIPE_BIND_RENDER_TARGET :
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
}
static const struct native_config **
@@ -124,8 +124,7 @@ drm_display_destroy(struct native_display *ndpy)
drm_display_fini_modeset(&drmdpy->base);
- if (drmdpy->base.screen)
- drmdpy->base.screen->destroy(drmdpy->base.screen);
+ ndpy_uninit(ndpy);
if (drmdpy->fd >= 0)
close(drmdpy->fd);
@@ -178,7 +177,7 @@ drm_display_init_screen(struct native_display *ndpy)
drmFreeVersion(version);
if (!drmdpy->base.screen) {
- _eglLog(_EGL_WARNING, "failed to create DRM screen");
+ _eglLog(_EGL_DEBUG, "failed to create DRM screen");
return FALSE;
}
@@ -237,9 +236,16 @@ 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 struct native_display *
-native_create_display(void *dpy, struct native_event_handler *event_handler,
- void *user_data)
+native_create_display(void *dpy, boolean use_sw, void *user_data)
{
int fd;
@@ -252,11 +258,12 @@ native_create_display(void *dpy, struct native_event_handler *event_handler,
if (fd < 0)
return NULL;
- return drm_create_display(fd, event_handler, user_data);
+ return drm_create_display(fd, drm_event_handler, user_data);
}
static const struct native_platform drm_platform = {
"DRM", /* name */
+ native_set_event_handler,
native_create_display
};
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.h b/src/gallium/state_trackers/egl/drm/native_drm.h
index 03c4fe01dc..7da9b45f23 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.h
+++ b/src/gallium/state_trackers/egl/drm/native_drm.h
@@ -91,6 +91,8 @@ struct drm_surface {
boolean is_shown;
struct drm_crtc current_crtc;
+
+ boolean have_pageflip;
};
struct drm_connector {
diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
index 1b5ea8bf9d..e2fde00e97 100644
--- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
+++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
@@ -320,7 +320,7 @@ fbdev_display_destroy(struct native_display *ndpy)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
- fbdpy->base.screen->destroy(fbdpy->base.screen);
+ ndpy_uninit(&fbdpy->base);
close(fbdpy->fd);
FREE(fbdpy);
}
@@ -422,7 +422,7 @@ fbdev_display_init(struct native_display *ndpy)
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, 0)) {
+ PIPE_BIND_RENDER_TARGET)) {
fbdpy->base.screen->destroy(fbdpy->base.screen);
fbdpy->base.screen = NULL;
}
@@ -459,9 +459,16 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler,
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;
+}
+
static struct native_display *
-native_create_display(void *dpy, struct native_event_handler *event_handler,
- void *user_data)
+native_create_display(void *dpy, boolean use_sw, void *user_data)
{
struct native_display *ndpy;
int fd;
@@ -476,7 +483,7 @@ native_create_display(void *dpy, struct native_event_handler *event_handler,
if (fd < 0)
return NULL;
- ndpy = fbdev_display_create(fd, event_handler, user_data);
+ ndpy = fbdev_display_create(fd, fbdev_event_handler, user_data);
if (!ndpy)
close(fd);
@@ -485,6 +492,7 @@ native_create_display(void *dpy, struct native_event_handler *event_handler,
static const struct native_platform fbdev_platform = {
"FBDEV", /* name */
+ native_set_event_handler,
native_create_display
};
diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c
index d259e6edc8..5d0045f92e 100644
--- a/src/gallium/state_trackers/egl/gdi/native_gdi.c
+++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c
@@ -285,7 +285,7 @@ fill_color_formats(struct native_display *ndpy, enum pipe_format formats[8])
for (i = 0; i < Elements(candidates); i++) {
if (screen->is_format_supported(screen, candidates[i],
- PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0))
+ PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET))
formats[count++] = candidates[i];
}
@@ -319,7 +319,6 @@ gdi_display_get_configs(struct native_display *ndpy, int *num_configs)
nconf->color_format = formats[i];
nconf->window_bit = TRUE;
- nconf->slow_config = TRUE;
}
gdpy->num_configs = count;
@@ -364,7 +363,7 @@ gdi_display_destroy(struct native_display *ndpy)
if (gdpy->configs)
FREE(gdpy->configs);
- gdpy->base.screen->destroy(gdpy->base.screen);
+ ndpy_uninit(ndpy);
FREE(gdpy);
}
@@ -407,15 +406,23 @@ 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 struct native_display *
-native_create_display(void *dpy, struct native_event_handler *event_handler,
- void *user_data)
+native_create_display(void *dpy, boolean use_sw, void *user_data)
{
- return gdi_create_display((HDC) dpy, event_handler, user_data);
+ return gdi_create_display((HDC) dpy, gdi_event_handler, user_data);
}
static const struct native_platform gdi_platform = {
"GDI", /* name */
+ native_set_event_handler,
native_create_display
};
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c
new file mode 100644
index 0000000000..068c3cd7c8
--- /dev/null
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c
@@ -0,0 +1,626 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.11
+ *
+ * Copyright (C) 2011 Benjamin Franzke <benjaminfranzke@googlemail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "state_tracker/drm_driver.h"
+
+#include "egllog.h"
+
+#include "native_wayland.h"
+
+/* see get_drm_screen_name */
+#include <radeon_drm.h>
+#include "radeon/drm/radeon_drm_public.h"
+
+#include <wayland-client.h>
+#include "wayland-drm-client-protocol.h"
+#include "wayland-egl-priv.h"
+
+#include <xf86drm.h>
+
+static struct native_event_handler *wayland_event_handler;
+
+static void
+sync_callback(void *data)
+{
+ int *done = data;
+
+ *done = 1;
+}
+
+static void
+force_roundtrip(struct wl_display *display)
+{
+ int done = 0;
+
+ wl_display_sync_callback(display, sync_callback, &done);
+ wl_display_iterate(display, WL_DISPLAY_WRITABLE);
+ while (!done)
+ wl_display_iterate(display, WL_DISPLAY_READABLE);
+}
+
+static const struct native_config **
+wayland_display_get_configs (struct native_display *ndpy, int *num_configs)
+{
+ struct wayland_display *display = wayland_display(ndpy);
+ const struct native_config **configs;
+
+ if (!display->config) {
+ struct native_config *nconf;
+ enum pipe_format format;
+ display->config = CALLOC(1, sizeof(*display->config));
+ if (!display->config)
+ return NULL;
+ nconf = &display->config->base;
+
+ nconf->buffer_mask =
+ (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
+ (1 << NATIVE_ATTACHMENT_BACK_LEFT);
+
+ format = PIPE_FORMAT_B8G8R8A8_UNORM;
+
+ nconf->color_format = format;
+ nconf->window_bit = TRUE;
+ nconf->pixmap_bit = TRUE;
+ }
+
+ configs = MALLOC(sizeof(*configs));
+ if (configs) {
+ configs[0] = &display->config->base;
+ if (num_configs)
+ *num_configs = 1;
+ }
+
+ return configs;
+}
+
+static int
+wayland_display_get_param(struct native_display *ndpy,
+ enum native_param_type param)
+{
+ int val;
+
+ switch (param) {
+ case NATIVE_PARAM_USE_NATIVE_BUFFER:
+ case NATIVE_PARAM_PRESERVE_BUFFER:
+ case NATIVE_PARAM_MAX_SWAP_INTERVAL:
+ default:
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
+static boolean
+wayland_display_is_pixmap_supported(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ /* all wl_egl_pixmaps are supported */
+
+ return TRUE;
+}
+
+static void
+wayland_display_destroy(struct native_display *ndpy)
+{
+ struct wayland_display *display = wayland_display(ndpy);
+
+ if (display->config)
+ FREE(display->config);
+
+ ndpy_uninit(ndpy);
+
+ FREE(display);
+}
+
+
+static struct wl_buffer *
+wayland_create_buffer(struct wayland_surface *surface,
+ enum native_attachment attachment)
+{
+ struct wayland_display *display = surface->display;
+ struct pipe_resource *resource;
+ struct winsys_handle wsh;
+ uint width, height;
+
+ resource = resource_surface_get_single_resource(surface->rsurf, attachment);
+ resource_surface_get_size(surface->rsurf, &width, &height);
+
+ wsh.type = DRM_API_HANDLE_TYPE_SHARED;
+ display->base.screen->resource_get_handle(display->base.screen, resource, &wsh);
+
+ pipe_resource_reference(&resource, NULL);
+
+ return wl_drm_create_buffer(display->dpy->drm, wsh.handle,
+ width, height,
+ wsh.stride, surface->win->visual);
+}
+
+static void
+wayland_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap)
+{
+ struct pipe_resource *resource = egl_pixmap->driver_private;
+
+ assert(resource);
+
+ pipe_resource_reference(&resource, NULL);
+
+ egl_pixmap->driver_private = NULL;
+ egl_pixmap->destroy = NULL;
+ egl_pixmap->name = 0;
+}
+
+static void
+wayland_pixmap_surface_intialize(struct wayland_surface *surface)
+{
+ struct native_display *ndpy = &surface->display->base;
+ struct pipe_resource *resource;
+ struct winsys_handle wsh;
+ const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+
+ if (surface->pix->name > 0)
+ return;
+
+ resource = resource_surface_get_single_resource(surface->rsurf, front_natt);
+
+ wsh.type = DRM_API_HANDLE_TYPE_SHARED;
+ ndpy->screen->resource_get_handle(ndpy->screen, resource, &wsh);
+
+ surface->pix->name = wsh.handle;
+ surface->pix->stride = wsh.stride;
+ surface->pix->destroy = wayland_pixmap_destroy;
+ surface->pix->driver_private = resource;
+}
+
+static void
+wayland_release_pending_resource(void *data)
+{
+ struct wayland_surface *surface = data;
+
+ /* FIXME: print internal error */
+ if (!surface->pending_resource)
+ return;
+
+ pipe_resource_reference(&surface->pending_resource, NULL);
+}
+
+static void
+wayland_window_surface_handle_resize(struct wayland_surface *surface)
+{
+ struct wayland_display *display = surface->display;
+ struct pipe_resource *front_resource;
+ const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ int i;
+
+ front_resource = resource_surface_get_single_resource(surface->rsurf,
+ front_natt);
+ if (resource_surface_set_size(surface->rsurf,
+ surface->win->width, surface->win->height)) {
+
+ if (surface->pending_resource)
+ force_roundtrip(display->dpy->display);
+
+ if (front_resource) {
+ surface->pending_resource = front_resource;
+ front_resource = NULL;
+ wl_display_sync_callback(display->dpy->display,
+ wayland_release_pending_resource, surface);
+ }
+
+ for (i = 0; i < WL_BUFFER_COUNT; ++i) {
+ if (surface->buffer[i])
+ wl_buffer_destroy(surface->buffer[i]);
+ surface->buffer[i] = NULL;
+ }
+ }
+ 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
+wayland_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_resource **textures,
+ int *width, int *height)
+{
+ struct wayland_surface *surface = wayland_surface(nsurf);
+
+ if (surface->type == WL_WINDOW_SURFACE)
+ wayland_window_surface_handle_resize(surface);
+
+ if (!resource_surface_add_resources(surface->rsurf, attachment_mask |
+ surface->attachment_mask))
+ return FALSE;
+
+ if (textures)
+ resource_surface_get_resources(surface->rsurf, textures, attachment_mask);
+
+ if (seq_num)
+ *seq_num = surface->sequence_number;
+
+ resource_surface_get_size(surface->rsurf, (uint *) width, (uint *) height);
+
+ if (surface->type == WL_PIXMAP_SURFACE)
+ wayland_pixmap_surface_intialize(surface);
+
+ return TRUE;
+}
+
+static void
+wayland_frame_callback(void *data, uint32_t time)
+{
+ struct wayland_surface *surface = data;
+
+ surface->block_swap_buffers = FALSE;
+}
+
+static INLINE void
+wayland_buffers_swap(struct wl_buffer **buffer,
+ enum wayland_buffer_type buf1,
+ enum wayland_buffer_type buf2)
+{
+ struct wl_buffer *tmp = buffer[buf1];
+ buffer[buf1] = buffer[buf2];
+ buffer[buf2] = tmp;
+}
+
+static boolean
+wayland_surface_swap_buffers(struct native_surface *nsurf)
+{
+ struct wayland_surface *surface = wayland_surface(nsurf);
+ struct wayland_display *display = surface->display;
+
+ while (surface->block_swap_buffers)
+ wl_display_iterate(display->dpy->display, WL_DISPLAY_READABLE);
+
+ surface->block_swap_buffers = TRUE;
+ wl_display_frame_callback(display->dpy->display, wayland_frame_callback,
+ surface);
+
+ if (surface->type == WL_WINDOW_SURFACE) {
+ resource_surface_swap_buffers(surface->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, FALSE);
+
+ wayland_buffers_swap(surface->buffer, WL_BUFFER_FRONT, WL_BUFFER_BACK);
+
+ if (surface->buffer[WL_BUFFER_FRONT] == NULL)
+ surface->buffer[WL_BUFFER_FRONT] =
+ wayland_create_buffer(surface, NATIVE_ATTACHMENT_FRONT_LEFT);
+
+ wl_surface_attach(surface->win->surface, surface->buffer[WL_BUFFER_FRONT],
+ surface->dx, surface->dy);
+
+ resource_surface_get_size(surface->rsurf,
+ (uint *) &surface->win->attached_width,
+ (uint *) &surface->win->attached_height);
+ surface->dx = 0;
+ surface->dy = 0;
+ }
+
+ surface->sequence_number++;
+ wayland_event_handler->invalid_surface(&display->base,
+ &surface->base, surface->sequence_number);
+
+ return TRUE;
+}
+
+static boolean
+wayland_surface_present(struct native_surface *nsurf,
+ enum native_attachment natt,
+ boolean preserve,
+ uint swap_interval)
+{
+ struct wayland_surface *surface = wayland_surface(nsurf);
+ uint width, height;
+ boolean ret;
+
+ if (preserve || swap_interval)
+ return FALSE;
+
+ switch (natt) {
+ case NATIVE_ATTACHMENT_FRONT_LEFT:
+ ret = TRUE;
+ break;
+ case NATIVE_ATTACHMENT_BACK_LEFT:
+ ret = wayland_surface_swap_buffers(nsurf);
+ break;
+ default:
+ ret = FALSE;
+ break;
+ }
+
+ if (surface->type == WL_WINDOW_SURFACE) {
+ resource_surface_get_size(surface->rsurf, &width, &height);
+ wl_surface_damage(surface->win->surface, 0, 0, width, height);
+ }
+
+ return ret;
+}
+
+static void
+wayland_surface_wait(struct native_surface *nsurf)
+{
+ /* no-op */
+}
+
+static void
+wayland_surface_destroy(struct native_surface *nsurf)
+{
+ struct wayland_surface *surface = wayland_surface(nsurf);
+ enum wayland_buffer_type buffer;
+
+ for (buffer = 0; buffer < WL_BUFFER_COUNT; ++buffer) {
+ if (surface->buffer[buffer])
+ wl_buffer_destroy(surface->buffer[buffer]);
+ }
+
+ resource_surface_destroy(surface->rsurf);
+ FREE(surface);
+}
+
+static struct native_surface *
+wayland_create_pixmap_surface(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct wayland_display *display = wayland_display(ndpy);
+ struct wayland_config *config = wayland_config(nconf);
+ struct wayland_surface *surface;
+ struct wl_egl_pixmap *egl_pixmap = (struct wl_egl_pixmap *) pix;
+ enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+
+ surface = CALLOC_STRUCT(wayland_surface);
+ if (!surface)
+ return NULL;
+
+ surface->display = display;
+
+ surface->pending_resource = NULL;
+ surface->type = WL_PIXMAP_SURFACE;
+ surface->pix = egl_pixmap;
+
+ if (surface->pix->visual == wl_display_get_rgb_visual(display->dpy->display))
+ surface->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ else
+ surface->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+
+ surface->attachment_mask = (1 << NATIVE_ATTACHMENT_FRONT_LEFT);
+
+ surface->rsurf = resource_surface_create(display->base.screen,
+ surface->color_format,
+ PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT);
+
+ if (!surface->rsurf) {
+ FREE(surface);
+ return NULL;
+ }
+
+ resource_surface_set_size(surface->rsurf,
+ egl_pixmap->width, egl_pixmap->height);
+
+ /* the pixmap is already allocated, so import it */
+ if (surface->pix->name > 0)
+ resource_surface_import_resource(surface->rsurf, natt,
+ surface->pix->driver_private);
+
+ surface->base.destroy = wayland_surface_destroy;
+ surface->base.present = wayland_surface_present;
+ surface->base.validate = wayland_surface_validate;
+ surface->base.wait = wayland_surface_wait;
+
+ return &surface->base;
+}
+
+static struct native_surface *
+wayland_create_window_surface(struct native_display *ndpy,
+ EGLNativeWindowType win,
+ const struct native_config *nconf)
+{
+ struct wayland_display *display = wayland_display(ndpy);
+ struct wayland_config *config = wayland_config(nconf);
+ struct wayland_surface *surface;
+
+ surface = CALLOC_STRUCT(wayland_surface);
+ if (!surface)
+ return NULL;
+
+ surface->display = display;
+ surface->color_format = config->base.color_format;
+
+ surface->win = (struct wl_egl_window *) win;
+
+ surface->pending_resource = NULL;
+ surface->block_swap_buffers = FALSE;
+ surface->type = WL_WINDOW_SURFACE;
+
+ surface->buffer[WL_BUFFER_FRONT] = NULL;
+ surface->buffer[WL_BUFFER_BACK] = NULL;
+ surface->attachment_mask = (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
+ (1 << NATIVE_ATTACHMENT_BACK_LEFT);
+
+ surface->rsurf = resource_surface_create(display->base.screen,
+ surface->color_format,
+ PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT);
+
+ if (!surface->rsurf) {
+ FREE(surface);
+ return NULL;
+ }
+
+ surface->base.destroy = wayland_surface_destroy;
+ surface->base.present = wayland_surface_present;
+ surface->base.validate = wayland_surface_validate;
+ surface->base.wait = wayland_surface_wait;
+
+ return &surface->base;
+}
+
+static const char *
+get_drm_screen_name(int fd, drmVersionPtr version)
+{
+ const char *name = version->name;
+
+ if (name && !strcmp(name, "radeon")) {
+ int chip_id;
+ struct drm_radeon_info info;
+
+ memset(&info, 0, sizeof(info));
+ info.request = RADEON_INFO_DEVICE_ID;
+ info.value = pointer_to_intptr(&chip_id);
+ if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0)
+ return NULL;
+
+ name = is_r3xx(chip_id) ? "r300" : "r600";
+ }
+
+ return name;
+}
+
+static boolean
+wayland_display_init_screen(struct native_display *ndpy)
+{
+ struct wayland_display *display = wayland_display(ndpy);
+ drmVersionPtr version;
+ const char *driver_name;
+
+ if (display->dpy->fd == -1)
+ force_roundtrip(display->dpy->display);
+ if (display->dpy->fd == -1)
+ return FALSE;
+
+ if (!display->dpy->authenticated)
+ force_roundtrip(display->dpy->display);
+ if (!display->dpy->authenticated)
+ return FALSE;
+
+ version = drmGetVersion(display->dpy->fd);
+ if (!version) {
+ _eglLog(_EGL_WARNING, "invalid fd %d", display->dpy->fd);
+ return FALSE;
+ }
+
+ /* FIXME: share this with native_drm or egl_dri2 */
+ driver_name = get_drm_screen_name(display->dpy->fd, version);
+
+ display->base.screen =
+ wayland_event_handler->new_drm_screen(&display->base,
+ driver_name, display->dpy->fd);
+ drmFreeVersion(version);
+
+ if (!display->base.screen) {
+ _eglLog(_EGL_WARNING, "failed to create DRM screen");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static void
+wayland_set_event_handler(struct native_event_handler *event_handler)
+{
+ wayland_event_handler = event_handler;
+}
+
+static struct pipe_resource *
+wayland_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_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_display_buffer = {
+ wayland_display_import_buffer,
+ wayland_display_export_buffer
+};
+
+static struct native_display *
+wayland_display_create(void *dpy, boolean use_sw, void *user_data)
+{
+ struct wayland_display *display;
+
+ display = CALLOC_STRUCT(wayland_display);
+ if (!display)
+ return NULL;
+
+ display->base.user_data = user_data;
+
+ display->dpy = dpy;
+ if (!display->dpy->display) {
+ wayland_display_destroy(&display->base);
+ return NULL;
+ }
+
+ if (!wayland_display_init_screen(&display->base)) {
+ wayland_display_destroy(&display->base);
+ return NULL;
+ }
+
+ display->base.destroy = wayland_display_destroy;
+ 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.create_window_surface = wayland_create_window_surface;
+ display->base.create_pixmap_surface = wayland_create_pixmap_surface;
+ display->base.buffer = &wayland_display_buffer;
+
+ return &display->base;
+}
+
+static const struct native_platform wayland_platform = {
+ "wayland", /* name */
+ wayland_set_event_handler,
+ wayland_display_create
+};
+
+const struct native_platform *
+native_get_wayland_platform(void)
+{
+ 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
new file mode 100644
index 0000000000..271c10dc11
--- /dev/null
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h
@@ -0,0 +1,97 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.11
+ *
+ * Copyright (C) 2011 Benjamin Franzke <benjaminfranzke@googlemail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _NATIVE_WAYLAND_H_
+#define _NATIVE_WAYLAND_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+
+#include "common/native.h"
+#include "common/native_helper.h"
+
+#include "wayland-egl-priv.h"
+
+struct wayland_display {
+ struct native_display base;
+
+ struct wayland_config *config;
+ struct wl_egl_display *dpy;
+};
+
+enum wayland_buffer_type {
+ WL_BUFFER_FRONT,
+ WL_BUFFER_BACK,
+ WL_BUFFER_COUNT
+};
+
+enum wayland_surface_type {
+ WL_WINDOW_SURFACE,
+ WL_PIXMAP_SURFACE,
+ WL_PBUFFER_SURFACE
+};
+
+struct wayland_surface {
+ struct native_surface base;
+ struct wayland_display *display;
+
+ struct wl_egl_window *win;
+ struct wl_egl_pixmap *pix;
+ enum wayland_surface_type type;
+ int dx, dy;
+ struct resource_surface *rsurf;
+ struct pipe_resource *pending_resource;
+ enum pipe_format color_format;
+
+ unsigned int sequence_number;
+ struct wl_buffer *buffer[WL_BUFFER_COUNT];
+ unsigned int attachment_mask;
+
+ boolean block_swap_buffers;
+};
+
+struct wayland_config {
+ struct native_config base;
+};
+
+static INLINE struct wayland_display *
+wayland_display(const struct native_display *ndpy)
+{
+ return (struct wayland_display *) ndpy;
+}
+
+static INLINE struct wayland_surface *
+wayland_surface(const struct native_surface *nsurf)
+{
+ return (struct wayland_surface *) nsurf;
+}
+
+static INLINE struct wayland_config *
+wayland_config(const struct native_config *nconf)
+{
+ return (struct wayland_config *) nconf;
+}
+
+#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 8108ce4586..5afca67a4d 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -40,11 +40,6 @@
#ifdef GLX_DIRECT_RENDERING
-enum dri2_surface_type {
- DRI2_SURFACE_TYPE_WINDOW,
- DRI2_SURFACE_TYPE_PIXMAP,
-};
-
struct dri2_display {
struct native_display base;
Display *dpy;
@@ -66,7 +61,6 @@ struct dri2_display {
struct dri2_surface {
struct native_surface base;
Drawable drawable;
- enum dri2_surface_type type;
enum pipe_format color_format;
struct dri2_display *dri2dpy;
@@ -439,12 +433,10 @@ dri2_surface_destroy(struct native_surface *nsurf)
static struct dri2_surface *
dri2_display_create_surface(struct native_display *ndpy,
- enum dri2_surface_type type,
Drawable drawable,
- const struct native_config *nconf)
+ enum pipe_format color_format)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
- struct dri2_config *dri2conf = dri2_config(nconf);
struct dri2_surface *dri2surf;
dri2surf = CALLOC_STRUCT(dri2_surface);
@@ -452,9 +444,8 @@ dri2_display_create_surface(struct native_display *ndpy,
return NULL;
dri2surf->dri2dpy = dri2dpy;
- dri2surf->type = type;
dri2surf->drawable = drawable;
- dri2surf->color_format = dri2conf->base.color_format;
+ dri2surf->color_format = color_format;
dri2surf->base.destroy = dri2_surface_destroy;
dri2surf->base.present = dri2_surface_present;
@@ -480,8 +471,8 @@ dri2_display_create_window_surface(struct native_display *ndpy,
{
struct dri2_surface *dri2surf;
- dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_WINDOW,
- (Drawable) win, nconf);
+ dri2surf = dri2_display_create_surface(ndpy,
+ (Drawable) win, nconf->color_format);
return (dri2surf) ? &dri2surf->base : NULL;
}
@@ -492,8 +483,29 @@ dri2_display_create_pixmap_surface(struct native_display *ndpy,
{
struct dri2_surface *dri2surf;
- dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PIXMAP,
- (Drawable) pix, nconf);
+ if (!nconf) {
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+ uint depth, nconf_depth;
+ int i;
+
+ depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
+ for (i = 0; i < dri2dpy->num_configs; i++) {
+ nconf_depth = util_format_get_blocksizebits(
+ dri2dpy->configs[i].base.color_format);
+ /* simple depth match for now */
+ if (depth == nconf_depth ||
+ (depth == 24 && depth + 8 == nconf_depth)) {
+ nconf = &dri2dpy->configs[i].base;
+ break;
+ }
+ }
+
+ if (!nconf)
+ return NULL;
+ }
+
+ dri2surf = dri2_display_create_surface(ndpy,
+ (Drawable) pix, nconf->color_format);
return (dri2surf) ? &dri2surf->base : NULL;
}
@@ -529,7 +541,7 @@ is_format_supported(struct pipe_screen *screen,
{
return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, sample_count,
(is_color) ? PIPE_BIND_RENDER_TARGET :
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
}
static boolean
@@ -548,6 +560,10 @@ dri2_display_convert_config(struct native_display *ndpy,
if (!mode->xRenderable || !mode->drawableType)
return FALSE;
+ /* fast/slow configs are probably not relevant */
+ if (mode->visualRating == GLX_SLOW_CONFIG)
+ return FALSE;
+
nconf->buffer_mask = 1 << NATIVE_ATTACHMENT_FRONT_LEFT;
if (mode->doubleBufferMode)
nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_LEFT;
@@ -568,17 +584,33 @@ dri2_display_convert_config(struct native_display *ndpy,
if (nconf->color_format == PIPE_FORMAT_NONE)
return FALSE;
- if (mode->drawableType & GLX_WINDOW_BIT)
+ if ((mode->drawableType & GLX_WINDOW_BIT) && mode->visualID)
nconf->window_bit = TRUE;
if (mode->drawableType & GLX_PIXMAP_BIT)
nconf->pixmap_bit = TRUE;
nconf->native_visual_id = mode->visualID;
- nconf->native_visual_type = mode->visualType;
+ switch (mode->visualType) {
+ case GLX_TRUE_COLOR:
+ nconf->native_visual_type = TrueColor;
+ break;
+ case GLX_DIRECT_COLOR:
+ nconf->native_visual_type = DirectColor;
+ break;
+ case GLX_PSEUDO_COLOR:
+ nconf->native_visual_type = PseudoColor;
+ break;
+ case GLX_STATIC_COLOR:
+ nconf->native_visual_type = StaticColor;
+ break;
+ case GLX_GRAY_SCALE:
+ nconf->native_visual_type = GrayScale;
+ break;
+ case GLX_STATIC_GRAY:
+ nconf->native_visual_type = StaticGray;
+ break;
+ }
nconf->level = mode->level;
- nconf->samples = mode->samples;
-
- nconf->slow_config = (mode->visualRating == GLX_SLOW_CONFIG);
if (mode->transparentPixel == GLX_TRANSPARENT_RGB) {
nconf->transparent_rgb = TRUE;
@@ -614,8 +646,17 @@ dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
count = 0;
for (i = 0; i < num_modes; i++) {
struct native_config *nconf = &dri2dpy->configs[count].base;
- if (dri2_display_convert_config(&dri2dpy->base, modes, nconf))
- count++;
+
+ if (dri2_display_convert_config(&dri2dpy->base, modes, nconf)) {
+ int j;
+ /* look for duplicates */
+ for (j = 0; j < count; j++) {
+ if (memcmp(&dri2dpy->configs[j], nconf, sizeof(*nconf)) == 0)
+ break;
+ }
+ if (j == count)
+ count++;
+ }
modes = modes->next;
}
@@ -741,7 +782,7 @@ dri2_display_init_screen(struct native_display *ndpy)
dri2dpy->event_handler->new_drm_screen(&dri2dpy->base,
dri2dpy->dri_driver, fd);
if (!dri2dpy->base.screen) {
- _eglLog(_EGL_WARNING, "failed to create DRM screen");
+ _eglLog(_EGL_DEBUG, "failed to create DRM screen");
return FALSE;
}
@@ -758,7 +799,7 @@ dri2_display_hash_table_hash(void *key)
static int
dri2_display_hash_table_compare(void *key1, void *key2)
{
- return (key1 - key2);
+ return ((char *) key1 - (char *) key2);
}
struct native_display *
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index 37c8b01541..a0bcad4c73 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -30,25 +30,30 @@
#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 struct native_display *
-native_create_display(void *dpy, struct native_event_handler *event_handler,
- void *user_data)
+native_create_display(void *dpy, boolean use_sw, void *user_data)
{
struct native_display *ndpy = NULL;
boolean force_sw;
force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
- if (!force_sw) {
- ndpy = x11_create_dri2_display((Display *) dpy,
- event_handler, user_data);
- }
-
- if (!ndpy) {
- EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
- _eglLog(level, "use software fallback");
+ if (force_sw || use_sw) {
+ _eglLog(_EGL_INFO, "use software fallback");
ndpy = x11_create_ximage_display((Display *) dpy,
- event_handler, user_data);
+ x11_event_handler, user_data);
+ }
+ else {
+ ndpy = x11_create_dri2_display((Display *) dpy,
+ x11_event_handler, user_data);
}
return ndpy;
@@ -56,6 +61,7 @@ native_create_display(void *dpy, struct native_event_handler *event_handler,
static const struct native_platform x11_platform = {
"X11", /* name */
+ native_set_event_handler,
native_create_display
};
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 84811fb6e1..8e32c6ff0c 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -38,11 +38,6 @@
#include "native_x11.h"
#include "x11_screen.h"
-enum ximage_surface_type {
- XIMAGE_SURFACE_TYPE_WINDOW,
- XIMAGE_SURFACE_TYPE_PIXMAP,
-};
-
struct ximage_display {
struct native_display base;
Display *dpy;
@@ -60,7 +55,6 @@ struct ximage_display {
struct ximage_surface {
struct native_surface base;
Drawable drawable;
- enum ximage_surface_type type;
enum pipe_format color_format;
XVisualInfo visual;
struct ximage_display *xdpy;
@@ -245,7 +239,6 @@ ximage_surface_destroy(struct native_surface *nsurf)
static struct ximage_surface *
ximage_display_create_surface(struct native_display *ndpy,
- enum ximage_surface_type type,
Drawable drawable,
const struct native_config *nconf)
{
@@ -258,7 +251,6 @@ ximage_display_create_surface(struct native_display *ndpy,
return NULL;
xsurf->xdpy = xdpy;
- xsurf->type = type;
xsurf->color_format = xconf->base.color_format;
xsurf->drawable = drawable;
@@ -297,11 +289,37 @@ ximage_display_create_window_surface(struct native_display *ndpy,
{
struct ximage_surface *xsurf;
- xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_WINDOW,
- (Drawable) win, nconf);
+ xsurf = ximage_display_create_surface(ndpy, (Drawable) win, nconf);
return (xsurf) ? &xsurf->base : NULL;
}
+static enum pipe_format
+get_pixmap_format(struct native_display *ndpy, EGLNativePixmapType pix)
+{
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ enum pipe_format fmt;
+ uint depth;
+
+ depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix);
+
+ switch (depth) {
+ case 32:
+ fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ case 24:
+ fmt = PIPE_FORMAT_B8G8R8X8_UNORM;
+ break;
+ case 16:
+ fmt = PIPE_FORMAT_B5G6R5_UNORM;
+ break;
+ default:
+ fmt = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ return fmt;
+}
+
static struct native_surface *
ximage_display_create_pixmap_surface(struct native_display *ndpy,
EGLNativePixmapType pix,
@@ -309,8 +327,26 @@ ximage_display_create_pixmap_surface(struct native_display *ndpy,
{
struct ximage_surface *xsurf;
- xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PIXMAP,
- (Drawable) pix, nconf);
+ /* find the config */
+ if (!nconf) {
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
+ int i;
+
+ if (fmt != PIPE_FORMAT_NONE) {
+ for (i = 0; i < xdpy->num_configs; i++) {
+ if (xdpy->configs[i].base.color_format == fmt) {
+ nconf = &xdpy->configs[i].base;
+ break;
+ }
+ }
+ }
+
+ if (!nconf)
+ return NULL;
+ }
+
+ xsurf = ximage_display_create_surface(ndpy, (Drawable) pix, nconf);
return (xsurf) ? &xsurf->base : NULL;
}
@@ -384,8 +420,6 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
xconf->base.native_visual_type = xconf->visual->class;
#endif
- xconf->base.slow_config = TRUE;
-
count++;
}
@@ -408,24 +442,7 @@ ximage_display_is_pixmap_supported(struct native_display *ndpy,
const struct native_config *nconf)
{
struct ximage_display *xdpy = ximage_display(ndpy);
- enum pipe_format fmt;
- uint depth;
-
- depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix);
- switch (depth) {
- case 32:
- fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
- break;
- case 24:
- fmt = PIPE_FORMAT_B8G8R8X8_UNORM;
- break;
- case 16:
- fmt = PIPE_FORMAT_B5G6R5_UNORM;
- break;
- default:
- fmt = PIPE_FORMAT_NONE;
- break;
- }
+ enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
return (fmt == nconf->color_format);
}
@@ -459,7 +476,7 @@ ximage_display_destroy(struct native_display *ndpy)
if (xdpy->configs)
FREE(xdpy->configs);
- xdpy->base.screen->destroy(xdpy->base.screen);
+ ndpy_uninit(ndpy);
x11_screen_destroy(xdpy->xscr);
if (xdpy->own_dpy)