mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 01:50:42 -05:00
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:
parent
63461c0f8b
commit
98e5a9c777
@ -47,11 +47,21 @@ typedef enum _CoglFramebufferType {
|
||||
COGL_FRAMEBUFFER_TYPE_OFFSCREEN
|
||||
} CoglFramebufferType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglSwapChain *swap_chain;
|
||||
gboolean need_stencil;
|
||||
} CoglFramebufferConfig;
|
||||
|
||||
struct _CoglFramebuffer
|
||||
{
|
||||
CoglObject _parent;
|
||||
CoglContext *context;
|
||||
CoglFramebufferType type;
|
||||
|
||||
/* The user configuration before allocation... */
|
||||
CoglFramebufferConfig config;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
/* Format of the pixels in the framebuffer (including the expected
|
||||
@ -108,6 +118,7 @@ typedef struct _CoglOffscreen
|
||||
CoglFramebuffer _parent;
|
||||
GLuint fbo_handle;
|
||||
GSList *renderbuffers;
|
||||
|
||||
CoglTexture *texture;
|
||||
} CoglOffscreen;
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "cogl-util.h"
|
||||
#include "cogl-texture-private.h"
|
||||
#include "cogl-framebuffer-private.h"
|
||||
#include "cogl-onscreen-template-private.h"
|
||||
#include "cogl-clip-stack.h"
|
||||
#include "cogl-journal-private.h"
|
||||
#include "cogl-winsys-private.h"
|
||||
@ -957,6 +958,16 @@ _cogl_offscreen_free (CoglOffscreen *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
|
||||
* to represent the CoglOnscreen framebuffer that the backend
|
||||
* creates... */
|
||||
@ -976,6 +987,8 @@ _cogl_onscreen_new (void)
|
||||
/* NB: make sure to pass positive width/height numbers here
|
||||
* because otherwise we'll hit input validation assertions!*/
|
||||
|
||||
_cogl_onscreen_init_from_template (onscreen, ctx->display->onscreen_template);
|
||||
|
||||
COGL_FRAMEBUFFER (onscreen)->allocated = TRUE;
|
||||
|
||||
/* 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 */
|
||||
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;
|
||||
|
||||
return _cogl_onscreen_object_new (onscreen);
|
||||
|
@ -31,7 +31,7 @@ struct _CoglOnscreenTemplate
|
||||
{
|
||||
CoglObject _parent;
|
||||
|
||||
CoglSwapChain *swap_chain;
|
||||
CoglFramebufferConfig config;
|
||||
};
|
||||
|
||||
#endif /* __COGL_ONSCREEN_TEMPLATE_PRIVATE_H */
|
||||
|
@ -31,8 +31,11 @@
|
||||
#include "cogl.h"
|
||||
#include "cogl-object.h"
|
||||
|
||||
#include "cogl-framebuffer-private.h"
|
||||
#include "cogl-onscreen-template-private.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static void _cogl_onscreen_template_free (CoglOnscreenTemplate *onscreen_template);
|
||||
|
||||
COGL_OBJECT_DEFINE (OnscreenTemplate, onscreen_template);
|
||||
@ -53,10 +56,15 @@ CoglOnscreenTemplate *
|
||||
cogl_onscreen_template_new (CoglSwapChain *swap_chain)
|
||||
{
|
||||
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)
|
||||
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);
|
||||
}
|
||||
|
@ -72,6 +72,8 @@
|
||||
#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
|
||||
#endif
|
||||
|
||||
#define MAX_EGL_CONFIG_ATTRIBS 30
|
||||
|
||||
typedef enum _CoglEGLWinsysFeature
|
||||
{
|
||||
COGL_EGL_WINSYS_FEATURE_SWAP_REGION =1L<<0,
|
||||
@ -143,6 +145,7 @@ typedef struct _CoglDisplayEGL
|
||||
|
||||
EGLConfig egl_config;
|
||||
gboolean found_egl_config;
|
||||
gboolean stencil_disabled;
|
||||
} CoglDisplayEGL;
|
||||
|
||||
typedef struct _CoglContextEGL
|
||||
@ -596,10 +599,59 @@ get_visual_info (CoglDisplay *display, EGLConfig egl_config)
|
||||
}
|
||||
#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
|
||||
try_create_context (CoglDisplay *display,
|
||||
int retry_cookie,
|
||||
gboolean *try_fallback,
|
||||
gboolean with_stencil_buffer,
|
||||
GError **error)
|
||||
{
|
||||
CoglDisplayEGL *egl_display = display->winsys;
|
||||
@ -612,38 +664,8 @@ try_create_context (CoglDisplay *display,
|
||||
EGLConfig config;
|
||||
EGLint config_count = 0;
|
||||
EGLBoolean status;
|
||||
EGLint cfg_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 cfg_attribs[MAX_EGL_CONFIG_ATTRIBS];
|
||||
EGLint attribs[3];
|
||||
|
||||
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
||||
XVisualInfo *xvisinfo;
|
||||
XSetWindowAttributes attrs;
|
||||
@ -653,28 +675,18 @@ try_create_context (CoglDisplay *display,
|
||||
#endif
|
||||
const char *error_message;
|
||||
|
||||
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_attributes_from_framebuffer_config (display,
|
||||
&display->onscreen_template->config,
|
||||
with_stencil_buffer,
|
||||
cfg_attribs);
|
||||
|
||||
g_return_val_if_fail (egl_display->egl_context == NULL, TRUE);
|
||||
|
||||
edpy = egl_renderer->edpy;
|
||||
|
||||
if (display->renderer->driver == COGL_DRIVER_GL)
|
||||
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,
|
||||
cfg_attribs,
|
||||
&config, 1,
|
||||
@ -687,6 +699,15 @@ try_create_context (CoglDisplay *display,
|
||||
|
||||
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,
|
||||
config,
|
||||
EGL_NO_CONTEXT,
|
||||
@ -919,21 +940,11 @@ try_create_context (CoglDisplay *display,
|
||||
|
||||
fail:
|
||||
|
||||
/* Currently we only have one fallback path... */
|
||||
if (retry_cookie == 0)
|
||||
{
|
||||
*try_fallback = TRUE;
|
||||
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
|
||||
cleanup_context (CoglDisplay *display)
|
||||
@ -997,35 +1008,25 @@ static gboolean
|
||||
create_context (CoglDisplay *display, GError **error)
|
||||
{
|
||||
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);
|
||||
|
||||
if (display->onscreen_template->swap_chain &&
|
||||
display->onscreen_template->swap_chain->has_alpha)
|
||||
support_transparent_windows = TRUE;
|
||||
/* Note: we don't just rely on eglChooseConfig to correctly
|
||||
* report that the driver doesn't support a stencil buffer
|
||||
* because we've seen PVR drivers that claim stencil buffer
|
||||
* support according to the EGLConfig but then later fail
|
||||
* 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
|
||||
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);
|
||||
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
|
||||
@ -1212,9 +1213,32 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
||||
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
|
||||
struct wl_visual *wayland_visual;
|
||||
#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);
|
||||
|
||||
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
|
||||
|
||||
/* 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);
|
||||
|
||||
xvisinfo = get_visual_info (display, egl_display->egl_config);
|
||||
xvisinfo = get_visual_info (display, egl_config);
|
||||
if (xvisinfo == NULL)
|
||||
{
|
||||
g_set_error (error, COGL_WINSYS_ERROR,
|
||||
@ -1336,7 +1360,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
||||
|
||||
egl_onscreen->egl_surface =
|
||||
eglCreateWindowSurface (egl_renderer->edpy,
|
||||
egl_display->egl_config,
|
||||
egl_config,
|
||||
(NativeWindowType) xlib_onscreen->xwin,
|
||||
NULL);
|
||||
#elif defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
|
||||
@ -1369,7 +1393,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
||||
|
||||
egl_onscreen->egl_surface =
|
||||
eglCreateWindowSurface (egl_renderer->edpy,
|
||||
egl_display->egl_config,
|
||||
egl_config,
|
||||
(EGLNativeWindowType)
|
||||
egl_onscreen->wayland_egl_native_window,
|
||||
NULL);
|
||||
|
@ -44,6 +44,8 @@
|
||||
#include "cogl-texture-2d-private.h"
|
||||
#include "cogl-texture-rectangle-private.h"
|
||||
#include "cogl-pipeline-opengl-private.h"
|
||||
#include "cogl-framebuffer-private.h"
|
||||
#include "cogl-swap-chain-private.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
@ -63,6 +65,7 @@
|
||||
#endif
|
||||
|
||||
#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
|
||||
#define MAX_GLX_CONFIG_ATTRIBS 30
|
||||
|
||||
typedef struct _CoglContextGLX
|
||||
{
|
||||
@ -452,34 +455,60 @@ update_winsys_features (CoglContext *context, GError **error)
|
||||
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
|
||||
* we could overload as an indication of error, so we have to return
|
||||
* an explicit boolean status. */
|
||||
static gboolean
|
||||
find_fbconfig (CoglDisplay *display,
|
||||
gboolean with_alpha,
|
||||
CoglFramebufferConfig *config,
|
||||
GLXFBConfig *config_ret,
|
||||
GError **error)
|
||||
{
|
||||
CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
|
||||
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
|
||||
GLXFBConfig *configs = NULL;
|
||||
int n_configs, i;
|
||||
static const int attributes[] = {
|
||||
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
|
||||
};
|
||||
int n_configs;
|
||||
static int attributes[MAX_GLX_CONFIG_ATTRIBS];
|
||||
gboolean ret = TRUE;
|
||||
int xscreen_num = DefaultScreen (xlib_renderer->xdpy);
|
||||
|
||||
glx_attributes_from_framebuffer_config (display, config, attributes);
|
||||
|
||||
configs = glx_renderer->glXChooseFBConfig (xlib_renderer->xdpy,
|
||||
xscreen_num,
|
||||
attributes,
|
||||
@ -493,8 +522,10 @@ find_fbconfig (CoglDisplay *display,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (with_alpha)
|
||||
if (config->swap_chain->has_alpha)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_configs; i++)
|
||||
{
|
||||
XVisualInfo *vinfo;
|
||||
@ -540,7 +571,8 @@ create_context (CoglDisplay *display, GError **error)
|
||||
CoglXlibDisplay *xlib_display = display->winsys;
|
||||
CoglXlibRenderer *xlib_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;
|
||||
GError *fbconfig_error = NULL;
|
||||
XSetWindowAttributes attrs;
|
||||
@ -550,14 +582,8 @@ create_context (CoglDisplay *display, GError **error)
|
||||
|
||||
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 =
|
||||
find_fbconfig (display, support_transparent_windows, &config,
|
||||
find_fbconfig (display, &display->onscreen_template->config, &config,
|
||||
&fbconfig_error);
|
||||
if (!glx_display->found_fbconfig)
|
||||
{
|
||||
@ -762,9 +788,23 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
||||
Window xwin;
|
||||
CoglOnscreenXlib *xlib_onscreen;
|
||||
CoglOnscreenGLX *glx_onscreen;
|
||||
GLXFBConfig fbconfig;
|
||||
GError *fbconfig_error = NULL;
|
||||
|
||||
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.
|
||||
* For foreign windows we need to be careful not to mess up any
|
||||
* existing event mask.
|
||||
@ -823,7 +863,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
||||
_cogl_xlib_renderer_trap_errors (display->renderer, &state);
|
||||
|
||||
xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy,
|
||||
glx_display->fbconfig);
|
||||
fbconfig);
|
||||
if (xvisinfo == NULL)
|
||||
{
|
||||
g_set_error (error, COGL_WINSYS_ERROR,
|
||||
@ -887,7 +927,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
||||
{
|
||||
glx_onscreen->glxwin =
|
||||
glx_renderer->glXCreateWindow (xlib_renderer->xdpy,
|
||||
glx_display->fbconfig,
|
||||
fbconfig,
|
||||
xlib_onscreen->xwin,
|
||||
NULL);
|
||||
}
|
||||
|
@ -316,7 +316,8 @@ pixel_format_is_better (const PIXELFORMATDESCRIPTOR *pfa,
|
||||
}
|
||||
|
||||
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;
|
||||
PIXELFORMATDESCRIPTOR best_pfd;
|
||||
@ -341,6 +342,11 @@ choose_pixel_format (HDC dc, PIXELFORMATDESCRIPTOR *pfd)
|
||||
already found */
|
||||
(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_pfd = *pfd;
|
||||
}
|
||||
@ -445,7 +451,8 @@ create_context (CoglDisplay *display, GError **error)
|
||||
|
||||
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))
|
||||
{
|
||||
@ -784,9 +791,10 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
||||
wgl_onscreen->client_dc = GetDC (hwnd);
|
||||
|
||||
/* Use the same pixel format as the dummy DC from the renderer */
|
||||
pf = GetPixelFormat (wgl_display->dummy_dc);
|
||||
DescribePixelFormat (wgl_display->dummy_dc, pf, sizeof (pfd), &pfd);
|
||||
if (!SetPixelFormat (wgl_onscreen->client_dc, pf, &pfd))
|
||||
pf = choose_pixel_format (&framebuffer->config,
|
||||
wgl_onscreen->client_dc, &pfd);
|
||||
|
||||
if (pf == 0 || !SetPixelFormat (wgl_onscreen->client_dc, pf, &pfd))
|
||||
{
|
||||
g_set_error (error, COGL_WINSYS_ERROR,
|
||||
COGL_WINSYS_ERROR_CREATE_ONSCREEN,
|
||||
|
Loading…
Reference in New Issue
Block a user