Rework how we search for winsys configs

When creating new onscreen framebuffers we need to take the
configuration in cogl terms and translate that into a configuration
applicable to any given winsys, e.g. an EGLConfig or a GLXFBConfig
or a PIXELFORMATDESCRIPTOR.

Also when we first create a context we typically have to do a very
similar thing because most OpenGL winsys APIs also associate a
framebuffer config with the context and all future configs need to be
compatible with that.

This patch introduces an internal CoglFramebufferConfig to wrap up some
of the configuration parameters that are common to CoglOnscreenTemplate
and to CoglFramebuffer so we aim to re-use code when dealing with the
above two problems.

This patch also aims to rework the winsys code so it can be more
naturally extended as we start adding more configureability to how
onscreen framebuffers are created.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
Robert Bragg 2011-08-22 23:55:57 +01:00
parent 63461c0f8b
commit 98e5a9c777
7 changed files with 229 additions and 122 deletions

View File

@ -47,11 +47,21 @@ typedef enum _CoglFramebufferType {
COGL_FRAMEBUFFER_TYPE_OFFSCREEN COGL_FRAMEBUFFER_TYPE_OFFSCREEN
} CoglFramebufferType; } CoglFramebufferType;
typedef struct
{
CoglSwapChain *swap_chain;
gboolean need_stencil;
} CoglFramebufferConfig;
struct _CoglFramebuffer struct _CoglFramebuffer
{ {
CoglObject _parent; CoglObject _parent;
CoglContext *context; CoglContext *context;
CoglFramebufferType type; CoglFramebufferType type;
/* The user configuration before allocation... */
CoglFramebufferConfig config;
int width; int width;
int height; int height;
/* Format of the pixels in the framebuffer (including the expected /* Format of the pixels in the framebuffer (including the expected
@ -108,7 +118,8 @@ typedef struct _CoglOffscreen
CoglFramebuffer _parent; CoglFramebuffer _parent;
GLuint fbo_handle; GLuint fbo_handle;
GSList *renderbuffers; GSList *renderbuffers;
CoglTexture *texture;
CoglTexture *texture;
} CoglOffscreen; } CoglOffscreen;
/* Flags to pass to _cogl_offscreen_new_to_texture_full */ /* Flags to pass to _cogl_offscreen_new_to_texture_full */

View File

@ -36,6 +36,7 @@
#include "cogl-util.h" #include "cogl-util.h"
#include "cogl-texture-private.h" #include "cogl-texture-private.h"
#include "cogl-framebuffer-private.h" #include "cogl-framebuffer-private.h"
#include "cogl-onscreen-template-private.h"
#include "cogl-clip-stack.h" #include "cogl-clip-stack.h"
#include "cogl-journal-private.h" #include "cogl-journal-private.h"
#include "cogl-winsys-private.h" #include "cogl-winsys-private.h"
@ -957,6 +958,16 @@ _cogl_offscreen_free (CoglOffscreen *offscreen)
g_free (offscreen); g_free (offscreen);
} }
static void
_cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
CoglOnscreenTemplate *onscreen_template)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
framebuffer->config = onscreen_template->config;
cogl_object_ref (framebuffer->config.swap_chain);
}
/* XXX: While we still have backend in Clutter we need a dummy object /* XXX: While we still have backend in Clutter we need a dummy object
* to represent the CoglOnscreen framebuffer that the backend * to represent the CoglOnscreen framebuffer that the backend
* creates... */ * creates... */
@ -976,6 +987,8 @@ _cogl_onscreen_new (void)
/* NB: make sure to pass positive width/height numbers here /* NB: make sure to pass positive width/height numbers here
* because otherwise we'll hit input validation assertions!*/ * because otherwise we'll hit input validation assertions!*/
_cogl_onscreen_init_from_template (onscreen, ctx->display->onscreen_template);
COGL_FRAMEBUFFER (onscreen)->allocated = TRUE; COGL_FRAMEBUFFER (onscreen)->allocated = TRUE;
/* XXX: Note we don't initialize onscreen->winsys in this case. */ /* XXX: Note we don't initialize onscreen->winsys in this case. */
@ -1007,6 +1020,9 @@ cogl_onscreen_new (CoglContext *ctx, int width, int height)
width, /* width */ width, /* width */
height); /* height */ height); /* height */
_cogl_onscreen_init_from_template (onscreen, ctx->display->onscreen_template);
/* FIXME: This should be configurable via the template too */
onscreen->swap_throttled = TRUE; onscreen->swap_throttled = TRUE;
return _cogl_onscreen_object_new (onscreen); return _cogl_onscreen_object_new (onscreen);

View File

@ -31,7 +31,7 @@ struct _CoglOnscreenTemplate
{ {
CoglObject _parent; CoglObject _parent;
CoglSwapChain *swap_chain; CoglFramebufferConfig config;
}; };
#endif /* __COGL_ONSCREEN_TEMPLATE_PRIVATE_H */ #endif /* __COGL_ONSCREEN_TEMPLATE_PRIVATE_H */

View File

@ -31,8 +31,11 @@
#include "cogl.h" #include "cogl.h"
#include "cogl-object.h" #include "cogl-object.h"
#include "cogl-framebuffer-private.h"
#include "cogl-onscreen-template-private.h" #include "cogl-onscreen-template-private.h"
#include <stdlib.h>
static void _cogl_onscreen_template_free (CoglOnscreenTemplate *onscreen_template); static void _cogl_onscreen_template_free (CoglOnscreenTemplate *onscreen_template);
COGL_OBJECT_DEFINE (OnscreenTemplate, onscreen_template); COGL_OBJECT_DEFINE (OnscreenTemplate, onscreen_template);
@ -53,10 +56,15 @@ CoglOnscreenTemplate *
cogl_onscreen_template_new (CoglSwapChain *swap_chain) cogl_onscreen_template_new (CoglSwapChain *swap_chain)
{ {
CoglOnscreenTemplate *onscreen_template = g_slice_new0 (CoglOnscreenTemplate); CoglOnscreenTemplate *onscreen_template = g_slice_new0 (CoglOnscreenTemplate);
char *user_config;
onscreen_template->swap_chain = swap_chain; onscreen_template->config.swap_chain = swap_chain;
if (swap_chain) if (swap_chain)
cogl_object_ref (swap_chain); cogl_object_ref (swap_chain);
else
onscreen_template->config.swap_chain = cogl_swap_chain_new ();
onscreen_template->config.need_stencil = TRUE;
return _cogl_onscreen_template_object_new (onscreen_template); return _cogl_onscreen_template_object_new (onscreen_template);
} }

View File

@ -72,6 +72,8 @@
#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask #define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
#endif #endif
#define MAX_EGL_CONFIG_ATTRIBS 30
typedef enum _CoglEGLWinsysFeature typedef enum _CoglEGLWinsysFeature
{ {
COGL_EGL_WINSYS_FEATURE_SWAP_REGION =1L<<0, COGL_EGL_WINSYS_FEATURE_SWAP_REGION =1L<<0,
@ -143,6 +145,7 @@ typedef struct _CoglDisplayEGL
EGLConfig egl_config; EGLConfig egl_config;
gboolean found_egl_config; gboolean found_egl_config;
gboolean stencil_disabled;
} CoglDisplayEGL; } CoglDisplayEGL;
typedef struct _CoglContextEGL typedef struct _CoglContextEGL
@ -596,10 +599,59 @@ get_visual_info (CoglDisplay *display, EGLConfig egl_config)
} }
#endif #endif
static void
egl_attributes_from_framebuffer_config (CoglDisplay *display,
CoglFramebufferConfig *config,
gboolean needs_stencil_override,
EGLint *attributes)
{
int i = 0;
attributes[i++] = EGL_STENCIL_SIZE;
attributes[i++] = needs_stencil_override ? 2 : 0;
attributes[i++] = EGL_RED_SIZE;
attributes[i++] = 1;
attributes[i++] = EGL_GREEN_SIZE;
attributes[i++] = 1;
attributes[i++] = EGL_BLUE_SIZE;
attributes[i++] = 1;
attributes[i++] = EGL_ALPHA_SIZE;
attributes[i++] = config->swap_chain->has_alpha ? 1 : EGL_DONT_CARE;
attributes[i++] = EGL_DEPTH_SIZE;
attributes[i++] = 1;
/* XXX: Why does the GDL platform choose these by default? */
#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
attributes[i++] = EGL_BIND_TO_TEXTURE_RGBA;
attributes[i++] = EGL_TRUE;
attributes[i++] = EGL_BIND_TO_TEXTURE_RGB;
attributes[i++] = EGL_TRUE;
#endif
attributes[i++] = EGL_BUFFER_SIZE;
attributes[i++] = EGL_DONT_CARE;
attributes[i++] = EGL_RENDERABLE_TYPE;
attributes[i++] = (display->renderer->driver == COGL_DRIVER_GL ?
EGL_OPENGL_BIT :
display->renderer->driver == COGL_DRIVER_GLES1 ?
EGL_OPENGL_ES_BIT :
EGL_OPENGL_ES2_BIT);
attributes[i++] = EGL_SURFACE_TYPE;
attributes[i++] = EGL_WINDOW_BIT;
attributes[i++] = EGL_NONE;
g_assert (i < MAX_EGL_CONFIG_ATTRIBS);
}
static gboolean static gboolean
try_create_context (CoglDisplay *display, try_create_context (CoglDisplay *display,
int retry_cookie, gboolean with_stencil_buffer,
gboolean *try_fallback,
GError **error) GError **error)
{ {
CoglDisplayEGL *egl_display = display->winsys; CoglDisplayEGL *egl_display = display->winsys;
@ -612,38 +664,8 @@ try_create_context (CoglDisplay *display,
EGLConfig config; EGLConfig config;
EGLint config_count = 0; EGLint config_count = 0;
EGLBoolean status; EGLBoolean status;
EGLint cfg_attribs[] = { EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS];
/* NB: This must be the first attribute, since we may
* try and fallback to no stencil buffer */
EGL_STENCIL_SIZE, 2,
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_ALPHA_SIZE, EGL_DONT_CARE,
EGL_DEPTH_SIZE, 1,
/* XXX: Why does the GDL platform choose these by default? */
#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE,
#endif
EGL_BUFFER_SIZE, EGL_DONT_CARE,
EGL_RENDERABLE_TYPE, (display->renderer->driver == COGL_DRIVER_GL ?
EGL_OPENGL_BIT :
display->renderer->driver == COGL_DRIVER_GLES1 ?
EGL_OPENGL_ES_BIT :
EGL_OPENGL_ES2_BIT),
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};
EGLint attribs[3]; EGLint attribs[3];
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
XVisualInfo *xvisinfo; XVisualInfo *xvisinfo;
XSetWindowAttributes attrs; XSetWindowAttributes attrs;
@ -653,28 +675,18 @@ try_create_context (CoglDisplay *display,
#endif #endif
const char *error_message; const char *error_message;
if (display->renderer->driver == COGL_DRIVER_GLES2) egl_attributes_from_framebuffer_config (display,
{ &display->onscreen_template->config,
attribs[0] = EGL_CONTEXT_CLIENT_VERSION; with_stencil_buffer,
attribs[1] = 2; cfg_attribs);
attribs[2] = EGL_NONE;
} g_return_val_if_fail (egl_display->egl_context == NULL, TRUE);
else
attribs[0] = EGL_NONE;
edpy = egl_renderer->edpy; edpy = egl_renderer->edpy;
if (display->renderer->driver == COGL_DRIVER_GL) if (display->renderer->driver == COGL_DRIVER_GL)
eglBindAPI (EGL_OPENGL_API); eglBindAPI (EGL_OPENGL_API);
/* Some GLES hardware can't support a stencil buffer: */
if (retry_cookie == 1)
{
g_warning ("Trying with stencil buffer disabled...");
cfg_attribs[1 /* EGL_STENCIL_SIZE */] = 0;
}
/* XXX: at this point we only have one fallback */
status = eglChooseConfig (edpy, status = eglChooseConfig (edpy,
cfg_attribs, cfg_attribs,
&config, 1, &config, 1,
@ -687,6 +699,15 @@ try_create_context (CoglDisplay *display,
egl_display->egl_config = config; egl_display->egl_config = config;
if (display->renderer->driver == COGL_DRIVER_GLES2)
{
attribs[0] = EGL_CONTEXT_CLIENT_VERSION;
attribs[1] = 2;
attribs[2] = EGL_NONE;
}
else
attribs[0] = EGL_NONE;
egl_display->egl_context = eglCreateContext (edpy, egl_display->egl_context = eglCreateContext (edpy,
config, config,
EGL_NO_CONTEXT, EGL_NO_CONTEXT,
@ -919,20 +940,10 @@ try_create_context (CoglDisplay *display,
fail: fail:
/* Currently we only have one fallback path... */ g_set_error (error, COGL_WINSYS_ERROR,
if (retry_cookie == 0) COGL_WINSYS_ERROR_CREATE_CONTEXT,
{ "%s", error_message);
*try_fallback = TRUE; return FALSE;
return FALSE;
}
else
{
*try_fallback = FALSE;
g_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_CREATE_CONTEXT,
"%s", error_message);
return FALSE;
}
} }
static void static void
@ -997,35 +1008,25 @@ static gboolean
create_context (CoglDisplay *display, GError **error) create_context (CoglDisplay *display, GError **error)
{ {
CoglDisplayEGL *egl_display = display->winsys; CoglDisplayEGL *egl_display = display->winsys;
gboolean support_transparent_windows;
int retry_cookie = 0;
gboolean status;
gboolean try_fallback;
GError *try_error = NULL;
g_return_val_if_fail (egl_display->egl_context == NULL, TRUE); /* Note: we don't just rely on eglChooseConfig to correctly
* report that the driver doesn't support a stencil buffer
if (display->onscreen_template->swap_chain && * because we've seen PVR drivers that claim stencil buffer
display->onscreen_template->swap_chain->has_alpha) * support according to the EGLConfig but then later fail
support_transparent_windows = TRUE; * when trying to create a context with such a config.
*/
if (try_create_context (display, TRUE, error))
{
egl_display->stencil_disabled = FALSE;
return TRUE;
}
else else
support_transparent_windows = FALSE;
retry_cookie = 0;
while (!(status = try_create_context (display,
retry_cookie,
&try_fallback,
&try_error)) &&
try_fallback)
{ {
g_clear_error (error); g_clear_error (error);
cleanup_context (display); cleanup_context (display);
retry_cookie++; egl_display->stencil_disabled = TRUE;
return try_create_context (display, FALSE, error);
} }
if (!status)
g_propagate_error (error, try_error);
return status;
} }
static void static void
@ -1212,9 +1213,32 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT #ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
struct wl_visual *wayland_visual; struct wl_visual *wayland_visual;
#endif #endif
EGLint attributes[MAX_EGL_CONFIG_ATTRIBS];
EGLConfig egl_config;
EGLint config_count = 0;
EGLBoolean status;
gboolean need_stencil =
egl_display->stencil_disabled ? FALSE : framebuffer->config.need_stencil;
g_return_val_if_fail (egl_display->egl_context, FALSE); g_return_val_if_fail (egl_display->egl_context, FALSE);
egl_attributes_from_framebuffer_config (display,
&framebuffer->config,
need_stencil,
attributes);
status = eglChooseConfig (egl_renderer->edpy,
attributes,
&egl_config, 1,
&config_count);
if (status != EGL_TRUE || config_count == 0)
{
g_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_CREATE_ONSCREEN,
"Failed to find a suitable EGL configuration");
return FALSE;
}
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
/* FIXME: We need to explicitly Select for ConfigureNotify events. /* FIXME: We need to explicitly Select for ConfigureNotify events.
@ -1274,7 +1298,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
_cogl_xlib_renderer_trap_errors (display->renderer, &state); _cogl_xlib_renderer_trap_errors (display->renderer, &state);
xvisinfo = get_visual_info (display, egl_display->egl_config); xvisinfo = get_visual_info (display, egl_config);
if (xvisinfo == NULL) if (xvisinfo == NULL)
{ {
g_set_error (error, COGL_WINSYS_ERROR, g_set_error (error, COGL_WINSYS_ERROR,
@ -1336,7 +1360,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
egl_onscreen->egl_surface = egl_onscreen->egl_surface =
eglCreateWindowSurface (egl_renderer->edpy, eglCreateWindowSurface (egl_renderer->edpy,
egl_display->egl_config, egl_config,
(NativeWindowType) xlib_onscreen->xwin, (NativeWindowType) xlib_onscreen->xwin,
NULL); NULL);
#elif defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT) #elif defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
@ -1369,7 +1393,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
egl_onscreen->egl_surface = egl_onscreen->egl_surface =
eglCreateWindowSurface (egl_renderer->edpy, eglCreateWindowSurface (egl_renderer->edpy,
egl_display->egl_config, egl_config,
(EGLNativeWindowType) (EGLNativeWindowType)
egl_onscreen->wayland_egl_native_window, egl_onscreen->wayland_egl_native_window,
NULL); NULL);

View File

@ -44,6 +44,8 @@
#include "cogl-texture-2d-private.h" #include "cogl-texture-2d-private.h"
#include "cogl-texture-rectangle-private.h" #include "cogl-texture-rectangle-private.h"
#include "cogl-pipeline-opengl-private.h" #include "cogl-pipeline-opengl-private.h"
#include "cogl-framebuffer-private.h"
#include "cogl-swap-chain-private.h"
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
@ -63,6 +65,7 @@
#endif #endif
#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask #define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
#define MAX_GLX_CONFIG_ATTRIBS 30
typedef struct _CoglContextGLX typedef struct _CoglContextGLX
{ {
@ -452,34 +455,60 @@ update_winsys_features (CoglContext *context, GError **error)
return TRUE; return TRUE;
} }
static void
glx_attributes_from_framebuffer_config (CoglDisplay *display,
CoglFramebufferConfig *config,
int *attributes)
{
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
int i = 0;
attributes[i++] = GLX_DRAWABLE_TYPE;
attributes[i++] = GLX_WINDOW_BIT;
attributes[i++] = GLX_RENDER_TYPE;
attributes[i++] = GLX_RGBA_BIT;
attributes[i++] = GLX_DOUBLEBUFFER;
attributes[i++] = GL_TRUE;
attributes[i++] = GLX_RED_SIZE;
attributes[i++] = 1;
attributes[i++] = GLX_GREEN_SIZE;
attributes[i++] = 1;
attributes[i++] = GLX_BLUE_SIZE;
attributes[i++] = 1;
attributes[i++] = GLX_ALPHA_SIZE;
attributes[i++] = config->swap_chain->has_alpha ? 1 : GLX_DONT_CARE;
attributes[i++] = GLX_DEPTH_SIZE;
attributes[i++] = 1;
attributes[i++] = GLX_STENCIL_SIZE;
attributes[i++] = config->need_stencil ? 1: GLX_DONT_CARE;
attributes[i++] = None;
g_assert (i < MAX_GLX_CONFIG_ATTRIBS);
}
/* It seems the GLX spec never defined an invalid GLXFBConfig that /* It seems the GLX spec never defined an invalid GLXFBConfig that
* we could overload as an indication of error, so we have to return * we could overload as an indication of error, so we have to return
* an explicit boolean status. */ * an explicit boolean status. */
static gboolean static gboolean
find_fbconfig (CoglDisplay *display, find_fbconfig (CoglDisplay *display,
gboolean with_alpha, CoglFramebufferConfig *config,
GLXFBConfig *config_ret, GLXFBConfig *config_ret,
GError **error) GError **error)
{ {
CoglXlibRenderer *xlib_renderer = display->renderer->winsys; CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
CoglGLXRenderer *glx_renderer = display->renderer->winsys; CoglGLXRenderer *glx_renderer = display->renderer->winsys;
GLXFBConfig *configs = NULL; GLXFBConfig *configs = NULL;
int n_configs, i; int n_configs;
static const int attributes[] = { static int attributes[MAX_GLX_CONFIG_ATTRIBS];
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DOUBLEBUFFER, GL_TRUE,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
None
};
gboolean ret = TRUE; gboolean ret = TRUE;
int xscreen_num = DefaultScreen (xlib_renderer->xdpy); int xscreen_num = DefaultScreen (xlib_renderer->xdpy);
glx_attributes_from_framebuffer_config (display, config, attributes);
configs = glx_renderer->glXChooseFBConfig (xlib_renderer->xdpy, configs = glx_renderer->glXChooseFBConfig (xlib_renderer->xdpy,
xscreen_num, xscreen_num,
attributes, attributes,
@ -493,8 +522,10 @@ find_fbconfig (CoglDisplay *display,
goto done; goto done;
} }
if (with_alpha) if (config->swap_chain->has_alpha)
{ {
int i;
for (i = 0; i < n_configs; i++) for (i = 0; i < n_configs; i++)
{ {
XVisualInfo *vinfo; XVisualInfo *vinfo;
@ -540,7 +571,8 @@ create_context (CoglDisplay *display, GError **error)
CoglXlibDisplay *xlib_display = display->winsys; CoglXlibDisplay *xlib_display = display->winsys;
CoglXlibRenderer *xlib_renderer = display->renderer->winsys; CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
CoglGLXRenderer *glx_renderer = display->renderer->winsys; CoglGLXRenderer *glx_renderer = display->renderer->winsys;
gboolean support_transparent_windows; gboolean support_transparent_windows =
display->onscreen_template->config.swap_chain->has_alpha;
GLXFBConfig config; GLXFBConfig config;
GError *fbconfig_error = NULL; GError *fbconfig_error = NULL;
XSetWindowAttributes attrs; XSetWindowAttributes attrs;
@ -550,14 +582,8 @@ create_context (CoglDisplay *display, GError **error)
g_return_val_if_fail (glx_display->glx_context == NULL, TRUE); g_return_val_if_fail (glx_display->glx_context == NULL, TRUE);
if (display->onscreen_template->swap_chain &&
display->onscreen_template->swap_chain->has_alpha)
support_transparent_windows = TRUE;
else
support_transparent_windows = FALSE;
glx_display->found_fbconfig = glx_display->found_fbconfig =
find_fbconfig (display, support_transparent_windows, &config, find_fbconfig (display, &display->onscreen_template->config, &config,
&fbconfig_error); &fbconfig_error);
if (!glx_display->found_fbconfig) if (!glx_display->found_fbconfig)
{ {
@ -762,9 +788,23 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
Window xwin; Window xwin;
CoglOnscreenXlib *xlib_onscreen; CoglOnscreenXlib *xlib_onscreen;
CoglOnscreenGLX *glx_onscreen; CoglOnscreenGLX *glx_onscreen;
GLXFBConfig fbconfig;
GError *fbconfig_error = NULL;
g_return_val_if_fail (glx_display->glx_context, FALSE); g_return_val_if_fail (glx_display->glx_context, FALSE);
if (!find_fbconfig (display, &framebuffer->config,
&fbconfig,
&fbconfig_error))
{
g_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_CREATE_CONTEXT,
"Unable to find suitable fbconfig for the GLX context: %s",
fbconfig_error->message);
g_error_free (fbconfig_error);
return FALSE;
}
/* FIXME: We need to explicitly Select for ConfigureNotify events. /* FIXME: We need to explicitly Select for ConfigureNotify events.
* For foreign windows we need to be careful not to mess up any * For foreign windows we need to be careful not to mess up any
* existing event mask. * existing event mask.
@ -823,7 +863,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
_cogl_xlib_renderer_trap_errors (display->renderer, &state); _cogl_xlib_renderer_trap_errors (display->renderer, &state);
xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy, xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy,
glx_display->fbconfig); fbconfig);
if (xvisinfo == NULL) if (xvisinfo == NULL)
{ {
g_set_error (error, COGL_WINSYS_ERROR, g_set_error (error, COGL_WINSYS_ERROR,
@ -887,7 +927,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
{ {
glx_onscreen->glxwin = glx_onscreen->glxwin =
glx_renderer->glXCreateWindow (xlib_renderer->xdpy, glx_renderer->glXCreateWindow (xlib_renderer->xdpy,
glx_display->fbconfig, fbconfig,
xlib_onscreen->xwin, xlib_onscreen->xwin,
NULL); NULL);
} }

View File

@ -316,7 +316,8 @@ pixel_format_is_better (const PIXELFORMATDESCRIPTOR *pfa,
} }
static int static int
choose_pixel_format (HDC dc, PIXELFORMATDESCRIPTOR *pfd) choose_pixel_format (CoglFramebufferConfig *config,
HDC dc, PIXELFORMATDESCRIPTOR *pfd)
{ {
int i, num_formats, best_pf = 0; int i, num_formats, best_pf = 0;
PIXELFORMATDESCRIPTOR best_pfd; PIXELFORMATDESCRIPTOR best_pfd;
@ -341,6 +342,11 @@ choose_pixel_format (HDC dc, PIXELFORMATDESCRIPTOR *pfd)
already found */ already found */
(best_pf == 0 || pixel_format_is_better (&best_pfd, pfd))) (best_pf == 0 || pixel_format_is_better (&best_pfd, pfd)))
{ {
if (config->swap_chain->has_alpha && pfd->cAlphaBits == 0)
continue;
if (config->need_stencil && pfd->cStencilBits == 0)
continue;
best_pf = i; best_pf = i;
best_pfd = *pfd; best_pfd = *pfd;
} }
@ -445,7 +451,8 @@ create_context (CoglDisplay *display, GError **error)
wgl_display->dummy_dc = GetDC (wgl_display->dummy_hwnd); wgl_display->dummy_dc = GetDC (wgl_display->dummy_hwnd);
pf = choose_pixel_format (wgl_display->dummy_dc, &pfd); pf = choose_pixel_format (&display->onscreen_template->config,
wgl_display->dummy_dc, &pfd);
if (pf == 0 || !SetPixelFormat (wgl_display->dummy_dc, pf, &pfd)) if (pf == 0 || !SetPixelFormat (wgl_display->dummy_dc, pf, &pfd))
{ {
@ -784,9 +791,10 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
wgl_onscreen->client_dc = GetDC (hwnd); wgl_onscreen->client_dc = GetDC (hwnd);
/* Use the same pixel format as the dummy DC from the renderer */ /* Use the same pixel format as the dummy DC from the renderer */
pf = GetPixelFormat (wgl_display->dummy_dc); pf = choose_pixel_format (&framebuffer->config,
DescribePixelFormat (wgl_display->dummy_dc, pf, sizeof (pfd), &pfd); wgl_onscreen->client_dc, &pfd);
if (!SetPixelFormat (wgl_onscreen->client_dc, pf, &pfd))
if (pf == 0 || !SetPixelFormat (wgl_onscreen->client_dc, pf, &pfd))
{ {
g_set_error (error, COGL_WINSYS_ERROR, g_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_CREATE_ONSCREEN, COGL_WINSYS_ERROR_CREATE_ONSCREEN,