1
0
Fork 0

Moves all GLX code down from Clutter to Cogl

This migrates all the GLX window system code down from the Clutter
backend code into a Cogl winsys. Moving OpenGL window system binding
code down from Clutter into Cogl is the biggest blocker to having Cogl
become a standalone 3D graphics library, so this is an important step in
that direction.
This commit is contained in:
Robert Bragg 2010-11-05 12:28:33 +00:00
parent bcd97f35ea
commit d40cdfa3e1
44 changed files with 3232 additions and 710 deletions

View file

@ -78,6 +78,7 @@ cogl_public_h = \
$(srcdir)/cogl-attribute.h \ $(srcdir)/cogl-attribute.h \
$(srcdir)/cogl-primitive.h \ $(srcdir)/cogl-primitive.h \
$(srcdir)/cogl-clip-state.h \ $(srcdir)/cogl-clip-state.h \
$(srcdir)/cogl-framebuffer.h \
$(srcdir)/cogl-clutter.h \ $(srcdir)/cogl-clutter.h \
$(srcdir)/cogl.h \ $(srcdir)/cogl.h \
$(NULL) $(NULL)
@ -115,9 +116,7 @@ endif # COGL_DRIVER_GLES
# winsys sources, common to all backends # winsys sources, common to all backends
cogl_winsys_common_sources = \ cogl_winsys_common_sources = \
$(srcdir)/winsys/cogl-winsys-private.h \ $(srcdir)/winsys/cogl-winsys-private.h \
$(srcdir)/winsys/cogl-context-winsys.h \ $(srcdir)/winsys/cogl-winsys.c \
$(srcdir)/winsys/cogl-context-winsys.c \
$(srcdir)/winsys/cogl-winsys-feature-functions.h \
$(NULL) $(NULL)
# tesselator sources # tesselator sources
@ -295,29 +294,39 @@ cogl_sources_c = \
if SUPPORT_XLIB if SUPPORT_XLIB
cogl_experimental_h += \ cogl_experimental_h += \
$(srcdir)/winsys/cogl-texture-pixmap-x11.h $(srcdir)/winsys/cogl-texture-pixmap-x11.h \
$(srcdir)/cogl-xlib.h
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-xlib.h \ $(srcdir)/cogl-renderer-x11-private.h \
$(srcdir)/winsys/cogl-winsys-xlib.c \ $(srcdir)/cogl-renderer-xlib-private.h \
$(srcdir)/cogl-renderer-xlib.c \
$(srcdir)/cogl-display-xlib-private.h \
$(srcdir)/cogl-xlib.c \
$(srcdir)/winsys/cogl-texture-pixmap-x11.c \ $(srcdir)/winsys/cogl-texture-pixmap-x11.c \
$(srcdir)/winsys/cogl-texture-pixmap-x11-private.h $(srcdir)/winsys/cogl-texture-pixmap-x11-private.h
endif endif
if SUPPORT_GLX if SUPPORT_GLX
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/cogl-renderer-glx-private.h \
$(srcdir)/cogl-display-glx-private.h \
$(srcdir)/winsys/cogl-winsys-glx-feature-functions.h \
$(srcdir)/winsys/cogl-winsys-glx.c $(srcdir)/winsys/cogl-winsys-glx.c
endif endif
if SUPPORT_EGL_PLATFORM_POWERVR_X11 if SUPPORT_EGL_PLATFORM_POWERVR_X11
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c $(srcdir)/winsys/cogl-winsys-egl.c \
$(srcdir)/winsys/cogl-winsys-stub.c
endif endif
if SUPPORT_EGL_PLATFORM_POWERVR_NULL if SUPPORT_EGL_PLATFORM_POWERVR_NULL
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c $(srcdir)/winsys/cogl-winsys-egl.c \
$(srcdir)/winsys/cogl-winsys-stub.c
endif endif
if SUPPORT_EGL_PLATFORM_POWERVR_GDL if SUPPORT_EGL_PLATFORM_POWERVR_GDL
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c $(srcdir)/winsys/cogl-winsys-egl.c \
$(srcdir)/winsys/cogl-winsys-stub.c
endif endif
if SUPPORT_EGL_PLATFORM_FRUITY if SUPPORT_EGL_PLATFORM_FRUITY
cogl_sources_c += \ cogl_sources_c += \
@ -325,15 +334,18 @@ cogl_sources_c += \
endif endif
if SUPPORT_EGL_PLATFORM_DRM_SURFACELESS if SUPPORT_EGL_PLATFORM_DRM_SURFACELESS
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c $(srcdir)/winsys/cogl-winsys-egl.c \
$(srcdir)/winsys/cogl-winsys-stub.c
endif endif
if SUPPORT_WIN32 if SUPPORT_WIN32
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-win32.c $(srcdir)/winsys/cogl-winsys-win32.c \
$(srcdir)/winsys/cogl-winsys-stub.c
endif endif
if SUPPORT_OSX if SUPPORT_OSX
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-osx.c $(srcdir)/winsys/cogl-winsys-osx.c \
$(srcdir)/winsys/cogl-winsys-stub.c
endif endif
EXTRA_DIST += stb_image.c EXTRA_DIST += stb_image.c

View file

@ -43,6 +43,12 @@ cogl_clutter_check_extension (const char *name, const char *ext)
return _cogl_check_extension (name, ext); return _cogl_check_extension (name, ext);
} }
gboolean
cogl_clutter_winsys_has_feature (CoglWinsysFeature feature)
{
return _cogl_winsys_has_feature (feature);
}
void void
cogl_onscreen_clutter_backend_set_size (int width, int height) cogl_onscreen_clutter_backend_set_size (int width, int height)
{ {
@ -57,3 +63,11 @@ cogl_onscreen_clutter_backend_set_size (int width, int height)
_cogl_framebuffer_winsys_update_size (framebuffer, width, height); _cogl_framebuffer_winsys_update_size (framebuffer, width, height);
} }
#ifdef COGL_HAS_XLIB_SUPPORT
XVisualInfo *
cogl_clutter_winsys_xlib_get_visual_info (void)
{
return _cogl_winsys_xlib_get_visual_info ();
}
#endif

View file

@ -38,10 +38,20 @@ G_BEGIN_DECLS
gboolean gboolean
cogl_clutter_check_extension (const char *name, const char *ext); cogl_clutter_check_extension (const char *name, const char *ext);
#define cogl_clutter_winsys_has_feature cogl_clutter_winsys_has_feature_CLUTTER
gboolean
cogl_clutter_winsys_has_feature (CoglWinsysFeature feature);
#define cogl_onscreen_clutter_backend_set_size cogl_onscreen_clutter_backend_set_size_CLUTTER #define cogl_onscreen_clutter_backend_set_size cogl_onscreen_clutter_backend_set_size_CLUTTER
void void
cogl_onscreen_clutter_backend_set_size (int width, int height); cogl_onscreen_clutter_backend_set_size (int width, int height);
#ifdef COGL_HAS_XLIB
#define cogl_clutter_winsys_xlib_get_visual_info cogl_clutter_winsys_xlib_get_visual_info_CLUTTER
XVisualInfo *
cogl_clutter_winsys_xlib_get_visual_info (void);
#endif
G_END_DECLS G_END_DECLS
#endif /* __COGL_CLUTTER_H__ */ #endif /* __COGL_CLUTTER_H__ */

View file

@ -26,6 +26,11 @@
#include "cogl-internal.h" #include "cogl-internal.h"
#include "cogl-context.h" #include "cogl-context.h"
#include "cogl-winsys-private.h"
#ifdef COGL_HAS_XLIB_SUPPORT
#include "cogl-xlib-private.h"
#endif
#if HAVE_COGL_GL #if HAVE_COGL_GL
#include "cogl-context-driver-gl.h" #include "cogl-context-driver-gl.h"
@ -35,7 +40,7 @@
#include "cogl-context-driver-gles.h" #include "cogl-context-driver-gles.h"
#endif #endif
#include "cogl-context-winsys.h" #include "cogl-display-private.h"
#include "cogl-primitives.h" #include "cogl-primitives.h"
#include "cogl-clip-stack.h" #include "cogl-clip-stack.h"
#include "cogl-matrix-stack.h" #include "cogl-matrix-stack.h"
@ -55,9 +60,10 @@ struct _CoglContext
{ {
CoglObject _parent; CoglObject _parent;
CoglDisplay *display;
/* Features cache */ /* Features cache */
CoglFeatureFlags feature_flags; CoglFeatureFlags feature_flags;
CoglFeatureFlagsPrivate feature_flags_private;
CoglHandle default_pipeline; CoglHandle default_pipeline;
CoglHandle default_layer_0; CoglHandle default_layer_0;
@ -70,8 +76,6 @@ struct _CoglContext
gboolean enable_backface_culling; gboolean enable_backface_culling;
CoglFrontWinding flushed_front_winding; CoglFrontWinding flushed_front_winding;
gboolean indirect;
/* A few handy matrix constants */ /* A few handy matrix constants */
CoglMatrix identity_matrix; CoglMatrix identity_matrix;
CoglMatrix y_flip_matrix; CoglMatrix y_flip_matrix;
@ -237,8 +241,26 @@ struct _CoglContext
GByteArray *buffer_map_fallback_array; GByteArray *buffer_map_fallback_array;
gboolean buffer_map_fallback_in_use; gboolean buffer_map_fallback_in_use;
CoglWinsysRectangleState rectangle_state;
/* FIXME: remove these when we remove the last xlib based clutter
* backend. they should be tracked as part of the renderer but e.g.
* the eglx backend doesn't yet have a corresponding Cogl winsys
* and so we wont have a renderer in that case. */
#ifdef COGL_HAS_XLIB_SUPPORT
int damage_base;
/* List of callback functions that will be given every Xlib event */
GSList *event_filters;
/* Current top of the XError trap state stack. The actual memory for
these is expected to be allocated on the stack by the caller */
CoglXlibTrapState *trap_state;
#endif
CoglContextDriver drv; CoglContextDriver drv;
CoglContextWinsys winsys;
CoglBitmask winsys_features;
void *winsys;
gboolean stub_winsys;
}; };
CoglContext * CoglContext *

View file

@ -28,6 +28,8 @@
#include "cogl.h" #include "cogl.h"
#include "cogl-object.h" #include "cogl-object.h"
#include "cogl-internal.h" #include "cogl-internal.h"
#include "cogl-private.h"
#include "cogl-winsys-private.h"
#include "cogl-profile.h" #include "cogl-profile.h"
#include "cogl-util.h" #include "cogl-util.h"
#include "cogl-context-private.h" #include "cogl-context-private.h"
@ -56,13 +58,8 @@ COGL_OBJECT_DEFINE (Context, context);
extern void extern void
_cogl_create_context_driver (CoglContext *context); _cogl_create_context_driver (CoglContext *context);
extern void
_cogl_create_context_winsys (CoglContext *context);
extern void
_cogl_destroy_context_winsys (CoglContext *context);
static CoglContext *_context = NULL; static CoglContext *_context = NULL;
static gboolean gl_is_indirect = FALSE;
static void static void
_cogl_init_feature_overrides (CoglContext *ctx) _cogl_init_feature_overrides (CoglContext *ctx)
@ -102,15 +99,8 @@ cogl_context_new (CoglDisplay *display,
CoglContext *context; CoglContext *context;
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 }; GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
unsigned long enable_flags = 0; unsigned long enable_flags = 0;
CoglHandle window_buffer;
int i; int i;
/* A NULL display means "please just do something sensible"
* and since we haven't implemented anything for CoglDisplay
* yet that's the only kind of context construction we allow
* for now. */
g_return_val_if_fail (display == NULL, NULL);
#ifdef CLUTTER_ENABLE_PROFILE #ifdef CLUTTER_ENABLE_PROFILE
/* We need to be absolutely sure that uprof has been initialized /* We need to be absolutely sure that uprof has been initialized
* before calling _cogl_uprof_init. uprof_init (NULL, NULL) * before calling _cogl_uprof_init. uprof_init (NULL, NULL)
@ -135,17 +125,20 @@ cogl_context_new (CoglDisplay *display,
* context which it can access via _COGL_GET_CONTEXT() including * context which it can access via _COGL_GET_CONTEXT() including
* code used to construct a CoglContext. Until all of that code * code used to construct a CoglContext. Until all of that code
* has been updated to take an explicit context argument we have * has been updated to take an explicit context argument we have
* to immediatly make our pointer the default context. * to immediately make our pointer the default context.
*/ */
_context = context; _context = context;
/* Init default values */ /* Init default values */
_context->feature_flags = 0; context->feature_flags = 0;
_context->feature_flags_private = 0;
context->texture_types = NULL; context->texture_types = NULL;
context->buffer_types = NULL; context->buffer_types = NULL;
context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_UNKNOWN;
_cogl_bitmask_init (&context->winsys_features);
if (!display) if (!display)
display = cogl_display_new (NULL, NULL); display = cogl_display_new (NULL, NULL);
else else
@ -158,11 +151,32 @@ cogl_context_new (CoglDisplay *display,
return NULL; return NULL;
} }
/* Initialise the driver specific state */ context->display = display;
_cogl_gl_context_init (context);
_cogl_init_feature_overrides (context);
_cogl_create_context_winsys (context); #ifdef COGL_HAS_FULL_WINSYS
if (!_cogl_winsys_context_init (context, error))
{
cogl_object_unref (display);
g_free (context);
return NULL;
}
#else
/* In this case Clutter is still responsible for creating a GL
* context. */
context->stub_winsys = TRUE;
if (!_cogl_gl_check_version (error))
{
g_free (context);
return NULL;
}
_cogl_gl_update_features (context);
#ifdef COGL_HAS_XLIB_SUPPORT
_cogl_xlib_query_damage_extension ();
#endif
#endif
/* Initialise the driver specific state */
_cogl_init_feature_overrides (context);
_cogl_pipeline_init_default_pipeline (); _cogl_pipeline_init_default_pipeline ();
_cogl_pipeline_init_default_layers (); _cogl_pipeline_init_default_layers ();
@ -174,8 +188,6 @@ cogl_context_new (CoglDisplay *display,
context->enable_backface_culling = FALSE; context->enable_backface_culling = FALSE;
context->flushed_front_winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE; context->flushed_front_winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE;
context->indirect = gl_is_indirect;
cogl_matrix_init_identity (&context->identity_matrix); cogl_matrix_init_identity (&context->identity_matrix);
cogl_matrix_init_identity (&context->y_flip_matrix); cogl_matrix_init_identity (&context->y_flip_matrix);
cogl_matrix_scale (&context->y_flip_matrix, 1, -1, 1); cogl_matrix_scale (&context->y_flip_matrix, 1, -1, 1);
@ -257,13 +269,18 @@ cogl_context_new (CoglDisplay *display,
context->framebuffer_stack = _cogl_create_framebuffer_stack (); context->framebuffer_stack = _cogl_create_framebuffer_stack ();
_context->current_clip_stack_valid = FALSE; /* XXX: In this case the Clutter backend is still responsible for
* the OpenGL binding API and for creating onscreen framebuffers and
* so we have to add a dummy framebuffer to represent the backend
* owned window... */
if (context->stub_winsys)
{
CoglOnscreen *window = _cogl_onscreen_new ();
cogl_set_framebuffer (COGL_FRAMEBUFFER (window));
cogl_object_unref (COGL_FRAMEBUFFER (window));
}
window_buffer = _cogl_onscreen_new (); _context->current_clip_stack_valid = FALSE;
cogl_set_framebuffer (window_buffer);
/* XXX: the deprecated _cogl_set_draw_buffer API expects to
* find the window buffer here... */
context->window_buffer = window_buffer;
context->dirty_bound_framebuffer = TRUE; context->dirty_bound_framebuffer = TRUE;
context->dirty_gl_viewport = TRUE; context->dirty_gl_viewport = TRUE;
@ -347,7 +364,7 @@ cogl_context_new (CoglDisplay *display,
static void static void
_cogl_context_free (CoglContext *context) _cogl_context_free (CoglContext *context)
{ {
_cogl_destroy_context_winsys (context); _cogl_winsys_context_deinit (context);
_cogl_destroy_texture_units (); _cogl_destroy_texture_units ();
@ -424,6 +441,8 @@ _cogl_context_free (CoglContext *context)
g_byte_array_free (context->buffer_map_fallback_array, TRUE); g_byte_array_free (context->buffer_map_fallback_array, TRUE);
_cogl_bitmask_destroy (&context->winsys_features);
cogl_object_unref (context->display); cogl_object_unref (context->display);
g_free (context); g_free (context);
@ -448,31 +467,12 @@ _cogl_context_get_default (void)
return _context; return _context;
} }
/**
* _cogl_set_indirect_context:
* @indirect: TRUE if GL context is indirect
*
* Advises COGL that the GL context is indirect (commands are sent
* over a socket). COGL uses this information to try to avoid
* round-trips in its use of GL, for example.
*
* This function cannot be called "on the fly," only before COGL
* initializes.
*/
void void
_cogl_set_indirect_context (gboolean indirect) cogl_set_default_context (CoglContext *context)
{ {
/* we get called multiple times if someone creates cogl_object_ref (context);
* more than the default stage
*/
if (_context != NULL)
{
if (indirect != _context->indirect)
g_warning ("Right now all stages will be treated as "
"either direct or indirect, ignoring attempt "
"to change to indirect=%d", indirect);
return;
}
gl_is_indirect = indirect; if (_context)
cogl_object_unref (_context);
_context = context;
} }

View file

@ -54,7 +54,12 @@ typedef struct _CoglContext CoglContext;
#define cogl_context_new cogl_context_new_EXP #define cogl_context_new cogl_context_new_EXP
CoglContext * CoglContext *
cogl_context_new (CoglDisplay *display); cogl_context_new (CoglDisplay *display,
GError **error);
#define cogl_set_default_context cogl_set_default_context_EXP
void
cogl_set_default_context (CoglContext *context);
G_END_DECLS G_END_DECLS

View file

@ -63,6 +63,7 @@ typedef enum {
COGL_DEBUG_DISABLE_PROGRAM_CACHES, COGL_DEBUG_DISABLE_PROGRAM_CACHES,
COGL_DEBUG_DISABLE_FAST_READ_PIXEL, COGL_DEBUG_DISABLE_FAST_READ_PIXEL,
COGL_DEBUG_CLIPPING, COGL_DEBUG_CLIPPING,
COGL_DEBUG_WINSYS,
COGL_DEBUG_N_FLAGS COGL_DEBUG_N_FLAGS
} CoglDebugFlags; } CoglDebugFlags;

View file

@ -0,0 +1,57 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_DISPLAY_GLX_PRIVATE_H
#define __COGL_DISPLAY_GLX_PRIVATE_H
#include "cogl-object-private.h"
#include "cogl-display-xlib-private.h"
typedef struct _CoglGLXCachedConfig
{
/* This will be -1 if there is no cached config in this slot */
int depth;
gboolean found;
GLXFBConfig fb_config;
gboolean can_mipmap;
} CoglGLXCachedConfig;
#define COGL_GLX_N_CACHED_CONFIGS 3
typedef struct _CoglDisplayGLX
{
CoglDisplayXlib _parent;
CoglGLXCachedConfig glx_cached_configs[COGL_GLX_N_CACHED_CONFIGS];
gboolean found_fbconfig;
gboolean fbconfig_has_rgba_visual;
GLXFBConfig fbconfig;
/* Single context for all wins */
GLXContext glx_context;
GLXWindow dummy_glxwin;
} CoglDisplayGLX;
#endif /* __COGL_DISPLAY_GLX_PRIVATE_H */

View file

@ -0,0 +1,35 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_DISPLAY_XLIB_PRIVATE_H
#define __COGL_DISPLAY_XLIB_PRIVATE_H
#include <X11/Xlib.h>
typedef struct _CoglDisplayXlib
{
Window dummy_xwin;
} CoglDisplayXlib;
#endif /* __COGL_DISPLAY_XLIB_PRIVATE_H */

View file

@ -100,6 +100,11 @@ cogl_display_setup (CoglDisplay *display,
if (display->setup) if (display->setup)
return TRUE; return TRUE;
#ifdef COGL_HAS_FULL_WINSYS
if (!_cogl_winsys_display_setup (display, error))
return FALSE;
#endif
display->setup = TRUE; display->setup = TRUE;
return TRUE; return TRUE;

View file

@ -31,6 +31,9 @@
#ifndef __COGL_DISPLAY_H__ #ifndef __COGL_DISPLAY_H__
#define __COGL_DISPLAY_H__ #define __COGL_DISPLAY_H__
#include <cogl/cogl-renderer.h>
#include <cogl/cogl-onscreen-template.h>
G_BEGIN_DECLS G_BEGIN_DECLS
/** /**
@ -69,8 +72,15 @@ typedef struct _CoglDisplay CoglDisplay;
#define COGL_DISPLAY(OBJECT) ((CoglDisplay *)OBJECT) #define COGL_DISPLAY(OBJECT) ((CoglDisplay *)OBJECT)
#define cogl_display_new cogl_display_new_EXP
CoglDisplay * CoglDisplay *
cogl_display_new (CoglDisplay *display); cogl_display_new (CoglRenderer *renderer,
CoglOnscreenTemplate *onscreen_template);
#define cogl_display_setup cogl_display_setup_EXP
gboolean
cogl_display_setup (CoglDisplay *display,
GError **error);
G_END_DECLS G_END_DECLS

View file

@ -37,7 +37,8 @@ _cogl_feature_check (const char *driver_prefix,
const CoglFeatureData *data, const CoglFeatureData *data,
unsigned int gl_major, unsigned int gl_major,
unsigned int gl_minor, unsigned int gl_minor,
const char *extensions_string) const char *extensions_string,
void *function_table)
{ {
const char *suffix = NULL; const char *suffix = NULL;
@ -123,7 +124,7 @@ _cogl_feature_check (const char *driver_prefix,
break; break;
/* Set the function pointer in the context */ /* Set the function pointer in the context */
*(void **) ((guint8 *) ctx + *(void **) ((guint8 *) function_table +
data->functions[func_num].pointer_offset) = func; data->functions[func_num].pointer_offset) = func;
} }

View file

@ -26,6 +26,8 @@
#include <glib.h> #include <glib.h>
#include "cogl-internal.h"
#define COGL_CHECK_GL_VERSION(driver_major, driver_minor, \ #define COGL_CHECK_GL_VERSION(driver_major, driver_minor, \
target_major, target_minor) \ target_major, target_minor) \
((driver_major) > (target_major) || \ ((driver_major) > (target_major) || \
@ -59,17 +61,21 @@ struct _CoglFeatureData
const char *extension_names; const char *extension_names;
/* A set of feature flags to enable if the extension is available */ /* A set of feature flags to enable if the extension is available */
CoglFeatureFlags feature_flags; CoglFeatureFlags feature_flags;
/* A set of private feature flags to enable if the extension is available /* FIXME: This is now unused */
* and for internal use only */ int padding_feature_flags_private;
CoglFeatureFlagsPrivate feature_flags_private; /* An optional corresponding winsys feature. */
CoglWinsysFeature winsys_feature;
/* A list of functions required for this feature. Terminated with a /* A list of functions required for this feature. Terminated with a
NULL name */ NULL name */
const CoglFeatureFunction *functions; const CoglFeatureFunction *functions;
}; };
gboolean _cogl_feature_check (const char *driver_prefix, gboolean
_cogl_feature_check (const char *driver_prefix,
const CoglFeatureData *data, const CoglFeatureData *data,
unsigned int gl_major, unsigned int gl_minor, unsigned int gl_major,
const char *extensions_string); unsigned int gl_minor,
const char *extensions_string,
void *function_table);
#endif /* __COGL_FEATURE_PRIVATE_H */ #endif /* __COGL_FEATURE_PRIVATE_H */

View file

@ -24,11 +24,20 @@
#ifndef __COGL_FRAMEBUFFER_PRIVATE_H #ifndef __COGL_FRAMEBUFFER_PRIVATE_H
#define __COGL_FRAMEBUFFER_PRIVATE_H #define __COGL_FRAMEBUFFER_PRIVATE_H
#include "cogl-handle.h" #include "cogl-object-private.h"
#include "cogl-matrix-stack.h" #include "cogl-matrix-stack.h"
#include "cogl-clip-state-private.h" #include "cogl-clip-state-private.h"
#include "cogl-journal-private.h" #include "cogl-journal-private.h"
#ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xlib.h>
#endif
#ifdef COGL_HAS_GLX_SUPPORT
#include <GL/glx.h>
#include <GL/glxext.h>
#endif
typedef enum _CoglFramebufferType { typedef enum _CoglFramebufferType {
COGL_FRAMEBUFFER_TYPE_ONSCREEN, COGL_FRAMEBUFFER_TYPE_ONSCREEN,
COGL_FRAMEBUFFER_TYPE_OFFSCREEN COGL_FRAMEBUFFER_TYPE_OFFSCREEN
@ -37,12 +46,14 @@ typedef enum _CoglFramebufferType {
struct _CoglFramebuffer struct _CoglFramebuffer
{ {
CoglObject _parent; CoglObject _parent;
CoglContext *context;
CoglFramebufferType type; CoglFramebufferType type;
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
premult state) */ premult state) */
CoglPixelFormat format; CoglPixelFormat format;
gboolean allocated;
CoglMatrixStack *modelview_stack; CoglMatrixStack *modelview_stack;
CoglMatrixStack *projection_stack; CoglMatrixStack *projection_stack;
@ -85,8 +96,6 @@ struct _CoglFramebuffer
gboolean clear_clip_dirty; gboolean clear_clip_dirty;
}; };
#define COGL_FRAMEBUFFER(X) ((CoglFramebuffer *)(X))
typedef struct _CoglOffscreen typedef struct _CoglOffscreen
{ {
CoglFramebuffer _parent; CoglFramebuffer _parent;
@ -103,12 +112,18 @@ typedef enum
#define COGL_OFFSCREEN(X) ((CoglOffscreen *)(X)) #define COGL_OFFSCREEN(X) ((CoglOffscreen *)(X))
typedef struct _CoglOnscreen struct _CoglOnscreen
{ {
CoglFramebuffer _parent; CoglFramebuffer _parent;
} CoglOnscreen;
#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X)) #ifdef COGL_HAS_X11_SUPPORT
guint32 foreign_xid;
#endif
gboolean swap_throttled;
void *winsys;
};
void void
_cogl_framebuffer_state_init (void); _cogl_framebuffer_state_init (void);
@ -233,7 +248,11 @@ typedef enum _CoglFramebufferFlushFlags
COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW = 1L<<0, COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW = 1L<<0,
/* Similarly this flag implies you are going to flush the clip state /* Similarly this flag implies you are going to flush the clip state
yourself */ yourself */
COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE = 1L<<1 COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE = 1L<<1,
/* When using this all that will be updated is the glBindFramebuffer
* state and corresponding winsys state to make the framebuffer
* current if it is a CoglOnscreen framebuffer. */
COGL_FRAMEBUFFER_FLUSH_BIND_ONLY = 1L<<2
} CoglFramebufferFlushFlags; } CoglFramebufferFlushFlags;
void void
@ -241,9 +260,6 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer, CoglFramebuffer *read_buffer,
CoglFramebufferFlushFlags flags); CoglFramebufferFlushFlags flags);
CoglHandle
_cogl_onscreen_new (void);
CoglFramebuffer * CoglFramebuffer *
_cogl_get_read_framebuffer (void); _cogl_get_read_framebuffer (void);
@ -339,5 +355,8 @@ _cogl_blit_framebuffer (unsigned int src_x,
unsigned int width, unsigned int width,
unsigned int height); unsigned int height);
CoglOnscreen *
_cogl_onscreen_new (void);
#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */ #endif /* __COGL_FRAMEBUFFER_PRIVATE_H */

View file

@ -36,6 +36,7 @@
#include "cogl-framebuffer-private.h" #include "cogl-framebuffer-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"
#ifndef HAVE_COGL_GLES2 #ifndef HAVE_COGL_GLES2
@ -291,6 +292,8 @@ _cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
int scissor_x1; int scissor_x1;
int scissor_y1; int scissor_y1;
g_return_if_fail (framebuffer->allocated);
_cogl_clip_stack_get_bounds (clip_stack, _cogl_clip_stack_get_bounds (clip_stack,
&scissor_x0, &scissor_y0, &scissor_x0, &scissor_y0,
&scissor_x1, &scissor_y1); &scissor_x1, &scissor_y1);
@ -451,6 +454,8 @@ _cogl_framebuffer_clear (CoglFramebuffer *framebuffer,
unsigned long buffers, unsigned long buffers,
const CoglColor *color) const CoglColor *color)
{ {
g_return_if_fail (framebuffer->allocated);
_cogl_framebuffer_clear4f (framebuffer, buffers, _cogl_framebuffer_clear4f (framebuffer, buffers,
cogl_color_get_red_float (color), cogl_color_get_red_float (color),
cogl_color_get_green_float (color), cogl_color_get_green_float (color),
@ -811,8 +816,6 @@ _cogl_offscreen_new_to_texture_full (CoglHandle texhandle,
CoglFramebufferTryFBOData data; CoglFramebufferTryFBOData data;
gboolean fbo_created; gboolean fbo_created;
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (!cogl_features_available (COGL_FEATURE_OFFSCREEN))
return COGL_INVALID_HANDLE; return COGL_INVALID_HANDLE;
@ -887,8 +890,11 @@ _cogl_offscreen_new_to_texture_full (CoglHandle texhandle,
if (fbo_created) if (fbo_created)
{ {
CoglOffscreen *ret; CoglOffscreen *ret;
CoglFramebuffer *fb = COGL_FRAMEBUFFER (offscreen);
_cogl_framebuffer_init (COGL_FRAMEBUFFER (offscreen), _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
_cogl_framebuffer_init (fb,
ctx, ctx,
COGL_FRAMEBUFFER_TYPE_OFFSCREEN, COGL_FRAMEBUFFER_TYPE_OFFSCREEN,
cogl_texture_get_format (texhandle), cogl_texture_get_format (texhandle),
@ -901,6 +907,8 @@ _cogl_offscreen_new_to_texture_full (CoglHandle texhandle,
ret = _cogl_offscreen_object_new (offscreen); ret = _cogl_offscreen_object_new (offscreen);
_cogl_texture_associate_framebuffer (texhandle, COGL_FRAMEBUFFER (ret)); _cogl_texture_associate_framebuffer (texhandle, COGL_FRAMEBUFFER (ret));
fb->allocated = TRUE;
return ret; return ret;
} }
else else
@ -946,16 +954,34 @@ _cogl_offscreen_free (CoglOffscreen *offscreen)
g_free (offscreen); g_free (offscreen);
} }
CoglHandle /* XXX: While we still have backend in Clutter we need a dummy object
* to represent the CoglOnscreen framebuffer that the backend
* creates... */
CoglOnscreen *
_cogl_onscreen_new (void) _cogl_onscreen_new (void)
{ {
CoglOnscreen *onscreen; CoglOnscreen *onscreen = g_new0 (CoglOnscreen, 1);
_COGL_GET_CONTEXT (ctx, NULL); _COGL_GET_CONTEXT (ctx, NULL);
/* XXX: Until we have full winsys support in Cogl then we can't fully _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen),
* implement CoglOnscreen framebuffers, since we can't, e.g. keep track of ctx,
* the window size. */ COGL_FRAMEBUFFER_TYPE_ONSCREEN,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
0xdeadbeef, /* width */
0xdeadbeef); /* height */
COGL_FRAMEBUFFER (onscreen)->allocated = TRUE;
/* XXX: Note we don't initialize onscreen->winsys in this case. */
return _cogl_onscreen_object_new (onscreen);
}
CoglOnscreen *
cogl_onscreen_new (CoglContext *ctx, int width, int height)
{
CoglOnscreen *onscreen;
/* FIXME: We are assuming onscreen buffers will always be /* FIXME: We are assuming onscreen buffers will always be
premultiplied so we'll set the premult flag on the bitmap premultiplied so we'll set the premult flag on the bitmap
@ -973,15 +999,41 @@ _cogl_onscreen_new (void)
ctx, ctx,
COGL_FRAMEBUFFER_TYPE_ONSCREEN, COGL_FRAMEBUFFER_TYPE_ONSCREEN,
COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_PIXEL_FORMAT_RGBA_8888_PRE,
0xdeadbeef, /* width */ width, /* width */
0xdeadbeef); /* height */ height); /* height */
onscreen->swap_throttled = TRUE;
return _cogl_onscreen_object_new (onscreen); return _cogl_onscreen_object_new (onscreen);
} }
gboolean
cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
GError **error)
{
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
if (framebuffer->allocated)
return TRUE;
/* XXX: with the current cogl_offscreen_new_to_texture() API the
* framebuffer is implicitly allocated before returning. */
g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN,
TRUE);
if (!_cogl_winsys_onscreen_init (onscreen, error))
return FALSE;
framebuffer->allocated = TRUE;
return TRUE;
}
static void static void
_cogl_onscreen_free (CoglOnscreen *onscreen) _cogl_onscreen_free (CoglOnscreen *onscreen)
{ {
_cogl_winsys_onscreen_deinit (onscreen);
/* Chain up to parent */ /* Chain up to parent */
_cogl_framebuffer_free (COGL_FRAMEBUFFER (onscreen)); _cogl_framebuffer_free (COGL_FRAMEBUFFER (onscreen));
@ -1059,11 +1111,14 @@ static void
_cogl_set_framebuffers_real (CoglFramebuffer *draw_buffer, _cogl_set_framebuffers_real (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer) CoglFramebuffer *read_buffer)
{ {
CoglContext *ctx = draw_buffer->context;
CoglFramebufferStackEntry *entry; CoglFramebufferStackEntry *entry;
GSList *l;
g_return_if_fail (context != NULL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
g_return_if_fail (draw_buffer->context == read_buffer->context);
g_return_if_fail (ctx != NULL);
g_return_if_fail (draw_buffer && read_buffer ?
draw_buffer->context == read_buffer->context : TRUE);
entry = ctx->framebuffer_stack->data; entry = ctx->framebuffer_stack->data;
@ -1087,9 +1142,26 @@ _cogl_set_framebuffers_real (CoglFramebuffer *draw_buffer,
* projection matrix stacks and clip state so we need to dirty * projection matrix stacks and clip state so we need to dirty
* them to ensure they get flushed for the next batch of geometry * them to ensure they get flushed for the next batch of geometry
* we flush */ * we flush */
if (draw_buffer)
{
_cogl_matrix_stack_dirty (draw_buffer->modelview_stack); _cogl_matrix_stack_dirty (draw_buffer->modelview_stack);
_cogl_matrix_stack_dirty (draw_buffer->projection_stack); _cogl_matrix_stack_dirty (draw_buffer->projection_stack);
}
_cogl_clip_stack_dirty (); _cogl_clip_stack_dirty ();
/* XXX:
* To support the deprecated cogl_set_draw_buffer API we keep track
* of the last onscreen framebuffer that was pushed so that it can
* be restored if the COGL_WINDOW_BUFFER enum is used. */
ctx->window_buffer = NULL;
for (l = ctx->framebuffer_stack; l; l = l->next)
{
entry = l->data;
if (entry->draw_buffer &&
entry->draw_buffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
ctx->window_buffer = entry->draw_buffer;
}
} }
static void static void
@ -1182,15 +1254,19 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
g_return_if_fail (_cogl_is_framebuffer (read_buffer)); g_return_if_fail (_cogl_is_framebuffer (read_buffer));
ctx = draw_buffer->context; ctx = draw_buffer->context;
g_return_if_fail (context != NULL); g_return_if_fail (ctx != NULL);
g_return_if_fail (draw_buffer->context == read_buffer->context); g_return_if_fail (draw_buffer->context == read_buffer->context);
g_return_if_fail (context->framebuffer_stack != NULL); g_return_if_fail (ctx->framebuffer_stack != NULL);
/* Copy the top of the stack so that when we call cogl_set_framebuffer /* Copy the top of the stack so that when we call cogl_set_framebuffer
it will still know what the old framebuffer was */ it will still know what the old framebuffer was */
old_draw_buffer = cogl_object_ref (cogl_get_draw_framebuffer ()); old_draw_buffer = cogl_get_draw_framebuffer ();
old_read_buffer = cogl_object_ref (_cogl_get_read_framebuffer ()); if (old_draw_buffer)
cogl_object_ref (old_draw_buffer);
old_read_buffer = _cogl_get_read_framebuffer ();
if (old_read_buffer)
cogl_object_ref (old_read_buffer);
ctx->framebuffer_stack = ctx->framebuffer_stack =
g_slist_prepend (ctx->framebuffer_stack, g_slist_prepend (ctx->framebuffer_stack,
create_stack_entry (old_draw_buffer, create_stack_entry (old_draw_buffer,
@ -1264,16 +1340,21 @@ cogl_pop_draw_buffer (void)
} }
static void static void
bind_gl_framebuffer (GLenum target, CoglFramebuffer *framebuffer) bind_gl_framebuffer (CoglContext *ctx,
GLenum target,
CoglFramebuffer *framebuffer)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
GE (glBindFramebuffer (target, GE (glBindFramebuffer (target,
COGL_OFFSCREEN (framebuffer)->fbo_handle)); COGL_OFFSCREEN (framebuffer)->fbo_handle));
else else
{
#ifdef COGL_HAS_FULL_WINSYS
_cogl_winsys_onscreen_bind (COGL_ONSCREEN (framebuffer));
#endif
GE (glBindFramebuffer (target, 0)); GE (glBindFramebuffer (target, 0));
} }
}
void void
_cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer, _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
@ -1282,20 +1363,28 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
{ {
CoglContext *ctx = draw_buffer->context; CoglContext *ctx = draw_buffer->context;
if (cogl_features_available (COGL_FEATURE_OFFSCREEN) && if (ctx->dirty_bound_framebuffer)
ctx->dirty_bound_framebuffer)
{ {
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN_BLIT) || if (draw_buffer == read_buffer)
draw_buffer == read_buffer) bind_gl_framebuffer (ctx, GL_FRAMEBUFFER, draw_buffer);
bind_gl_framebuffer (GL_FRAMEBUFFER, draw_buffer);
else else
{ {
bind_gl_framebuffer (GL_DRAW_FRAMEBUFFER, draw_buffer); /* NB: Currently we only take advantage of binding separate
bind_gl_framebuffer (GL_READ_FRAMEBUFFER, read_buffer); * read/write buffers for offscreen framebuffer blit
* purposes. */
g_return_if_fail (cogl_features_available (COGL_FEATURE_OFFSCREEN_BLIT));
g_return_if_fail (draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN);
g_return_if_fail (read_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN);
bind_gl_framebuffer (ctx, GL_DRAW_FRAMEBUFFER, draw_buffer);
bind_gl_framebuffer (ctx, GL_READ_FRAMEBUFFER, read_buffer);
}
} }
ctx->dirty_bound_framebuffer = FALSE; ctx->dirty_bound_framebuffer = FALSE;
}
if (flags & COGL_FRAMEBUFFER_FLUSH_BIND_ONLY)
return;
if (ctx->dirty_gl_viewport) if (ctx->dirty_gl_viewport)
{ {
@ -1452,6 +1541,8 @@ _cogl_blit_framebuffer (unsigned int src_x,
CoglFramebuffer *read_buffer; CoglFramebuffer *read_buffer;
CoglContext *ctx; CoglContext *ctx;
/* FIXME: this function should take explit src and dst framebuffer
* arguments. */
draw_buffer = cogl_get_draw_framebuffer (); draw_buffer = cogl_get_draw_framebuffer ();
read_buffer = _cogl_get_read_framebuffer (); read_buffer = _cogl_get_read_framebuffer ();
ctx = draw_buffer->context; ctx = draw_buffer->context;
@ -1484,3 +1575,83 @@ _cogl_blit_framebuffer (unsigned int src_x,
GL_COLOR_BUFFER_BIT, GL_COLOR_BUFFER_BIT,
GL_NEAREST); GL_NEAREST);
} }
void
cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer)
{
/* FIXME: we shouldn't need to flush *all* journals here! */
cogl_flush ();
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
_cogl_winsys_onscreen_swap_buffers (COGL_ONSCREEN (framebuffer));
}
void
cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer,
int *rectangles,
int n_rectangles)
{
/* FIXME: we shouldn't need to flush *all* journals here! */
cogl_flush ();
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
_cogl_winsys_onscreen_swap_region (COGL_ONSCREEN (framebuffer),
rectangles,
n_rectangles);
}
#ifdef COGL_HAS_X11_SUPPORT
void
cogl_onscreen_x11_set_foreign_window_xid (CoglOnscreen *onscreen,
guint32 xid)
{
onscreen->foreign_xid = xid;
}
guint32
cogl_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
{
return _cogl_winsys_onscreen_x11_get_window_xid (onscreen);
}
guint32
cogl_onscreen_x11_get_visual_xid (CoglOnscreen *onscreen)
{
guint32 id;
XVisualInfo *visinfo = _cogl_winsys_xlib_get_visual_info ();
id = (guint32)visinfo->visualid;
XFree (visinfo);
return id;
}
#endif /* COGL_HAS_X11_SUPPORT */
unsigned int
cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer,
CoglSwapBuffersNotify callback,
void *user_data)
{
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
/* Should this just be cogl_onscreen API instead? */
g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0);
return _cogl_winsys_onscreen_add_swap_buffers_callback (onscreen,
callback,
user_data);
}
void
cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer,
unsigned int id)
{
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
_cogl_winsys_onscreen_remove_swap_buffers_callback (onscreen, id);
}
void
cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
gboolean throttled)
{
onscreen->swap_throttled = throttled;
if (COGL_FRAMEBUFFER (onscreen)->allocated)
_cogl_winsys_onscreen_update_swap_throttled (onscreen);
}

109
cogl/cogl-framebuffer.h Normal file
View file

@ -0,0 +1,109 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef __COGL_FRAMEBUFFER_H
#define __COGL_FRAMEBUFFER_H
#include <glib.h>
G_BEGIN_DECLS
#ifdef COGL_ENABLE_EXPERIMENTAL_API
#define cogl_onscreen_new cogl_onscreen_new_EXP
#define COGL_FRAMEBUFFER(X) ((CoglFramebuffer *)(X))
#define cogl_framebuffer_allocate cogl_framebuffer_allocate_EXP
gboolean
cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
GError **error);
#define cogl_framebuffer_swap_buffers cogl_framebuffer_swap_buffers_EXP
void
cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer);
#define cogl_framebuffer_swap_region cogl_framebuffer_swap_region_EXP
void
cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer,
int *rectangles,
int n_rectangles);
typedef void (*CoglSwapBuffersNotify) (CoglFramebuffer *framebuffer,
void *user_data);
#define cogl_framebuffer_add_swap_buffers_callback \
cogl_framebuffer_add_swap_buffers_callback_EXP
unsigned int
cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer,
CoglSwapBuffersNotify callback,
void *user_data);
#define cogl_framebuffer_remove_swap_buffers_callback \
cogl_framebuffer_remove_swap_buffers_callback_EXP
void
cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer,
unsigned int id);
typedef struct _CoglOnscreen CoglOnscreen;
#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X))
CoglOnscreen *
cogl_onscreen_new (CoglContext *context, int width, int height);
#ifdef COGL_HAS_X11
#define cogl_onscreen_x11_set_foreign_window_xid \
cogl_onscreen_x11_set_foreign_window_xid_EXP
void
cogl_onscreen_x11_set_foreign_window_xid (CoglOnscreen *onscreen,
guint32 xid);
#define cogl_onscreen_x11_get_window_xid cogl_onscreen_x11_get_window_xid_EXP
guint32
cogl_onscreen_x11_get_window_xid (CoglOnscreen *onscreen);
#define cogl_onscreen_x11_get_visual_xid cogl_onscreen_x11_get_visual_xid_EXP
guint32
cogl_onscreen_x11_get_visual_xid (CoglOnscreen *onscreen);
#endif /* COGL_HAS_X11 */
void
cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
gboolean throttled);
#define cogl_get_draw_framebuffer cogl_get_draw_framebuffer_EXP
CoglFramebuffer *
cogl_get_draw_framebuffer (void);
#endif /* COGL_ENABLE_EXPERIMENTAL_API */
G_END_DECLS
#endif /* __COGL_FRAMEBUFFER_H */

View file

@ -29,7 +29,7 @@
#include "cogl-bitmask.h" #include "cogl-bitmask.h"
#ifdef COGL_HAS_XLIB_SUPPORT #ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xlib.h> #include <X11/Xutil.h>
#endif #endif
typedef enum typedef enum
@ -119,99 +119,17 @@ _cogl_transform_point (const CoglMatrix *matrix_mv,
float *x, float *x,
float *y); float *y);
#ifdef COGL_HAS_XLIB_SUPPORT #define COGL_DRIVER_ERROR (_cogl_driver_error_quark ())
/* typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/
* CoglX11FilterReturn: COGL_DRIVER_ERROR_UNKNOWN_VERSION,
* @COGL_XLIB_FILTER_CONTINUE: The event was not handled, continues the COGL_DRIVER_ERROR_INVALID_VERSION
* processing } CoglDriverError;
* @COGL_XLIB_FILTER_REMOVE: Remove the event, stops the processing
*
* Return values for the #CoglX11FilterFunc function.
*/
typedef enum _CoglXlibFilterReturn {
COGL_XLIB_FILTER_CONTINUE,
COGL_XLIB_FILTER_REMOVE
} CoglXlibFilterReturn;
/*
* CoglXlibFilterFunc:
*
* A callback function that can be registered with
* _cogl_xlib_add_filter. The function should return
* %COGL_XLIB_FILTER_REMOVE if it wants to prevent further processing
* or %COGL_XLIB_FILTER_CONTINUE otherwise.
*/
typedef CoglXlibFilterReturn (* CoglXlibFilterFunc) (XEvent *xevent,
gpointer data);
/*
* cogl_xlib_handle_event:
* @xevent: pointer to XEvent structure
*
* This function processes a single X event; it can be used to hook
* into external X event retrieval (for example that done by Clutter
* or GDK).
*
* Return value: #CoglXlibFilterReturn. %COGL_XLIB_FILTER_REMOVE
* indicates that Cogl has internally handled the event and the
* caller should do no further processing. %COGL_XLIB_FILTER_CONTINUE
* indicates that Cogl is either not interested in the event,
* or has used the event to update internal state without taking
* any exclusive action.
*/
CoglXlibFilterReturn
_cogl_xlib_handle_event (XEvent *xevent);
/*
* _cogl_xlib_get_display:
*
* Return value: the Xlib display that will be used by the Xlib winsys
* backend. The display needs to be set with _cogl_xlib_set_display()
* before this function is called.
*/
Display *
_cogl_xlib_get_display (void);
/*
* cogl_xlib_set_display:
*
* Sets the Xlib display that Cogl will use for the Xlib winsys
* backend. This function should eventually go away when Cogl gains a
* more complete winsys abstraction.
*/
void
_cogl_xlib_set_display (Display *display);
/*
* _cogl_xlib_add_filter:
*
* Adds a callback function that will receive all X11 events. The
* function can stop further processing of the event by return
* %COGL_XLIB_FILTER_REMOVE.
*/
void
_cogl_xlib_add_filter (CoglXlibFilterFunc func,
gpointer data);
/*
* _cogl_xlib_remove_filter:
*
* Removes a callback that was previously added with
* _cogl_xlib_add_filter().
*/
void
_cogl_xlib_remove_filter (CoglXlibFilterFunc func,
gpointer data);
#endif /* COGL_HAS_XLIB_SUPPORT */
typedef enum _CoglFeatureFlagsPrivate
{
COGL_FEATURE_PRIVATE_PLACE_HOLDER = (1 << 0)
} CoglFeatureFlagsPrivate;
gboolean gboolean
_cogl_features_available_private (CoglFeatureFlagsPrivate features); _cogl_check_extension (const char *name, const char *ext);
GQuark
_cogl_driver_error_quark (void);
#endif /* __COGL_INTERNAL_H */ #endif /* __COGL_INTERNAL_H */

View file

@ -24,6 +24,7 @@
#ifndef __COGL_JOURNAL_PRIVATE_H #ifndef __COGL_JOURNAL_PRIVATE_H
#define __COGL_JOURNAL_PRIVATE_H #define __COGL_JOURNAL_PRIVATE_H
#include "cogl.h"
#include "cogl-handle.h" #include "cogl-handle.h"
#include "cogl-clip-stack.h" #include "cogl-clip-stack.h"

View file

@ -26,6 +26,12 @@
G_BEGIN_DECLS G_BEGIN_DECLS
gboolean
_cogl_gl_check_version (GError **error);
void
_cogl_gl_update_features (CoglContext *context);
gboolean gboolean
_cogl_check_extension (const char *name, const char *ext); _cogl_check_extension (const char *name, const char *ext);

View file

@ -0,0 +1,61 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_RENDERER_GLX_PRIVATE_H
#define __COGL_RENDERER_GLX_PRIVATE_H
#include "cogl-object-private.h"
#include "cogl-renderer-xlib-private.h"
typedef struct _CoglRendererGLX
{
CoglRendererXlib _parent;
int glx_major;
int glx_minor;
int glx_error_base;
int glx_event_base;
gboolean is_direct;
/* Vblank stuff */
int dri_fd;
/* Function pointers for GLX specific extensions */
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f)
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
ret (APIENTRY * pf_ ## name) args;
#define COGL_WINSYS_FEATURE_END()
#include "cogl-winsys-glx-feature-functions.h"
#undef COGL_WINSYS_FEATURE_BEGIN
#undef COGL_WINSYS_FEATURE_FUNCTION
#undef COGL_WINSYS_FEATURE_END
} CoglRendererGLX;
#endif /* __COGL_RENDERER_GLX_PRIVATE_H */

View file

@ -0,0 +1,32 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_RENDERER_X11_PRIVATE_H
#define __COGL_RENDERER_X11_PRIVATE_H
typedef struct _CoglRendererX11
{
int damage_base;
} CoglRendererX11;
#endif /* __COGL_RENDERER_X11_PRIVATE_H */

View file

@ -3,7 +3,7 @@
* *
* An object oriented GL/GLES Abstraction/Utility Layer * An object oriented GL/GLES Abstraction/Utility Layer
* *
* Copyright (C) 2010 Intel Corporation. * Copyright (C) 2011 Intel Corporation.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -15,30 +15,40 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public License
* License along with this library. If not, see <http://www.gnu.org/licenses/>. * along with this library. If not, see <http://www.gnu.org/licenses/>.
* *
* *
*/ */
#ifndef __COGL_XLIB_H #ifndef __COGL_RENDERER_XLIB_PRIVATE_H
#define __COGL_XLIB_H #define __COGL_RENDERER_XLIB_PRIVATE_H
#include "cogl.h" #include "cogl-object-private.h"
#include "cogl-context-winsys.h" #include "cogl-xlib-private.h"
#include "cogl-renderer-x11-private.h"
#include <X11/Xlib.h> typedef struct _CoglRendererXlib
typedef struct _CoglXlibFilterClosure CoglXlibFilterClosure;
struct _CoglXlibFilterClosure
{ {
CoglXlibFilterFunc func; CoglRendererX11 _parent;
gpointer data;
}; Display *xdpy;
/* List of callback functions that will be given every Xlib event */
GSList *event_filters;
/* Current top of the XError trap state stack. The actual memory for
these is expected to be allocated on the stack by the caller */
CoglXlibTrapState *trap_state;
} CoglRendererXlib;
gboolean
_cogl_renderer_xlib_connect (CoglRenderer *renderer, GError **error);
void
_cogl_renderer_xlib_disconnect (CoglRenderer *renderer);
/* /*
* _cogl_xlib_trap_errors: * cogl_renderer_xlib_trap_errors:
* @state: A temporary place to store data for the trap. * @state: A temporary place to store data for the trap.
* *
* Traps every X error until _cogl_xlib_untrap_errors() called. You * Traps every X error until _cogl_xlib_untrap_errors() called. You
@ -50,10 +60,11 @@ struct _CoglXlibFilterClosure
* pointers in reverse order. * pointers in reverse order.
*/ */
void void
_cogl_xlib_trap_errors (CoglXlibTrapState *state); _cogl_renderer_xlib_trap_errors (CoglRenderer *renderer,
CoglXlibTrapState *state);
/* /*
* _cogl_xlib_untrap_errors: * cogl_renderer_xlib_untrap_errors:
* @state: The state that was passed to _cogl_xlib_trap_errors(). * @state: The state that was passed to _cogl_xlib_trap_errors().
* *
* Removes the X error trap and returns the current status. * Removes the X error trap and returns the current status.
@ -61,6 +72,7 @@ _cogl_xlib_trap_errors (CoglXlibTrapState *state);
* Return value: the trapped error code, or 0 for success * Return value: the trapped error code, or 0 for success
*/ */
int int
_cogl_xlib_untrap_errors (CoglXlibTrapState *state); _cogl_renderer_xlib_untrap_errors (CoglRenderer *renderer,
CoglXlibTrapState *state);
#endif /* __COGL_XLIB_H */ #endif /* __COGL_RENDERER_XLIB_PRIVATE_H */

288
cogl/cogl-renderer-xlib.c Normal file
View file

@ -0,0 +1,288 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2008,2009,2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "cogl.h"
#include "cogl-internal.h"
#include "cogl-object.h"
#include "cogl-renderer-private.h"
#include "cogl-renderer-xlib-private.h"
#include "cogl-renderer-x11-private.h"
#include "cogl-winsys-private.h"
#include <X11/Xlib.h>
#include <X11/extensions/Xdamage.h>
static char *_cogl_x11_display_name = NULL;
static GList *_cogl_xlib_renderers = NULL;
CoglXlibFilterReturn
cogl_renderer_xlib_handle_event (CoglRenderer *renderer,
XEvent *xevent)
{
CoglRendererXlib *xlib_renderer = renderer->winsys;
GSList *l;
g_return_val_if_fail (xlib_renderer->xdpy != NULL, COGL_XLIB_FILTER_CONTINUE);
/* XXX: should this be a more graceful check? */
g_return_val_if_fail (xlib_renderer != NULL, COGL_XLIB_FILTER_CONTINUE);
/* Pass the event on to all of the registered filters in turn */
for (l = xlib_renderer->event_filters; l; l = l->next)
{
CoglXlibFilterClosure *closure = l->data;
if (closure->func (xevent, closure->data) == COGL_XLIB_FILTER_REMOVE)
return COGL_XLIB_FILTER_REMOVE;
}
switch (xevent->type)
{
/* TODO... */
default:
break;
}
return COGL_XLIB_FILTER_CONTINUE;
}
void
cogl_renderer_xlib_add_filter (CoglRenderer *renderer,
CoglXlibFilterFunc func,
void *data)
{
CoglRendererXlib *xlib_renderer;
CoglXlibFilterClosure *closure;
xlib_renderer = renderer->winsys;
closure = g_slice_new (CoglXlibFilterClosure);
closure->func = func;
closure->data = data;
xlib_renderer->event_filters =
g_slist_prepend (xlib_renderer->event_filters, closure);
}
void
cogl_renderer_xlib_remove_filter (CoglRenderer *renderer,
CoglXlibFilterFunc func,
void *data)
{
CoglRendererXlib *xlib_renderer;
GSList *l, *prev = NULL;
xlib_renderer = renderer->winsys;
for (l = xlib_renderer->event_filters; l; prev = l, l = l->next)
{
CoglXlibFilterClosure *closure = l->data;
if (closure->func == func && closure->data == data)
{
g_slice_free (CoglXlibFilterClosure, closure);
if (prev)
prev->next = g_slist_delete_link (prev->next, l);
else
xlib_renderer->event_filters =
g_slist_delete_link (xlib_renderer->event_filters, l);
break;
}
}
}
static void
register_xlib_renderer (CoglRenderer *renderer)
{
GList *l;
for (l = _cogl_xlib_renderers; l; l = l->next)
if (l->data == renderer)
return;
_cogl_xlib_renderers = g_list_prepend (_cogl_xlib_renderers, renderer);
}
static void
unregister_xlib_renderer (CoglRenderer *renderer)
{
_cogl_xlib_renderers = g_list_remove (_cogl_xlib_renderers, renderer);
}
static CoglRenderer *
get_renderer_for_xdisplay (Display *xdpy)
{
GList *l;
for (l = _cogl_xlib_renderers; l; l = l->next)
{
CoglRenderer *renderer = l->data;
CoglRendererXlib *xlib_renderer = renderer->winsys;
if (xlib_renderer->xdpy == xdpy)
return renderer;
}
return NULL;
}
static int
error_handler (Display *xdpy,
XErrorEvent *error)
{
CoglRenderer *renderer;
CoglRendererXlib *xlib_renderer;
renderer = get_renderer_for_xdisplay (xdpy);
xlib_renderer = renderer->winsys;
g_assert (xlib_renderer->trap_state);
xlib_renderer->trap_state->trapped_error_code = error->error_code;
return 0;
}
void
_cogl_renderer_xlib_trap_errors (CoglRenderer *renderer,
CoglXlibTrapState *state)
{
CoglRendererXlib *xlib_renderer;
xlib_renderer = renderer->winsys;
state->trapped_error_code = 0;
state->old_error_handler = XSetErrorHandler (error_handler);
state->old_state = xlib_renderer->trap_state;
xlib_renderer->trap_state = state;
}
int
_cogl_renderer_xlib_untrap_errors (CoglRenderer *renderer,
CoglXlibTrapState *state)
{
CoglRendererXlib *xlib_renderer;
xlib_renderer = renderer->winsys;
g_assert (state == xlib_renderer->trap_state);
XSetErrorHandler (state->old_error_handler);
xlib_renderer->trap_state = state->old_state;
return state->trapped_error_code;
}
static Display *
assert_xlib_display (CoglRenderer *renderer, GError **error)
{
Display *xdpy = cogl_renderer_xlib_get_foreign_display (renderer);
CoglRendererXlib *xlib_renderer = renderer->winsys;
/* A foreign display may have already been set... */
if (xdpy)
{
xlib_renderer->xdpy = xdpy;
return xdpy;
}
xdpy = XOpenDisplay (_cogl_x11_display_name);
if (xdpy == NULL)
{
g_set_error (error,
COGL_RENDERER_ERROR,
COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN,
"Failed to open X Display %s", _cogl_x11_display_name);
return NULL;
}
xlib_renderer->xdpy = xdpy;
return xdpy;
}
gboolean
_cogl_renderer_xlib_connect (CoglRenderer *renderer, GError **error)
{
CoglRendererXlib *xlib_renderer = renderer->winsys;
CoglRendererX11 *x11_renderer = renderer->winsys;
int damage_error;
if (!assert_xlib_display (renderer, error))
return FALSE;
/* Check whether damage events are supported on this display */
if (!XDamageQueryExtension (xlib_renderer->xdpy,
&x11_renderer->damage_base,
&damage_error))
x11_renderer->damage_base = -1;
xlib_renderer->event_filters = NULL;
xlib_renderer->trap_state = NULL;
register_xlib_renderer (renderer);
return TRUE;
}
static void
free_xlib_filter_closure (void *data, void *user_data)
{
g_slice_free (CoglXlibFilterClosure, data);
}
void
_cogl_renderer_xlib_disconnect (CoglRenderer *renderer)
{
CoglRendererXlib *xlib_renderer = renderer->winsys;
g_slist_foreach (xlib_renderer->event_filters,
free_xlib_filter_closure, NULL);
g_slist_free (xlib_renderer->event_filters);
if (!renderer->foreign_xdpy)
XCloseDisplay (xlib_renderer->xdpy);
unregister_xlib_renderer (renderer);
}
Display *
cogl_renderer_xlib_get_display (CoglRenderer *renderer)
{
CoglRendererXlib *xlib_renderer;
g_return_val_if_fail (cogl_is_renderer (renderer), NULL);
xlib_renderer = renderer->winsys;
return xlib_renderer->xdpy;
}

View file

@ -50,6 +50,9 @@ cogl_renderer_error_quark (void)
static void static void
_cogl_renderer_free (CoglRenderer *renderer) _cogl_renderer_free (CoglRenderer *renderer)
{ {
#ifdef COGL_HAS_FULL_WINSYS
_cogl_winsys_renderer_disconnect (renderer);
#endif
g_free (renderer); g_free (renderer);
} }
@ -90,6 +93,21 @@ cogl_renderer_check_onscreen_template (CoglRenderer *renderer,
CoglOnscreenTemplate *onscreen_template, CoglOnscreenTemplate *onscreen_template,
GError **error) GError **error)
{ {
#ifdef COGL_HAS_FULL_WINSYS
CoglDisplay *display;
if (!_cogl_winsys_renderer_connect (renderer, error))
return FALSE;
display = cogl_display_new (renderer, onscreen_template);
if (!cogl_display_setup (display, error))
{
cogl_object_unref (display);
return FALSE;
}
cogl_object_unref (display);
#endif
return TRUE; return TRUE;
} }
@ -101,6 +119,11 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error)
if (renderer->connected) if (renderer->connected)
return TRUE; return TRUE;
#ifdef COGL_HAS_FULL_WINSYS
if (!_cogl_winsys_renderer_connect (renderer, error))
return FALSE;
#endif
renderer->connected = TRUE; renderer->connected = TRUE;
return TRUE; return TRUE;
} }

View file

@ -30,6 +30,11 @@
#include <glib-object.h> #include <glib-object.h>
#include <cogl/cogl-defines.h>
#ifdef COGL_HAS_XLIB
#include <X11/Xlib.h>
#endif
G_BEGIN_DECLS G_BEGIN_DECLS
/* Some structures are meant to be opaque but they have public /* Some structures are meant to be opaque but they have public
@ -284,7 +289,8 @@ typedef enum
COGL_FEATURE_TEXTURE_3D = (1 << 19), COGL_FEATURE_TEXTURE_3D = (1 << 19),
COGL_FEATURE_SHADERS_ARBFP = (1 << 20), COGL_FEATURE_SHADERS_ARBFP = (1 << 20),
COGL_FEATURE_MAP_BUFFER_FOR_READ = (1 << 21), COGL_FEATURE_MAP_BUFFER_FOR_READ = (1 << 21),
COGL_FEATURE_MAP_BUFFER_FOR_WRITE = (1 << 22) COGL_FEATURE_MAP_BUFFER_FOR_WRITE = (1 << 22),
COGL_FEATURE_ONSCREEN_MULTIPLE = (1 << 23)
} CoglFeatureFlags; } CoglFeatureFlags;
/** /**
@ -582,11 +588,84 @@ typedef enum
COGL_DEPTH_TEST_FUNCTION_GEQUAL = 0x0206, COGL_DEPTH_TEST_FUNCTION_GEQUAL = 0x0206,
COGL_DEPTH_TEST_FUNCTION_ALWAYS = 0x0207 COGL_DEPTH_TEST_FUNCTION_ALWAYS = 0x0207
} CoglDepthTestFunction; } CoglDepthTestFunction;
/* XXX: Note these types are only referenced by experimental API so
* although they aren't explicitly guarded they are implicitly
* experimental too. */
/* NB: The above definitions are taken from gl.h equivalents */ /* NB: The above definitions are taken from gl.h equivalents */
typedef enum { /*< prefix=COGL_RENDERER_ERROR >*/
COGL_RENDERER_ERROR_NOT_FOUND,
COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN
} CoglRendererError;
/*
* CoglXlibFilterReturn:
* @COGL_XLIB_FILTER_CONTINUE: The event was not handled, continues the
* processing
* @COGL_XLIB_FILTER_REMOVE: Remove the event, stops the processing
*
* Return values for the #CoglXlibFilterFunc function.
*
* Stability: Unstable
*/
typedef enum _CoglXlibFilterReturn { /*< prefix=COGL_XLIB_FILTER >*/
COGL_XLIB_FILTER_CONTINUE,
COGL_XLIB_FILTER_REMOVE
} CoglXlibFilterReturn;
typedef enum _CoglWinsysFeature
{
COGL_WINSYS_FEATURE_NONE,
/* Available if the window system can support multiple onscreen
* framebuffers at the same time. */
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
/* Available if onscreen framebuffer swaps can be automatically
* throttled to the vblank frequency. */
COGL_WINSYS_FEATURE_SWAP_THROTTLE,
/* Available if its possible to query a counter that
* increments at each vblank. */
COGL_WINSYS_FEATURE_VBLANK_COUNTER,
/* Available if its possible to wait until the next vertical
* blank period */
COGL_WINSYS_FEATURE_VBLANK_WAIT,
/* Available if the window system supports mapping native
* pixmaps to textures. */
COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP,
/* Available if the window system supports reporting an event
* for swap buffer completions. */
COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT,
/* Available if it's possible to swap a list of sub rectangles
* from the back buffer to the front buffer */
COGL_WINSYS_FEATURE_SWAP_REGION,
/* Available if swap_region requests can be automatically throttled
* to the vblank frequency. */
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE
} CoglWinsysFeature;
/* XXX: Note these enum types are only referenced by experimental API
* so although they aren't explicitly guarded they are implicitly
* experimental too. */
#ifdef COGL_HAS_XLIB
/*
* CoglXlibFilterFunc:
*
* A callback function that can be registered with
* _cogl_xlib_add_filter. The function should return
* %COGL_XLIB_FILTER_REMOVE if it wants to prevent further processing
* or %COGL_XLIB_FILTER_CONTINUE otherwise.
*/
typedef CoglXlibFilterReturn (* CoglXlibFilterFunc) (XEvent *xevent,
void *data);
#endif /* COGL_HAS_XLIB */
G_END_DECLS G_END_DECLS
#endif /* __COGL_TYPES_H__ */ #endif /* __COGL_TYPES_H__ */

View file

@ -37,7 +37,6 @@
#include "cogl-shader.h" #include "cogl-shader.h"
#include "cogl-texture.h" #include "cogl-texture.h"
#include "cogl-types.h" #include "cogl-types.h"
#include "cogl-handle.h"
#include "cogl-util.h" #include "cogl-util.h"
/* /*

82
cogl/cogl-xlib-private.h Normal file
View file

@ -0,0 +1,82 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010,2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_XLIB_PRIVATE_H
#define __COGL_XLIB_PRIVATE_H
#include "cogl/cogl.h"
#include <X11/Xlib.h>
typedef struct _CoglXlibTrapState CoglXlibTrapState;
struct _CoglXlibTrapState
{
/* These values are intended to be internal to
* _cogl_xlib_{un,}trap_errors but they need to be in the header so
* that the struct can be allocated on the stack */
int (* old_error_handler) (Display *, XErrorEvent *);
int trapped_error_code;
CoglXlibTrapState *old_state;
};
typedef struct _CoglXlibFilterClosure
{
CoglXlibFilterFunc func;
void *data;
} CoglXlibFilterClosure;
void
_cogl_xlib_query_damage_extension (void);
int
_cogl_xlib_get_damage_base (void);
void
_cogl_xlib_trap_errors (CoglXlibTrapState *state);
int
_cogl_xlib_untrap_errors (CoglXlibTrapState *state);
/*
* _cogl_xlib_add_filter:
*
* Adds a callback function that will receive all X11 events. The
* function can stop further processing of the event by return
* %COGL_XLIB_FILTER_REMOVE.
*/
void
_cogl_xlib_add_filter (CoglXlibFilterFunc func,
void *data);
/*
* _cogl_xlib_remove_filter:
*
* Removes a callback that was previously added with
* _cogl_xlib_add_filter().
*/
void
_cogl_xlib_remove_filter (CoglXlibFilterFunc func,
void *data);
#endif /* __COGL_XLIB_PRIVATE_H */

View file

@ -3,7 +3,7 @@
* *
* An object oriented GL/GLES Abstraction/Utility Layer * An object oriented GL/GLES Abstraction/Utility Layer
* *
* Copyright (C) 2010 Intel Corporation. * Copyright (C) 2010,2011 Intel Corporation.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -34,24 +34,36 @@
#include <cogl-handle.h> #include <cogl-handle.h>
#include <cogl-context-private.h> #include <cogl-context-private.h>
#include <cogl-framebuffer-private.h> #include <cogl-framebuffer-private.h>
#include <cogl-display-private.h>
#include <cogl-renderer-private.h>
#include <cogl-renderer-xlib-private.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/extensions/Xdamage.h>
#include "cogl-xlib.h" #include "cogl-xlib.h"
/* FIXME: when we remove the last X11 based Clutter backend then we
* will get rid of these functions and instead rely on the equivalent
* _cogl_renderer_xlib API
*/
/* This can't be in the Cogl context because it can be set before /* This can't be in the Cogl context because it can be set before
context is created */ context is created */
static Display *_cogl_xlib_display = NULL; static Display *_cogl_xlib_display = NULL;
CoglXlibFilterReturn CoglXlibFilterReturn
_cogl_xlib_handle_event (XEvent *xevent) cogl_xlib_handle_event (XEvent *xevent)
{ {
GSList *l; GSList *l;
_COGL_GET_CONTEXT (ctx, COGL_XLIB_FILTER_CONTINUE); _COGL_GET_CONTEXT (ctx, COGL_XLIB_FILTER_CONTINUE);
if (!ctx->stub_winsys)
return cogl_renderer_xlib_handle_event (ctx->display->renderer, xevent);
/* Pass the event on to all of the registered filters in turn */ /* Pass the event on to all of the registered filters in turn */
for (l = ctx->winsys.event_filters; l; l = l->next) for (l = ctx->event_filters; l; l = l->next)
{ {
CoglXlibFilterClosure *closure = l->data; CoglXlibFilterClosure *closure = l->data;
@ -70,10 +82,13 @@ _cogl_xlib_handle_event (XEvent *xevent)
} }
Display * Display *
_cogl_xlib_get_display (void) cogl_xlib_get_display (void)
{ {
_COGL_GET_CONTEXT (ctx, NULL); _COGL_GET_CONTEXT (ctx, NULL);
if (!ctx->stub_winsys)
return cogl_renderer_xlib_get_display (ctx->display->renderer);
/* _cogl_xlib_set_display should be called before this function */ /* _cogl_xlib_set_display should be called before this function */
g_assert (_cogl_xlib_display != NULL); g_assert (_cogl_xlib_display != NULL);
@ -81,7 +96,7 @@ _cogl_xlib_get_display (void)
} }
void void
_cogl_xlib_set_display (Display *display) cogl_xlib_set_display (Display *display)
{ {
/* This can only be called once before the Cogl context is created */ /* This can only be called once before the Cogl context is created */
g_assert (_cogl_xlib_display == NULL); g_assert (_cogl_xlib_display == NULL);
@ -91,29 +106,43 @@ _cogl_xlib_set_display (Display *display)
void void
_cogl_xlib_add_filter (CoglXlibFilterFunc func, _cogl_xlib_add_filter (CoglXlibFilterFunc func,
gpointer data) void *data)
{ {
CoglXlibFilterClosure *closure; CoglXlibFilterClosure *closure;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!ctx->stub_winsys)
{
cogl_renderer_xlib_add_filter (ctx->display->renderer,
func, data);
return;
}
closure = g_slice_new (CoglXlibFilterClosure); closure = g_slice_new (CoglXlibFilterClosure);
closure->func = func; closure->func = func;
closure->data = data; closure->data = data;
ctx->winsys.event_filters = ctx->event_filters =
g_slist_prepend (ctx->winsys.event_filters, closure); g_slist_prepend (ctx->event_filters, closure);
} }
void void
_cogl_xlib_remove_filter (CoglXlibFilterFunc func, _cogl_xlib_remove_filter (CoglXlibFilterFunc func,
gpointer data) void *data)
{ {
GSList *l, *prev = NULL; GSList *l, *prev = NULL;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
for (l = ctx->winsys.event_filters; l; prev = l, l = l->next) if (!ctx->stub_winsys)
{
cogl_renderer_xlib_remove_filter (ctx->display->renderer,
func, data);
return;
}
for (l = ctx->event_filters; l; prev = l, l = l->next)
{ {
CoglXlibFilterClosure *closure = l->data; CoglXlibFilterClosure *closure = l->data;
@ -123,8 +152,8 @@ _cogl_xlib_remove_filter (CoglXlibFilterFunc func,
if (prev) if (prev)
prev->next = g_slist_delete_link (prev->next, l); prev->next = g_slist_delete_link (prev->next, l);
else else
ctx->winsys.event_filters = ctx->event_filters =
g_slist_delete_link (ctx->winsys.event_filters, l); g_slist_delete_link (ctx->event_filters, l);
break; break;
} }
} }
@ -136,9 +165,9 @@ error_handler (Display *xdpy,
{ {
_COGL_GET_CONTEXT (ctxt, 0); _COGL_GET_CONTEXT (ctxt, 0);
g_assert (ctxt->winsys.trap_state); g_assert (ctxt->trap_state);
ctxt->winsys.trap_state->trapped_error_code = error->error_code; ctxt->trap_state->trapped_error_code = error->error_code;
return 0; return 0;
} }
@ -148,11 +177,17 @@ _cogl_xlib_trap_errors (CoglXlibTrapState *state)
{ {
_COGL_GET_CONTEXT (ctxt, NO_RETVAL); _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
if (!ctxt->stub_winsys)
{
_cogl_renderer_xlib_trap_errors (ctxt->display->renderer, state);
return;
}
state->trapped_error_code = 0; state->trapped_error_code = 0;
state->old_error_handler = XSetErrorHandler (error_handler); state->old_error_handler = XSetErrorHandler (error_handler);
state->old_state = ctxt->winsys.trap_state; state->old_state = ctxt->trap_state;
ctxt->winsys.trap_state = state; ctxt->trap_state = state;
} }
int int
@ -160,11 +195,44 @@ _cogl_xlib_untrap_errors (CoglXlibTrapState *state)
{ {
_COGL_GET_CONTEXT (ctxt, 0); _COGL_GET_CONTEXT (ctxt, 0);
g_assert (state == ctxt->winsys.trap_state); if (!ctxt->stub_winsys)
{
return _cogl_renderer_xlib_untrap_errors (ctxt->display->renderer, state);
}
g_assert (state == ctxt->trap_state);
XSetErrorHandler (state->old_error_handler); XSetErrorHandler (state->old_error_handler);
ctxt->winsys.trap_state = state->old_state; ctxt->trap_state = state->old_state;
return state->trapped_error_code; return state->trapped_error_code;
} }
void
_cogl_xlib_query_damage_extension (void)
{
int damage_error;
_COGL_GET_CONTEXT (ctxt, NO_RETVAL);
/* Check whether damage events are supported on this display */
if (!XDamageQueryExtension (cogl_xlib_get_display (),
&ctxt->damage_base,
&damage_error))
ctxt->damage_base = -1;
}
int
_cogl_xlib_get_damage_base (void)
{
_COGL_GET_CONTEXT (ctxt, -1);
if (!ctxt->stub_winsys)
{
CoglRendererX11 *x11_renderer = ctxt->display->renderer->winsys;
return x11_renderer->damage_base;
}
else
return ctxt->damage_base;
}

84
cogl/cogl-xlib.h Normal file
View file

@ -0,0 +1,84 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cogl/cogl.h> can be included directly."
#endif
#ifndef __COGL_XLIB_H__
#define __COGL_XLIB_H__
#include <cogl/cogl-types.h>
#include <X11/Xlib.h>
G_BEGIN_DECLS
/*
* cogl_xlib_get_display:
*
* Return value: the Xlib display that will be used by the Xlib winsys
* backend. The display needs to be set with _cogl_xlib_set_display()
* before this function is called.
*
* Stability: Unstable
*/
#define cogl_xlib_get_display cogl_xlib_get_display_EXP
Display *
cogl_xlib_get_display (void);
/*
* cogl_xlib_set_display:
*
* Sets the Xlib display that Cogl will use for the Xlib winsys
* backend. This function should eventually go away when Cogl gains a
* more complete winsys abstraction.
*
* Stability: Unstable
*/
#define cogl_xlib_set_display cogl_xlib_set_display_EXP
void
cogl_xlib_set_display (Display *display);
/*
* cogl_xlib_handle_event:
* @xevent: pointer to XEvent structure
*
* This function processes a single X event; it can be used to hook
* into external X event retrieval (for example that done by Clutter
* or GDK).
*
* Return value: #CoglXlibFilterReturn. %COGL_XLIB_FILTER_REMOVE
* indicates that Cogl has internally handled the event and the
* caller should do no further processing. %COGL_XLIB_FILTER_CONTINUE
* indicates that Cogl is either not interested in the event,
* or has used the event to update internal state without taking
* any exclusive action.
*
* Stability: Unstable
*/
#define cogl_xlib_handle_event cogl_xlib_handle_event_EXP
CoglXlibFilterReturn
cogl_xlib_handle_event (XEvent *xevent);
#endif /* __COGL_XLIB_H__ */

View file

@ -38,7 +38,7 @@
#include "cogl-context-private.h" #include "cogl-context-private.h"
#include "cogl-pipeline-private.h" #include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h" #include "cogl-pipeline-opengl-private.h"
#include "cogl-winsys.h" #include "cogl-winsys-private.h"
#include "cogl-framebuffer-private.h" #include "cogl-framebuffer-private.h"
#include "cogl-matrix-private.h" #include "cogl-matrix-private.h"
#include "cogl-journal-private.h" #include "cogl-journal-private.h"
@ -394,14 +394,6 @@ cogl_features_available (CoglFeatureFlags features)
return (ctx->feature_flags & features) == features; return (ctx->feature_flags & features) == features;
} }
gboolean
_cogl_features_available_private (CoglFeatureFlagsPrivate features)
{
_COGL_GET_CONTEXT (ctx, 0);
return (ctx->feature_flags_private & features) == features;
}
/* XXX: This function should either be replaced with one returning /* XXX: This function should either be replaced with one returning
* integers, or removed/deprecated and make the * integers, or removed/deprecated and make the
* _cogl_framebuffer_get_viewport* functions public. * _cogl_framebuffer_get_viewport* functions public.

View file

@ -67,7 +67,12 @@
#include <cogl/cogl-deprecated.h> #include <cogl/cogl-deprecated.h>
typedef struct _CoglFramebuffer CoglFramebuffer;
#if defined (COGL_ENABLE_EXPERIMENTAL_API) #if defined (COGL_ENABLE_EXPERIMENTAL_API)
#include <cogl/cogl-swap-chain.h>
#include <cogl/cogl-renderer.h>
#include <cogl/cogl-display.h>
#include <cogl/cogl-context.h> #include <cogl/cogl-context.h>
#include <cogl/cogl-buffer.h> #include <cogl/cogl-buffer.h>
#include <cogl/cogl-pixel-array.h> #include <cogl/cogl-pixel-array.h>
@ -79,6 +84,13 @@
#include <cogl/cogl-attribute.h> #include <cogl/cogl-attribute.h>
#include <cogl/cogl-primitive.h> #include <cogl/cogl-primitive.h>
#include <cogl/cogl-pipeline.h> #include <cogl/cogl-pipeline.h>
#include <cogl/cogl-framebuffer.h>
#ifdef COGL_HAS_XLIB
#include <cogl/cogl-xlib.h>
#endif
/* XXX: This will definitly go away once all the Clutter winsys
* code has been migrated down into Cogl! */
#include <cogl/cogl-clutter.h>
#endif #endif
G_BEGIN_DECLS G_BEGIN_DECLS
@ -90,8 +102,6 @@ G_BEGIN_DECLS
* General utility functions for COGL. * General utility functions for COGL.
*/ */
typedef struct _CoglFramebuffer CoglFramebuffer;
/** /**
* cogl_get_option_group: * cogl_get_option_group:
* *
@ -1245,44 +1255,6 @@ cogl_begin_gl (void);
void void
cogl_end_gl (void); cogl_end_gl (void);
/*
* Internal API available only to Clutter.
*
* These are typically only to deal with the poor seperation of
* responsabilities that currently exists between Clutter and Cogl.
* Eventually a lot of the backend code currently in Clutter will
* move down into Cogl and these functions will be removed.
*/
void
_cogl_destroy_context (void);
/*< private >*/
#define COGL_DRIVER_ERROR (_cogl_driver_error_quark ())
typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/
COGL_DRIVER_ERROR_UNKNOWN_VERSION,
COGL_DRIVER_ERROR_INVALID_VERSION
} CoglDriverError;
gboolean
_cogl_check_extension (const char *name, const char *ext);
void
_cogl_set_indirect_context (gboolean indirect);
gboolean
_cogl_check_driver_valid (GError **error);
GQuark
_cogl_driver_error_quark (void);
#ifdef COGL_ENABLE_EXPERIMENTAL_API
#define cogl_get_draw_framebuffer cogl_get_draw_framebuffer_EXP
CoglFramebuffer *
cogl_get_draw_framebuffer (void);
#endif
G_END_DECLS G_END_DECLS
#undef __COGL_H_INSIDE__ #undef __COGL_H_INSIDE__

View file

@ -0,0 +1,53 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2007,2008,2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_CONTEXT_DRIVER_H
#define __COGL_CONTEXT_DRIVER_H
#include "cogl.h"
#ifndef APIENTRY
#define APIENTRY
#endif
#define COGL_FEATURE_BEGIN(a, b, c, d, e, f, g)
#define COGL_FEATURE_FUNCTION(ret, name, args) \
ret (APIENTRY * pf_ ## name) args;
#define COGL_FEATURE_END()
typedef struct _CoglContextDriver
{
/* This defines a list of function pointers */
#include "cogl-feature-functions-gl.h"
GLint gl_max_program_temoraries_arb;
} CoglContextDriver;
#undef COGL_FEATURE_BEGIN
#undef COGL_FEATURE_FUNCTION
#undef COGL_FEATURE_END
#endif /* __COGL_CONTEXT_DRIVER_H */

View file

@ -29,6 +29,7 @@
#include "cogl.h" #include "cogl.h"
#include "cogl-private.h"
#include "cogl-internal.h" #include "cogl-internal.h"
#include "cogl-context-private.h" #include "cogl-context-private.h"
#include "cogl-feature-private.h" #include "cogl-feature-private.h"
@ -95,7 +96,7 @@ _cogl_get_gl_version (int *major_out, int *minor_out)
} }
gboolean gboolean
_cogl_check_driver_valid (GError **error) _cogl_gl_check_version (GError **error)
{ {
int major, minor; int major, minor;
const char *gl_extensions; const char *gl_extensions;
@ -161,7 +162,7 @@ _cogl_check_driver_valid (GError **error)
namespaces, extension_names, \ namespaces, extension_names, \
feature_flags, feature_flags_private) \ feature_flags, feature_flags_private) \
{ min_gl_major, min_gl_minor, namespaces, \ { min_gl_major, min_gl_minor, namespaces, \
extension_names, feature_flags, feature_flags_private, \ extension_names, feature_flags, feature_flags_private, 0, \
cogl_feature_ ## name ## _funcs }, cogl_feature_ ## name ## _funcs },
#undef COGL_FEATURE_FUNCTION #undef COGL_FEATURE_FUNCTION
#define COGL_FEATURE_FUNCTION(ret, name, args) #define COGL_FEATURE_FUNCTION(ret, name, args)
@ -182,23 +183,35 @@ static const CoglFeatureData cogl_feature_data[] =
#define COGL_FEATURE_END() #define COGL_FEATURE_END()
static void static void
initialize_context_driver (CoglContext *context) initialize_function_table (CoglContext *context)
{ {
#include "cogl-feature-functions-gl.h" #include "cogl-feature-functions-gl.h"
} }
/* Query the GL extensions and lookup the corresponding function
* pointers. Theoretically the list of extensions can change for
* different GL contexts so it is the winsys backend's responsiblity
* to know when to re-query the GL extensions. */
void void
_cogl_gl_context_init (CoglContext *context) _cogl_gl_update_features (CoglContext *context)
{ {
CoglFeatureFlags flags = 0; CoglFeatureFlags flags = 0;
CoglFeatureFlagsPrivate flags_private = 0;
const char *gl_extensions; const char *gl_extensions;
int max_clip_planes = 0; int max_clip_planes = 0;
int num_stencil_bits = 0; int num_stencil_bits = 0;
int gl_major = 0, gl_minor = 0; int gl_major = 0, gl_minor = 0;
int i; int i;
initialize_context_driver (context); COGL_NOTE (WINSYS,
"Checking features\n"
" GL_VENDOR: %s\n"
" GL_RENDERER: %s\n"
" GL_VERSION: %s\n"
" GL_EXTENSIONS: %s",
glGetString (GL_VENDOR),
glGetString (GL_RENDERER),
glGetString (GL_VERSION),
glGetString (GL_EXTENSIONS));
_cogl_get_gl_version (&gl_major, &gl_minor); _cogl_get_gl_version (&gl_major, &gl_minor);
@ -235,16 +248,15 @@ _cogl_gl_context_init (CoglContext *context)
if (max_clip_planes >= 4) if (max_clip_planes >= 4)
flags |= COGL_FEATURE_FOUR_CLIP_PLANES; flags |= COGL_FEATURE_FOUR_CLIP_PLANES;
initialize_function_table (context);
for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++) for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++)
if (_cogl_feature_check ("GL", cogl_feature_data + i, if (_cogl_feature_check ("GL", cogl_feature_data + i,
gl_major, gl_minor, gl_major, gl_minor,
gl_extensions)) gl_extensions,
{ context))
flags |= cogl_feature_data[i].feature_flags; flags |= cogl_feature_data[i].feature_flags;
flags_private |= cogl_feature_data[i].feature_flags_private;
}
/* Cache features */ /* Cache features */
context->feature_flags = flags; context->feature_flags |= flags;
context->feature_flags_private = flags_private;
} }

View file

@ -0,0 +1,52 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2007,2008,2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_CONTEXT_DRIVER_H
#define __COGL_CONTEXT_DRIVER_H
#include "cogl.h"
#ifndef APIENTRY
#define APIENTRY
#endif
#define COGL_FEATURE_BEGIN(a, b, c, d, e, f, g)
#define COGL_FEATURE_FUNCTION(ret, name, args) \
ret (APIENTRY * pf_ ## name) args;
#define COGL_FEATURE_END()
typedef struct _CoglContextDriver
{
/* This defines a list of function pointers */
#include "cogl-feature-functions-gles.h"
} CoglContextDriver;
#undef COGL_FEATURE_BEGIN
#undef COGL_FEATURE_FUNCTION
#undef COGL_FEATURE_END
#endif /* __COGL_CONTEXT_DRIVER_H */

View file

@ -33,7 +33,7 @@
#include "cogl-feature-private.h" #include "cogl-feature-private.h"
gboolean gboolean
_cogl_check_driver_valid (GError **error) _cogl_gl_check_version (GError **error)
{ {
/* The GLES backend doesn't have any particular version requirements */ /* The GLES backend doesn't have any particular version requirements */
return TRUE; return TRUE;
@ -58,7 +58,7 @@ _cogl_check_driver_valid (GError **error)
namespaces, extension_names, \ namespaces, extension_names, \
feature_flags, feature_flags_private) \ feature_flags, feature_flags_private) \
{ min_gl_major, min_gl_minor, namespaces, \ { min_gl_major, min_gl_minor, namespaces, \
extension_names, feature_flags, feature_flags_private, \ extension_names, feature_flags, feature_flags_private, 0, \
cogl_feature_ ## name ## _funcs }, cogl_feature_ ## name ## _funcs },
#undef COGL_FEATURE_FUNCTION #undef COGL_FEATURE_FUNCTION
#define COGL_FEATURE_FUNCTION(ret, name, args) #define COGL_FEATURE_FUNCTION(ret, name, args)
@ -74,36 +74,44 @@ static const CoglFeatureData cogl_feature_data[] =
#define COGL_FEATURE_BEGIN(a, b, c, d, e, f, g) #define COGL_FEATURE_BEGIN(a, b, c, d, e, f, g)
#undef COGL_FEATURE_FUNCTION #undef COGL_FEATURE_FUNCTION
#define COGL_FEATURE_FUNCTION(ret, name, args) \ #define COGL_FEATURE_FUNCTION(ret, name, args) \
_context->drv.pf_ ## name = NULL; context->drv.pf_ ## name = NULL;
#undef COGL_FEATURE_END #undef COGL_FEATURE_END
#define COGL_FEATURE_END() #define COGL_FEATURE_END()
static void static void
initialize_context_driver (CoglContext *context) initialize_function_table (CoglContext *context)
{ {
#include "cogl-feature-functions-gles.h" #include "cogl-feature-functions-gles.h"
} }
/* Query the GL extensions and lookup the corresponding function
* pointers. Theoretically the list of extensions can change for
* different GL contexts so it is the winsys backend's responsiblity
* to know when to re-query the GL extensions. */
void void
_cogl_gl_context_init (CoglContext *context) _cogl_gl_update_features (CoglContext *context)
{ {
CoglFeatureFlags flags = 0; CoglFeatureFlags flags = 0;
const char *gl_extensions;
#ifndef HAVE_COGL_GLES2 #ifndef HAVE_COGL_GLES2
int max_clip_planes = 0; int max_clip_planes = 0;
#endif #endif
int num_stencil_bits = 0; int num_stencil_bits = 0;
const char *gl_extensions;
int i; int i;
initialize_context_driver (context); COGL_NOTE (WINSYS,
"Checking features\n"
" GL_VENDOR: %s\n"
" GL_RENDERER: %s\n"
" GL_VERSION: %s\n"
" GL_EXTENSIONS: %s",
glGetString (GL_VENDOR),
glGetString (GL_RENDERER),
glGetString (GL_VERSION),
glGetString (GL_EXTENSIONS));
gl_extensions = (const char*) glGetString (GL_EXTENSIONS); gl_extensions = (const char*) glGetString (GL_EXTENSIONS);
for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++)
if (_cogl_feature_check ("GL", cogl_feature_data + i,
0, 0,
gl_extensions))
flags |= cogl_feature_data[i].feature_flags;
GE( glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) ); GE( glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) );
/* We need at least three stencil bits to combine clips */ /* We need at least three stencil bits to combine clips */
@ -128,7 +136,15 @@ _cogl_gl_context_init (CoglContext *context)
/* Both GLES 1.1 and GLES 2.0 support point sprites in core */ /* Both GLES 1.1 and GLES 2.0 support point sprites in core */
flags |= COGL_FEATURE_POINT_SPRITE; flags |= COGL_FEATURE_POINT_SPRITE;
/* Cache features */ initialize_function_table (context);
context->feature_flags = flags;
}
for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++)
if (_cogl_feature_check ("GL", cogl_feature_data + i,
0, 0,
gl_extensions,
context))
flags |= cogl_feature_data[i].feature_flags;
/* Cache features */
context->feature_flags |= flags;
}

View file

@ -1,152 +0,0 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef COGL_HAS_GLX_SUPPORT
#include <GL/glx.h>
#endif
#include "cogl-context-private.h"
#include "cogl-feature-private.h"
/* Define a set of arrays containing the functions required from GL
for each winsys feature */
#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \
feature_flags, feature_flags_private) \
static const CoglFeatureFunction \
cogl_winsys_feature_ ## name ## _funcs[] = {
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
{ G_STRINGIFY (name), G_STRUCT_OFFSET (CoglContext, winsys.pf_ ## name) },
#define COGL_WINSYS_FEATURE_END() \
{ NULL, 0 }, \
};
#include "cogl-winsys-feature-functions.h"
/* Define an array of features */
#undef COGL_WINSYS_FEATURE_BEGIN
#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \
feature_flags, feature_flags_private) \
{ 255, 255, namespaces, extension_names, \
feature_flags, feature_flags_private, \
cogl_winsys_feature_ ## name ## _funcs },
#undef COGL_WINSYS_FEATURE_FUNCTION
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args)
#undef COGL_WINSYS_FEATURE_END
#define COGL_WINSYS_FEATURE_END()
static const CoglFeatureData cogl_winsys_feature_data[] =
{
#include "cogl-winsys-feature-functions.h"
/* This stub is just here so that if the header is empty then we
won't end up declaring an empty array */
{ 0, }
};
#define COGL_WINSYS_N_FEATURES (G_N_ELEMENTS (cogl_winsys_feature_data) - 1)
static const char *
_cogl_get_winsys_extensions (void)
{
#ifdef COGL_HAS_GLX_SUPPORT
Display *display = _cogl_xlib_get_display ();
return glXQueryExtensionsString (display, DefaultScreen (display));
#else
return "";
#endif
}
static void
_cogl_winsys_features_init (CoglContext *context)
{
CoglWinsysFeatureFlags flags = 0;
const char *extensions = _cogl_get_winsys_extensions ();
int i;
for (i = 0; i < COGL_WINSYS_N_FEATURES; i++)
if (_cogl_feature_check ("GLX", cogl_winsys_feature_data + i, 0, 0,
extensions))
flags |= cogl_winsys_feature_data[i].feature_flags;
context->winsys.feature_flags = flags;
}
void
_cogl_create_context_winsys (CoglContext *context)
{
#ifdef COGL_HAS_XLIB_SUPPORT
{
Display *display = _cogl_xlib_get_display ();
int damage_error;
/* Check whether damage events are supported on this display */
if (!XDamageQueryExtension (display,
&context->winsys.damage_base,
&damage_error))
context->winsys.damage_base = -1;
context->winsys.event_filters = NULL;
context->winsys.trap_state = NULL;
}
#endif
#ifdef COGL_HAS_GLX_SUPPORT
{
int i;
for (i = 0; i < COGL_WINSYS_N_CACHED_CONFIGS; i++)
context->winsys.glx_cached_configs[i].depth = -1;
context->winsys.rectangle_state = COGL_WINSYS_RECTANGLE_STATE_UNKNOWN;
}
#endif
_cogl_winsys_features_init (context);
}
#ifdef COGL_HAS_XLIB_SUPPORT
#include "cogl-xlib.h"
static void
free_xlib_filter_closure (gpointer data, gpointer user_data)
{
g_slice_free (CoglXlibFilterClosure, data);
}
#endif
void
_cogl_destroy_context_winsys (CoglContext *context)
{
#ifdef COGL_HAS_XLIB_SUPPORT
g_slist_foreach (context->winsys.event_filters,
free_xlib_filter_closure, NULL);
g_slist_free (context->winsys.event_filters);
#endif
}

View file

@ -1,118 +0,0 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_CONTEXT_WINSYS_H
#define __COGL_CONTEXT_WINSYS_H
#ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/extensions/Xdamage.h>
#include <X11/Xlib.h>
#endif
#ifdef COGL_HAS_GLX_SUPPORT
#include <GL/glx.h>
#endif
typedef enum
{
COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP = 1
} CoglWinsysFeatureFlags;
#ifdef COGL_HAS_XLIB_SUPPORT
typedef struct _CoglXlibTrapState CoglXlibTrapState;
struct _CoglXlibTrapState
{
/* These values are intended to be internal to
_cogl_xlib_{un,}trap_errors but they need to be in the header so
that the struct can be allocated on the stack */
int (* old_error_handler) (Display *, XErrorEvent *);
int trapped_error_code;
CoglXlibTrapState *old_state;
};
#endif /* COGL_HAS_XLIB_SUPPORT */
#ifdef COGL_HAS_GLX_SUPPORT
typedef struct
{
/* This will be -1 if there is no cached config in this slot */
int depth;
gboolean found;
GLXFBConfig fb_config;
gboolean can_mipmap;
} CoglWinsysCachedConfig;
#define COGL_WINSYS_N_CACHED_CONFIGS 3
typedef enum
{
COGL_WINSYS_RECTANGLE_STATE_UNKNOWN,
COGL_WINSYS_RECTANGLE_STATE_DISABLE,
COGL_WINSYS_RECTANGLE_STATE_ENABLE
} CoglWinsysRectangleState;
#endif /* COGL_HAS_GLX_SUPPORT */
typedef struct
{
/* These are specific to winsys backends supporting Xlib. This
should probably eventually be moved into a separate file specific
to Xlib when Cogl gains a more complete winsys abstraction */
#ifdef COGL_HAS_XLIB_SUPPORT
/* This will be -1 if the damage extension is not support, or it
will be the event number offset for damage events if it is */
int damage_base;
/* List of callback functions that will be given every Xlib event */
GSList *event_filters;
/* Current top of the XError trap state stack. The actual memory for
these is expected to be allocated on the stack by the caller */
CoglXlibTrapState *trap_state;
#endif
#ifdef COGL_HAS_GLX_SUPPORT
CoglWinsysCachedConfig glx_cached_configs[COGL_WINSYS_N_CACHED_CONFIGS];
/* Whether the texture rectangle extension should be used */
CoglWinsysRectangleState rectangle_state;
#endif
/* Function pointers for winsys specific extensions */
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e)
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
ret (APIENTRY * pf_ ## name) args;
#define COGL_WINSYS_FEATURE_END()
#include "cogl-winsys-feature-functions.h"
#undef COGL_WINSYS_FEATURE_BEGIN
#undef COGL_WINSYS_FEATURE_FUNCTION
#undef COGL_WINSYS_FEATURE_END
CoglWinsysFeatureFlags feature_flags;
} CoglContextWinsys;
#endif /* __COGL_CONTEXT_WINSYS_H */

View file

@ -42,7 +42,11 @@
#include "cogl-texture-rectangle-private.h" #include "cogl-texture-rectangle-private.h"
#include "cogl-context-private.h" #include "cogl-context-private.h"
#include "cogl-handle.h" #include "cogl-handle.h"
#include "cogl-winsys-xlib.h" #if COGL_HAS_GLX_SUPPORT
#include "cogl-display-glx-private.h"
#include "cogl-renderer-private.h"
#include "cogl-renderer-glx-private.h"
#endif
#include "cogl-pipeline-opengl-private.h" #include "cogl-pipeline-opengl-private.h"
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -55,9 +59,6 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#define glXBindTexImage ctx->winsys.pf_glXBindTexImage
#define glXReleaseTexImage ctx->winsys.pf_glXReleaseTexImage
static void _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap); static void _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap);
COGL_TEXTURE_DEFINE (TexturePixmapX11, texture_pixmap_x11); COGL_TEXTURE_DEFINE (TexturePixmapX11, texture_pixmap_x11);
@ -112,7 +113,7 @@ process_damage_event (CoglTexturePixmapX11 *tex_pixmap,
_COGL_GET_CONTEXT (ctxt, NO_RETVAL); _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
display = _cogl_xlib_get_display (); display = cogl_xlib_get_display ();
COGL_NOTE (TEXTURE_PIXMAP, "Damage event received for %p", tex_pixmap); COGL_NOTE (TEXTURE_PIXMAP, "Damage event received for %p", tex_pixmap);
@ -206,10 +207,12 @@ static CoglXlibFilterReturn
_cogl_texture_pixmap_x11_filter (XEvent *event, gpointer data) _cogl_texture_pixmap_x11_filter (XEvent *event, gpointer data)
{ {
CoglTexturePixmapX11 *tex_pixmap = data; CoglTexturePixmapX11 *tex_pixmap = data;
int damage_base;
_COGL_GET_CONTEXT (ctxt, COGL_XLIB_FILTER_CONTINUE); _COGL_GET_CONTEXT (ctxt, COGL_XLIB_FILTER_CONTINUE);
if (event->type == ctxt->winsys.damage_base + XDamageNotify) damage_base = _cogl_xlib_get_damage_base ();
if (event->type == damage_base + XDamageNotify)
{ {
XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) event; XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) event;
@ -233,21 +236,23 @@ get_fbconfig_for_depth (unsigned int depth,
int db, stencil, alpha, mipmap, rgba, value; int db, stencil, alpha, mipmap, rgba, value;
int spare_cache_slot = 0; int spare_cache_slot = 0;
gboolean found = FALSE; gboolean found = FALSE;
CoglDisplayGLX *glx_display;
_COGL_GET_CONTEXT (ctxt, FALSE); _COGL_GET_CONTEXT (ctxt, FALSE);
glx_display = ctxt->display->winsys;
/* Check if we've already got a cached config for this depth */ /* Check if we've already got a cached config for this depth */
for (i = 0; i < COGL_WINSYS_N_CACHED_CONFIGS; i++) for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++)
if (ctxt->winsys.glx_cached_configs[i].depth == -1) if (glx_display->glx_cached_configs[i].depth == -1)
spare_cache_slot = i; spare_cache_slot = i;
else if (ctxt->winsys.glx_cached_configs[i].depth == depth) else if (glx_display->glx_cached_configs[i].depth == depth)
{ {
*fbconfig_ret = ctxt->winsys.glx_cached_configs[i].fb_config; *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config;
*can_mipmap_ret = ctxt->winsys.glx_cached_configs[i].can_mipmap; *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap;
return ctxt->winsys.glx_cached_configs[i].found; return glx_display->glx_cached_configs[i].found;
} }
dpy = _cogl_xlib_get_display (); dpy = cogl_xlib_get_display ();
fbconfigs = glXGetFBConfigs (dpy, DefaultScreen (dpy), fbconfigs = glXGetFBConfigs (dpy, DefaultScreen (dpy),
&n_elements); &n_elements);
@ -349,10 +354,10 @@ get_fbconfig_for_depth (unsigned int depth,
if (n_elements) if (n_elements)
XFree (fbconfigs); XFree (fbconfigs);
ctxt->winsys.glx_cached_configs[spare_cache_slot].depth = depth; glx_display->glx_cached_configs[spare_cache_slot].depth = depth;
ctxt->winsys.glx_cached_configs[spare_cache_slot].found = found; glx_display->glx_cached_configs[spare_cache_slot].found = found;
ctxt->winsys.glx_cached_configs[spare_cache_slot].fb_config = *fbconfig_ret; glx_display->glx_cached_configs[spare_cache_slot].fb_config = *fbconfig_ret;
ctxt->winsys.glx_cached_configs[spare_cache_slot].can_mipmap = mipmap; glx_display->glx_cached_configs[spare_cache_slot].can_mipmap = mipmap;
return found; return found;
} }
@ -362,7 +367,7 @@ should_use_rectangle (void)
{ {
_COGL_GET_CONTEXT (ctxt, FALSE); _COGL_GET_CONTEXT (ctxt, FALSE);
if (ctxt->winsys.rectangle_state == COGL_WINSYS_RECTANGLE_STATE_UNKNOWN) if (ctxt->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_UNKNOWN)
{ {
if (cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE)) if (cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE))
{ {
@ -378,7 +383,7 @@ should_use_rectangle (void)
the env var is set to 'allow' or not set and NPOTs textures the env var is set to 'allow' or not set and NPOTs textures
are not available */ are not available */
ctxt->winsys.rectangle_state = ctxt->rectangle_state =
cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) ? cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) ?
COGL_WINSYS_RECTANGLE_STATE_DISABLE : COGL_WINSYS_RECTANGLE_STATE_DISABLE :
COGL_WINSYS_RECTANGLE_STATE_ENABLE; COGL_WINSYS_RECTANGLE_STATE_ENABLE;
@ -389,10 +394,10 @@ should_use_rectangle (void)
(rect_env = g_getenv ("CLUTTER_PIXMAP_TEXTURE_RECTANGLE"))) (rect_env = g_getenv ("CLUTTER_PIXMAP_TEXTURE_RECTANGLE")))
{ {
if (g_ascii_strcasecmp (rect_env, "force") == 0) if (g_ascii_strcasecmp (rect_env, "force") == 0)
ctxt->winsys.rectangle_state = ctxt->rectangle_state =
COGL_WINSYS_RECTANGLE_STATE_ENABLE; COGL_WINSYS_RECTANGLE_STATE_ENABLE;
else if (g_ascii_strcasecmp (rect_env, "disable") == 0) else if (g_ascii_strcasecmp (rect_env, "disable") == 0)
ctxt->winsys.rectangle_state = ctxt->rectangle_state =
COGL_WINSYS_RECTANGLE_STATE_DISABLE; COGL_WINSYS_RECTANGLE_STATE_DISABLE;
else if (g_ascii_strcasecmp (rect_env, "allow")) else if (g_ascii_strcasecmp (rect_env, "allow"))
g_warning ("Unknown value for COGL_PIXMAP_TEXTURE_RECTANGLE, " g_warning ("Unknown value for COGL_PIXMAP_TEXTURE_RECTANGLE, "
@ -400,10 +405,10 @@ should_use_rectangle (void)
} }
} }
else else
ctxt->winsys.rectangle_state = COGL_WINSYS_RECTANGLE_STATE_DISABLE; ctxt->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_DISABLE;
} }
return ctxt->winsys.rectangle_state == COGL_WINSYS_RECTANGLE_STATE_ENABLE; return ctxt->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_ENABLE;
} }
static void static void
@ -425,11 +430,10 @@ try_create_glx_pixmap (CoglTexturePixmapX11 *tex_pixmap,
tex_pixmap->pixmap_bound = FALSE; tex_pixmap->pixmap_bound = FALSE;
tex_pixmap->glx_pixmap = None; tex_pixmap->glx_pixmap = None;
if ((ctxt->winsys.feature_flags & if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP))
COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP) == 0)
return; return;
dpy = _cogl_xlib_get_display (); dpy = cogl_xlib_get_display ();
if (!get_fbconfig_for_depth (tex_pixmap->depth, &fb_config, if (!get_fbconfig_for_depth (tex_pixmap->depth, &fb_config,
&tex_pixmap->glx_can_mipmap)) &tex_pixmap->glx_can_mipmap))
@ -507,7 +511,7 @@ set_damage_object_internal (CoglTexturePixmapX11 *tex_pixmap,
if (tex_pixmap->damage_owned) if (tex_pixmap->damage_owned)
{ {
XDamageDestroy (_cogl_xlib_get_display (), tex_pixmap->damage); XDamageDestroy (cogl_xlib_get_display (), tex_pixmap->damage);
tex_pixmap->damage_owned = FALSE; tex_pixmap->damage_owned = FALSE;
} }
} }
@ -524,12 +528,13 @@ cogl_texture_pixmap_x11_new (guint32 pixmap,
gboolean automatic_updates) gboolean automatic_updates)
{ {
CoglTexturePixmapX11 *tex_pixmap = g_new (CoglTexturePixmapX11, 1); CoglTexturePixmapX11 *tex_pixmap = g_new (CoglTexturePixmapX11, 1);
Display *display = _cogl_xlib_get_display (); Display *display = cogl_xlib_get_display ();
Window pixmap_root_window; Window pixmap_root_window;
int pixmap_x, pixmap_y; int pixmap_x, pixmap_y;
unsigned int pixmap_border_width; unsigned int pixmap_border_width;
CoglTexture *tex = COGL_TEXTURE (tex_pixmap); CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
XWindowAttributes window_attributes; XWindowAttributes window_attributes;
int damage_base;
_COGL_GET_CONTEXT (ctxt, COGL_INVALID_HANDLE); _COGL_GET_CONTEXT (ctxt, COGL_INVALID_HANDLE);
@ -565,7 +570,8 @@ cogl_texture_pixmap_x11_new (guint32 pixmap,
/* If automatic updates are requested and the Xlib connection /* If automatic updates are requested and the Xlib connection
supports damage events then we'll register a damage object on the supports damage events then we'll register a damage object on the
pixmap */ pixmap */
if (automatic_updates && ctxt->winsys.damage_base >= 0) damage_base = _cogl_xlib_get_damage_base ();
if (automatic_updates && damage_base >= 0)
{ {
Damage damage = XDamageCreate (display, Damage damage = XDamageCreate (display,
pixmap, pixmap,
@ -601,7 +607,7 @@ try_alloc_shm (CoglTexturePixmapX11 *tex_pixmap)
XImage *dummy_image; XImage *dummy_image;
Display *display; Display *display;
display = _cogl_xlib_get_display (); display = cogl_xlib_get_display ();
if (!XShmQueryExtension (display)) if (!XShmQueryExtension (display))
return; return;
@ -709,13 +715,15 @@ cogl_texture_pixmap_x11_set_damage_object (CoglHandle handle,
report_level) report_level)
{ {
CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle); CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle);
int damage_base;
_COGL_GET_CONTEXT (ctxt, NO_RETVAL); _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
if (!cogl_is_texture_pixmap_x11 (tex_pixmap)) if (!cogl_is_texture_pixmap_x11 (tex_pixmap))
return; return;
if (ctxt->winsys.damage_base >= 0) damage_base = _cogl_xlib_get_damage_base ();
if (damage_base >= 0)
set_damage_object_internal (tex_pixmap, damage, report_level); set_damage_object_internal (tex_pixmap, damage, report_level);
} }
@ -728,7 +736,7 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
int src_x, src_y; int src_x, src_y;
int x, y, width, height; int x, y, width, height;
display = _cogl_xlib_get_display (); display = cogl_xlib_get_display ();
/* If the damage region is empty then there's nothing to do */ /* If the damage region is empty then there's nothing to do */
if (tex_pixmap->damage_rect.x2 == tex_pixmap->damage_rect.x1) if (tex_pixmap->damage_rect.x2 == tex_pixmap->damage_rect.x1)
@ -889,11 +897,14 @@ _cogl_texture_pixmap_x11_free_glx_pixmap (CoglTexturePixmapX11 *tex_pixmap)
if (tex_pixmap->glx_pixmap) if (tex_pixmap->glx_pixmap)
{ {
CoglXlibTrapState trap_state; CoglXlibTrapState trap_state;
CoglRendererGLX *glx_renderer;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
glx_renderer = ctx->display->renderer->winsys;
if (tex_pixmap->pixmap_bound) if (tex_pixmap->pixmap_bound)
glXReleaseTexImage (_cogl_xlib_get_display (), tex_pixmap->glx_pixmap, glx_renderer->pf_glXReleaseTexImage (cogl_xlib_get_display (),
tex_pixmap->glx_pixmap,
GLX_FRONT_LEFT_EXT); GLX_FRONT_LEFT_EXT);
/* FIXME - we need to trap errors and synchronize here because /* FIXME - we need to trap errors and synchronize here because
@ -913,8 +924,8 @@ _cogl_texture_pixmap_x11_free_glx_pixmap (CoglTexturePixmapX11 *tex_pixmap)
* http://bugzilla.clutter-project.org/show_bug.cgi?id=2324 * http://bugzilla.clutter-project.org/show_bug.cgi?id=2324
*/ */
_cogl_xlib_trap_errors (&trap_state); _cogl_xlib_trap_errors (&trap_state);
glXDestroyPixmap (_cogl_xlib_get_display (), tex_pixmap->glx_pixmap); glXDestroyPixmap (cogl_xlib_get_display (), tex_pixmap->glx_pixmap);
XSync (_cogl_xlib_get_display (), False); XSync (cogl_xlib_get_display (), False);
_cogl_xlib_untrap_errors (&trap_state); _cogl_xlib_untrap_errors (&trap_state);
tex_pixmap->glx_pixmap = None; tex_pixmap->glx_pixmap = None;
@ -927,8 +938,10 @@ _cogl_texture_pixmap_x11_update_glx_texture (CoglTexturePixmapX11 *tex_pixmap,
gboolean needs_mipmap) gboolean needs_mipmap)
{ {
gboolean ret = TRUE; gboolean ret = TRUE;
CoglRendererGLX *glx_renderer;
_COGL_GET_CONTEXT (ctx, FALSE); _COGL_GET_CONTEXT (ctx, FALSE);
glx_renderer = ctx->display->renderer->winsys;
/* If we don't have a GLX pixmap then fallback */ /* If we don't have a GLX pixmap then fallback */
if (tex_pixmap->glx_pixmap == None) if (tex_pixmap->glx_pixmap == None)
@ -1031,11 +1044,11 @@ _cogl_texture_pixmap_x11_update_glx_texture (CoglTexturePixmapX11 *tex_pixmap,
GE( _cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE) ); GE( _cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE) );
if (tex_pixmap->pixmap_bound) if (tex_pixmap->pixmap_bound)
glXReleaseTexImage (_cogl_xlib_get_display (), glx_renderer->pf_glXReleaseTexImage (cogl_xlib_get_display (),
tex_pixmap->glx_pixmap, tex_pixmap->glx_pixmap,
GLX_FRONT_LEFT_EXT); GLX_FRONT_LEFT_EXT);
glXBindTexImage (_cogl_xlib_get_display (), glx_renderer->pf_glXBindTexImage (cogl_xlib_get_display (),
tex_pixmap->glx_pixmap, tex_pixmap->glx_pixmap,
GLX_FRONT_LEFT_EXT, GLX_FRONT_LEFT_EXT,
NULL); NULL);
@ -1373,7 +1386,7 @@ _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
if (tex_pixmap->shm_info.shmid != -1) if (tex_pixmap->shm_info.shmid != -1)
{ {
XShmDetach (_cogl_xlib_get_display (), &tex_pixmap->shm_info); XShmDetach (cogl_xlib_get_display (), &tex_pixmap->shm_info);
shmdt (tex_pixmap->shm_info.shmaddr); shmdt (tex_pixmap->shm_info.shmaddr);
shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0); shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0);
} }

View file

@ -1,45 +0,0 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
/* This can be included multiple times with different definitions for
the COGL_WINSYS_FEATURE_* functions */
#ifdef COGL_HAS_GLX_SUPPORT
COGL_WINSYS_FEATURE_BEGIN (texture_from_pixmap,
"EXT\0",
"texture_from_pixmap\0",
COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP,
0)
COGL_WINSYS_FEATURE_FUNCTION (void, glXBindTexImage,
(Display *display,
GLXDrawable drawable,
int buffer,
int *attribList))
COGL_WINSYS_FEATURE_FUNCTION (void, glXReleaseTexImage,
(Display *display,
GLXDrawable drawable,
int buffer))
COGL_WINSYS_FEATURE_END ()
#endif

View file

@ -0,0 +1,105 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*/
/* This can be included multiple times with different definitions for
* the COGL_WINSYS_FEATURE_* functions.
*/
/* Macro prototypes:
* COGL_WINSYS_FEATURE_BEGIN (name, namespaces, extension_names,
* implied_public_feature_flags,
* implied_private_feature_flags,
* implied_winsys_feature)
* COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name,
* (arguments))
* ...
* COGL_WINSYS_FEATURE_END ()
*
* Note: You can list multiple namespace and extension names if the
* corresponding _FEATURE_FUNCTIONS have the same semantics accross
* the different extension variants.
*
* XXX: NB: Don't add a trailing semicolon when using these macros
*/
COGL_WINSYS_FEATURE_BEGIN (texture_from_pixmap,
"EXT\0",
"texture_from_pixmap\0",
0,
0,
COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP)
COGL_WINSYS_FEATURE_FUNCTION (void, glXBindTexImage,
(Display *display,
GLXDrawable drawable,
int buffer,
int *attribList))
COGL_WINSYS_FEATURE_FUNCTION (void, glXReleaseTexImage,
(Display *display,
GLXDrawable drawable,
int buffer))
COGL_WINSYS_FEATURE_END ()
COGL_WINSYS_FEATURE_BEGIN (video_sync,
"SGI\0",
"video_sync\0",
0,
0,
COGL_WINSYS_FEATURE_VBLANK_COUNTER)
COGL_WINSYS_FEATURE_FUNCTION (int, glXGetVideoSync,
(unsigned int *count))
COGL_WINSYS_FEATURE_FUNCTION (int, glXWaitVideoSync,
(int divisor,
int remainder,
unsigned int *count))
COGL_WINSYS_FEATURE_END ()
COGL_WINSYS_FEATURE_BEGIN (swap_control,
"SGI\0",
"swap_control\0",
0,
0,
COGL_WINSYS_FEATURE_SWAP_THROTTLE)
COGL_WINSYS_FEATURE_FUNCTION (int, glXSwapInterval,
(int interval))
COGL_WINSYS_FEATURE_END ()
COGL_WINSYS_FEATURE_BEGIN (copy_sub_buffer,
"MESA\0",
"copy_sub_buffer\0",
0,
0,
0)
COGL_WINSYS_FEATURE_FUNCTION (void, glXCopySubBuffer,
(Display *dpy,
GLXDrawable drawable,
int x, int y, int width, int height))
COGL_WINSYS_FEATURE_END ()
COGL_WINSYS_FEATURE_BEGIN (swap_event,
"INTEL\0",
"swap_event\0",
0,
0,
COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT)
COGL_WINSYS_FEATURE_END ()

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,95 @@
#ifndef __COGL_WINSYS_PRIVATE_H #ifndef __COGL_WINSYS_PRIVATE_H
#define __COGL_WINSYS_PRIVATE_H #define __COGL_WINSYS_PRIVATE_H
#include "cogl-framebuffer-private.h"
#ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xutil.h>
#endif
GQuark
_cogl_winsys_error_quark (void);
#define COGL_WINSYS_ERROR (_cogl_winsys_error_quark ())
typedef enum { /*< prefix=COGL_WINSYS_ERROR >*/
COGL_WINSYS_ERROR_INIT,
COGL_WINSYS_ERROR_CREATE_CONTEXT,
COGL_WINSYS_ERROR_CREATE_ONSCREEN,
} CoglWinsysError;
typedef enum
{
COGL_WINSYS_RECTANGLE_STATE_UNKNOWN,
COGL_WINSYS_RECTANGLE_STATE_DISABLE,
COGL_WINSYS_RECTANGLE_STATE_ENABLE
} CoglWinsysRectangleState;
CoglFuncPtr CoglFuncPtr
_cogl_winsys_get_proc_address (const char *name); _cogl_winsys_get_proc_address (const char *name);
gboolean
_cogl_winsys_renderer_connect (CoglRenderer *renderer,
GError **error);
void
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer);
gboolean
_cogl_winsys_display_setup (CoglDisplay *display,
GError **error);
void
_cogl_winsys_display_destroy (CoglDisplay *display);
gboolean
_cogl_winsys_context_init (CoglContext *context, GError **error);
void
_cogl_winsys_context_deinit (CoglContext *context);
gboolean
_cogl_winsys_has_feature (CoglWinsysFeature feature);
#ifdef COGL_HAS_XLIB_SUPPORT
XVisualInfo *
_cogl_winsys_xlib_get_visual_info (void);
#endif
gboolean
_cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
GError **error);
void
_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen);
void
_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen);
void
_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen);
void
_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
int *rectangles,
int n_rectangles);
void
_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen);
guint32
_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen);
guint32
_cogl_winsys_get_vsync_counter (void);
unsigned int
_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
CoglSwapBuffersNotify callback,
void *user_data);
void
_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
unsigned int id);
#endif /* __COGL_WINSYS_PRIVATE_H */ #endif /* __COGL_WINSYS_PRIVATE_H */

View file

@ -0,0 +1,114 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "cogl-framebuffer-private.h"
/* This provides a stub winsys implementation for when Clutter still handles
* creating an OpenGL context. This is useful so we don't have to guard all
* calls into the winsys layer with #ifdef COGL_HAS_FULL_WINSYS
*/
void
_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
{
}
void
_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
int *rectangles,
int n_rectangles)
{
}
void
_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
{
}
unsigned int
_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
CoglSwapBuffersNotify callback,
void *user_data)
{
g_assert (0);
return 0;
}
void
_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
unsigned int id)
{
g_assert (0);
}
#ifdef COGL_HAS_XLIB_SUPPORT
XVisualInfo *
_cogl_winsys_xlib_get_visual_info (void)
{
g_assert (0);
return NULL;
}
#endif
gboolean
_cogl_winsys_has_feature (CoglWinsysFeature feature)
{
g_assert (0);
return FALSE;
}
#ifdef COGL_HAS_X11_SUPPORT
guint32
_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
{
g_assert (0);
return 0;
}
#endif
gboolean
_cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
GError **error)
{
return TRUE;
}
void
_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
{
}
void
_cogl_winsys_context_deinit (CoglContext *context)
{
}

36
cogl/winsys/cogl-winsys.c Normal file
View file

@ -0,0 +1,36 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2007,2008,2009,2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "cogl.h"
GQuark
_cogl_winsys_error_quark (void)
{
return g_quark_from_static_string ("cogl-winsys-error-quark");
}