mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 18:11:05 -05:00
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:
parent
aa1a2cb661
commit
d6f110a4d2
@ -37,6 +37,11 @@ struct _ClutterBackend
|
|||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
|
CoglRenderer *cogl_renderer;
|
||||||
|
CoglDisplay *cogl_display;
|
||||||
|
CoglContext *cogl_context;
|
||||||
|
|
||||||
ClutterBackendPrivate *priv;
|
ClutterBackendPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "clutter-version.h"
|
#include "clutter-version.h"
|
||||||
|
|
||||||
#include <cogl/cogl.h>
|
#include <cogl/cogl.h>
|
||||||
|
#include <cogl/cogl-internal.h>
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT);
|
G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
@ -672,7 +672,6 @@ clutter_stage_realize (ClutterActor *self)
|
|||||||
if (is_realized)
|
if (is_realized)
|
||||||
{
|
{
|
||||||
ClutterBackend *backend = clutter_get_default_backend ();
|
ClutterBackend *backend = clutter_get_default_backend ();
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
/* We want to select the context without calling
|
/* We want to select the context without calling
|
||||||
clutter_backend_ensure_context so that it doesn't call any
|
clutter_backend_ensure_context so that it doesn't call any
|
||||||
@ -680,17 +679,6 @@ clutter_stage_realize (ClutterActor *self)
|
|||||||
before we get a chance to check whether the GL version is
|
before we get a chance to check whether the GL version is
|
||||||
valid */
|
valid */
|
||||||
_clutter_backend_ensure_context_internal (backend, CLUTTER_STAGE (self));
|
_clutter_backend_ensure_context_internal (backend, CLUTTER_STAGE (self));
|
||||||
|
|
||||||
/* Make sure Cogl can support the driver */
|
|
||||||
if (!_cogl_check_driver_valid (&error))
|
|
||||||
{
|
|
||||||
g_critical ("The GL driver is not supported: %s",
|
|
||||||
error->message);
|
|
||||||
g_clear_error (&error);
|
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||||
|
@ -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)
|
||||||
@ -114,10 +115,8 @@ 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)/winsys/cogl-texture-pixmap-x11.c \
|
$(srcdir)/cogl-renderer-xlib.c \
|
||||||
$(srcdir)/winsys/cogl-texture-pixmap-x11-private.h
|
$(srcdir)/cogl-display-xlib-private.h \
|
||||||
|
$(srcdir)/cogl-xlib.c \
|
||||||
|
$(srcdir)/winsys/cogl-texture-pixmap-x11.c \
|
||||||
|
$(srcdir)/winsys/cogl-texture-pixmap-x11-private.h
|
||||||
endif
|
endif
|
||||||
if SUPPORT_GLX
|
if SUPPORT_GLX
|
||||||
cogl_sources_c += \
|
cogl_sources_c += \
|
||||||
$(srcdir)/winsys/cogl-winsys-glx.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
|
||||||
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
|
||||||
|
@ -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
|
||||||
|
@ -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__ */
|
||||||
|
@ -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 *
|
||||||
|
@ -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,18 +125,21 @@ 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;
|
||||||
|
|
||||||
if (!display)
|
context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_UNKNOWN;
|
||||||
|
|
||||||
|
_cogl_bitmask_init (&context->winsys_features);
|
||||||
|
|
||||||
|
if (!display)
|
||||||
display = cogl_display_new (NULL, NULL);
|
display = cogl_display_new (NULL, NULL);
|
||||||
else
|
else
|
||||||
cogl_object_ref (display);
|
cogl_object_ref (display);
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
57
clutter/cogl/cogl/cogl-display-glx-private.h
Normal file
57
clutter/cogl/cogl/cogl-display-glx-private.h
Normal 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 */
|
35
clutter/cogl/cogl/cogl-display-xlib-private.h
Normal file
35
clutter/cogl/cogl/cogl-display-xlib-private.h
Normal 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 */
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
const CoglFeatureData *data,
|
_cogl_feature_check (const char *driver_prefix,
|
||||||
unsigned int gl_major, unsigned int gl_minor,
|
const CoglFeatureData *data,
|
||||||
const char *extensions_string);
|
unsigned int gl_major,
|
||||||
|
unsigned int gl_minor,
|
||||||
|
const char *extensions_string,
|
||||||
|
void *function_table);
|
||||||
|
|
||||||
#endif /* __COGL_FEATURE_PRIVATE_H */
|
#endif /* __COGL_FEATURE_PRIVATE_H */
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
_cogl_matrix_stack_dirty (draw_buffer->modelview_stack);
|
if (draw_buffer)
|
||||||
_cogl_matrix_stack_dirty (draw_buffer->projection_stack);
|
{
|
||||||
|
_cogl_matrix_stack_dirty (draw_buffer->modelview_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,15 +1340,20 @@ 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
|
||||||
GE (glBindFramebuffer (target, 0));
|
{
|
||||||
|
#ifdef COGL_HAS_FULL_WINSYS
|
||||||
|
_cogl_winsys_onscreen_bind (COGL_ONSCREEN (framebuffer));
|
||||||
|
#endif
|
||||||
|
GE (glBindFramebuffer (target, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1282,21 +1363,29 @@ _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);
|
||||||
|
|
||||||
ctx->dirty_bound_framebuffer = FALSE;
|
bind_gl_framebuffer (ctx, GL_DRAW_FRAMEBUFFER, draw_buffer);
|
||||||
|
bind_gl_framebuffer (ctx, GL_READ_FRAMEBUFFER, read_buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->dirty_bound_framebuffer = FALSE;
|
||||||
|
|
||||||
|
if (flags & COGL_FRAMEBUFFER_FLUSH_BIND_ONLY)
|
||||||
|
return;
|
||||||
|
|
||||||
if (ctx->dirty_gl_viewport)
|
if (ctx->dirty_gl_viewport)
|
||||||
{
|
{
|
||||||
float gl_viewport_y;
|
float gl_viewport_y;
|
||||||
@ -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
clutter/cogl/cogl/cogl-framebuffer.h
Normal file
109
clutter/cogl/cogl/cogl-framebuffer.h
Normal 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 */
|
||||||
|
|
@ -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 */
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
61
clutter/cogl/cogl/cogl-renderer-glx-private.h
Normal file
61
clutter/cogl/cogl/cogl-renderer-glx-private.h
Normal 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 */
|
32
clutter/cogl/cogl/cogl-renderer-x11-private.h
Normal file
32
clutter/cogl/cogl/cogl-renderer-x11-private.h
Normal 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 */
|
@ -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
clutter/cogl/cogl/cogl-renderer-xlib.c
Normal file
288
clutter/cogl/cogl/cogl-renderer-xlib.c
Normal 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;
|
||||||
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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__ */
|
||||||
|
@ -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
clutter/cogl/cogl/cogl-xlib-private.h
Normal file
82
clutter/cogl/cogl/cogl-xlib-private.h
Normal 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 */
|
@ -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
clutter/cogl/cogl/cogl-xlib.h
Normal file
84
clutter/cogl/cogl/cogl-xlib.h
Normal 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__ */
|
@ -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.
|
||||||
|
@ -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__
|
||||||
|
53
clutter/cogl/cogl/driver/gl/cogl-context-driver-gl.h
Normal file
53
clutter/cogl/cogl/driver/gl/cogl-context-driver-gl.h
Normal 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 */
|
||||||
|
|
@ -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,8 +162,8 @@ _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)
|
||||||
#undef COGL_FEATURE_END
|
#undef COGL_FEATURE_END
|
||||||
@ -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;
|
|
||||||
}
|
}
|
||||||
|
52
clutter/cogl/cogl/driver/gles/cogl-context-driver-gles.h
Normal file
52
clutter/cogl/cogl/driver/gles/cogl-context-driver-gles.h
Normal 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 */
|
||||||
|
|
@ -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,8 +58,8 @@ _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)
|
||||||
#undef COGL_FEATURE_END
|
#undef COGL_FEATURE_END
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||||
|
|
||||||
@ -228,26 +231,28 @@ get_fbconfig_for_depth (unsigned int depth,
|
|||||||
gboolean *can_mipmap_ret)
|
gboolean *can_mipmap_ret)
|
||||||
{
|
{
|
||||||
GLXFBConfig *fbconfigs;
|
GLXFBConfig *fbconfigs;
|
||||||
int n_elements, i;
|
int n_elements, i;
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
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,12 +897,15 @@ _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 (),
|
||||||
GLX_FRONT_LEFT_EXT);
|
tex_pixmap->glx_pixmap,
|
||||||
|
GLX_FRONT_LEFT_EXT);
|
||||||
|
|
||||||
/* FIXME - we need to trap errors and synchronize here because
|
/* FIXME - we need to trap errors and synchronize here because
|
||||||
* of ordering issues between the XPixmap destruction and the
|
* of ordering issues between the XPixmap destruction and the
|
||||||
@ -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,14 +1044,14 @@ _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);
|
||||||
|
|
||||||
/* According to the recommended usage in the spec for
|
/* According to the recommended usage in the spec for
|
||||||
GLX_EXT_texture_pixmap we should release the texture after
|
GLX_EXT_texture_pixmap we should release the texture after
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
105
clutter/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h
Normal file
105
clutter/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h
Normal 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
@ -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 */
|
||||||
|
114
clutter/cogl/cogl/winsys/cogl-winsys-stub.c
Normal file
114
clutter/cogl/cogl/winsys/cogl-winsys-stub.c
Normal 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
clutter/cogl/cogl/winsys/cogl-winsys.c
Normal file
36
clutter/cogl/cogl/winsys/cogl-winsys.c
Normal 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");
|
||||||
|
}
|
||||||
|
|
@ -49,6 +49,7 @@
|
|||||||
#include "clutter-stage-private.h"
|
#include "clutter-stage-private.h"
|
||||||
|
|
||||||
#include "cogl/cogl.h"
|
#include "cogl/cogl.h"
|
||||||
|
#include "cogl/cogl-internal.h"
|
||||||
|
|
||||||
#define clutter_backend_glx_get_type _clutter_backend_glx_get_type
|
#define clutter_backend_glx_get_type _clutter_backend_glx_get_type
|
||||||
|
|
||||||
@ -57,12 +58,15 @@ G_DEFINE_TYPE (ClutterBackendGLX, clutter_backend_glx, CLUTTER_TYPE_BACKEND_X11)
|
|||||||
/* singleton object */
|
/* singleton object */
|
||||||
static ClutterBackendGLX *backend_singleton = NULL;
|
static ClutterBackendGLX *backend_singleton = NULL;
|
||||||
|
|
||||||
static gchar *clutter_vblank_name = NULL;
|
static gchar *clutter_vblank = NULL;
|
||||||
|
|
||||||
G_CONST_RETURN gchar*
|
G_CONST_RETURN gchar*
|
||||||
_clutter_backend_glx_get_vblank_method (void)
|
_clutter_backend_glx_get_vblank (void)
|
||||||
{
|
{
|
||||||
return clutter_vblank_name;
|
if (clutter_vblank && strcmp (clutter_vblank, "0") == 0)
|
||||||
|
return "none";
|
||||||
|
else
|
||||||
|
return clutter_vblank;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -76,7 +80,7 @@ clutter_backend_glx_pre_parse (ClutterBackend *backend,
|
|||||||
env_string = g_getenv ("CLUTTER_VBLANK");
|
env_string = g_getenv ("CLUTTER_VBLANK");
|
||||||
if (env_string)
|
if (env_string)
|
||||||
{
|
{
|
||||||
clutter_vblank_name = g_strdup (env_string);
|
clutter_vblank = g_strdup (env_string);
|
||||||
env_string = NULL;
|
env_string = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,42 +91,12 @@ static gboolean
|
|||||||
clutter_backend_glx_post_parse (ClutterBackend *backend,
|
clutter_backend_glx_post_parse (ClutterBackend *backend,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
|
||||||
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
|
|
||||||
ClutterBackendClass *parent_class =
|
ClutterBackendClass *parent_class =
|
||||||
CLUTTER_BACKEND_CLASS (clutter_backend_glx_parent_class);
|
CLUTTER_BACKEND_CLASS (clutter_backend_glx_parent_class);
|
||||||
int glx_major, glx_minor;
|
|
||||||
|
|
||||||
if (!parent_class->post_parse (backend, error))
|
if (!parent_class->post_parse (backend, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!glXQueryExtension (backend_x11->xdpy,
|
|
||||||
&backend_glx->error_base,
|
|
||||||
&backend_glx->event_base))
|
|
||||||
{
|
|
||||||
g_set_error_literal (error, CLUTTER_INIT_ERROR,
|
|
||||||
CLUTTER_INIT_ERROR_BACKEND,
|
|
||||||
"XServer appears to lack the required GLX support");
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX: Technically we should require >= GLX 1.3 support but for a long
|
|
||||||
* time Mesa has exported a hybrid GLX, exporting extensions specified
|
|
||||||
* to require GLX 1.3, but still reporting 1.2 via glXQueryVersion. */
|
|
||||||
glx_major = 1;
|
|
||||||
glx_minor = 2;
|
|
||||||
if (!glXQueryVersion (backend_x11->xdpy, &glx_major, &glx_minor) ||
|
|
||||||
!(glx_major == 1 && glx_minor >= 2))
|
|
||||||
{
|
|
||||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
|
||||||
CLUTTER_INIT_ERROR_BACKEND,
|
|
||||||
"XServer appears to lack the required GLX "
|
|
||||||
"1.2 support (%d.%d reported)",
|
|
||||||
glx_major, glx_minor);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,8 +104,9 @@ static const GOptionEntry entries[] =
|
|||||||
{
|
{
|
||||||
{ "vblank", 0,
|
{ "vblank", 0,
|
||||||
0,
|
0,
|
||||||
G_OPTION_ARG_STRING, &clutter_vblank_name,
|
G_OPTION_ARG_STRING, &clutter_vblank,
|
||||||
N_("VBlank method to be used (none, dri or glx)"), "METHOD"
|
N_("Set to 'none' or '0' to disable throttling "
|
||||||
|
"framerate to vblank"), "OPTION"
|
||||||
},
|
},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
@ -160,32 +135,20 @@ clutter_backend_glx_finalize (GObject *gobject)
|
|||||||
static void
|
static void
|
||||||
clutter_backend_glx_dispose (GObject *gobject)
|
clutter_backend_glx_dispose (GObject *gobject)
|
||||||
{
|
{
|
||||||
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (gobject);
|
ClutterBackend *backend = CLUTTER_BACKEND (gobject);
|
||||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (gobject);
|
|
||||||
|
|
||||||
/* Unrealize all shaders, since the GL context is going away */
|
/* Unrealize all shaders, since the GL context is going away */
|
||||||
|
/* XXX: Why isn't this done in
|
||||||
|
* clutter-backend.c:clutter_backend_dispose ?
|
||||||
|
*/
|
||||||
_clutter_shader_release_all ();
|
_clutter_shader_release_all ();
|
||||||
|
|
||||||
if (backend_glx->gl_context)
|
/* We chain up before disposing our CoglContext so that we will
|
||||||
{
|
* destroy all of the stages first. Otherwise the actors may try to
|
||||||
glXMakeContextCurrent (backend_x11->xdpy, None, None, NULL);
|
* make Cogl calls during destruction which would cause a crash */
|
||||||
glXDestroyContext (backend_x11->xdpy, backend_glx->gl_context);
|
|
||||||
backend_glx->gl_context = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backend_glx->dummy_glxwin)
|
|
||||||
{
|
|
||||||
glXDestroyWindow (backend_x11->xdpy, backend_glx->dummy_glxwin);
|
|
||||||
backend_glx->dummy_glxwin = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backend_glx->dummy_xwin)
|
|
||||||
{
|
|
||||||
XDestroyWindow (backend_x11->xdpy, backend_glx->dummy_xwin);
|
|
||||||
backend_glx->dummy_xwin = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_backend_glx_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (clutter_backend_glx_parent_class)->dispose (gobject);
|
||||||
|
|
||||||
|
cogl_object_unref (backend->cogl_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GObject *
|
static GObject *
|
||||||
@ -212,197 +175,46 @@ clutter_backend_glx_constructor (GType gtype,
|
|||||||
return g_object_ref (backend_singleton);
|
return g_object_ref (backend_singleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
check_vblank_env (const char *name)
|
|
||||||
{
|
|
||||||
if (clutter_vblank_name && !g_ascii_strcasecmp (clutter_vblank_name, name))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ClutterFeatureFlags
|
static ClutterFeatureFlags
|
||||||
clutter_backend_glx_get_features (ClutterBackend *backend)
|
clutter_backend_glx_get_features (ClutterBackend *backend)
|
||||||
{
|
{
|
||||||
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
|
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
|
||||||
ClutterBackendClass *parent_class;
|
ClutterBackendClass *parent_class;
|
||||||
const gchar *glx_extensions = NULL;
|
|
||||||
const gchar *gl_extensions = NULL;
|
|
||||||
ClutterFeatureFlags flags;
|
ClutterFeatureFlags flags;
|
||||||
gboolean use_dri = FALSE;
|
|
||||||
|
|
||||||
parent_class = CLUTTER_BACKEND_CLASS (clutter_backend_glx_parent_class);
|
parent_class = CLUTTER_BACKEND_CLASS (clutter_backend_glx_parent_class);
|
||||||
|
|
||||||
flags = parent_class->get_features (backend);
|
flags = parent_class->get_features (backend);
|
||||||
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
|
|
||||||
|
|
||||||
/* this will make sure that the GL context exists */
|
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN))
|
||||||
g_assert (backend_glx->gl_context != NULL);
|
|
||||||
g_assert (glXGetCurrentDrawable () != None);
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
|
||||||
"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));
|
|
||||||
|
|
||||||
glx_extensions =
|
|
||||||
glXQueryExtensionsString (clutter_x11_get_default_display (),
|
|
||||||
clutter_x11_get_default_screen ());
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, " GLX Extensions: %s", glx_extensions);
|
|
||||||
|
|
||||||
gl_extensions = (const gchar *)glGetString (GL_EXTENSIONS);
|
|
||||||
|
|
||||||
/* When using glBlitFramebuffer or glXCopySubBufferMESA for sub stage
|
|
||||||
* redraws, we cannot rely on glXSwapIntervalSGI to throttle the blits
|
|
||||||
* so we need to resort to manually synchronizing with the vblank so we
|
|
||||||
* always check for the video_sync extension...
|
|
||||||
*/
|
|
||||||
if (_cogl_check_extension ("GLX_SGI_video_sync", glx_extensions) &&
|
|
||||||
/* Note: the GLX_SGI_video_sync spec explicitly states this extension
|
|
||||||
* only works for direct contexts. */
|
|
||||||
glXIsDirect (clutter_x11_get_default_display (),
|
|
||||||
backend_glx->gl_context))
|
|
||||||
{
|
{
|
||||||
backend_glx->get_video_sync =
|
CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers");
|
||||||
(GetVideoSyncProc) cogl_get_proc_address ("glXGetVideoSyncSGI");
|
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
|
||||||
|
}
|
||||||
backend_glx->wait_video_sync =
|
else
|
||||||
(WaitVideoSyncProc) cogl_get_proc_address ("glXWaitVideoSyncSGI");
|
{
|
||||||
|
CLUTTER_NOTE (BACKEND, "Cogl only supports one onscreen framebuffer");
|
||||||
|
flags |= CLUTTER_FEATURE_STAGE_STATIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
use_dri = check_vblank_env ("dri");
|
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE))
|
||||||
|
|
||||||
/* First check for explicit disabling or it set elsewhere (eg NVIDIA) */
|
|
||||||
if (check_vblank_env ("none"))
|
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (BACKEND, "vblank sync: disabled at user request");
|
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling");
|
||||||
goto vblank_setup_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_getenv ("__GL_SYNC_TO_VBLANK") != NULL)
|
|
||||||
{
|
|
||||||
backend_glx->vblank_type = CLUTTER_VBLANK_GLX_SWAP;
|
|
||||||
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
|
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling");
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Using __GL_SYNC_TO_VBLANK hint");
|
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT))
|
||||||
goto vblank_setup_done;
|
{
|
||||||
|
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers complete events");
|
||||||
|
flags |= CLUTTER_FEATURE_SWAP_EVENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We try two GL vblank syncing mechanisms.
|
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION))
|
||||||
* glXSwapIntervalSGI is tried first, then glXGetVideoSyncSGI.
|
|
||||||
*
|
|
||||||
* glXSwapIntervalSGI is known to work with Mesa and in particular
|
|
||||||
* the Intel drivers. glXGetVideoSyncSGI has serious problems with
|
|
||||||
* Intel drivers causing terrible frame rate so it only tried as a
|
|
||||||
* fallback.
|
|
||||||
*
|
|
||||||
* How well glXGetVideoSyncSGI works with other driver (ATI etc) needs
|
|
||||||
* to be investigated. glXGetVideoSyncSGI on ATI at least seems to have
|
|
||||||
* no effect.
|
|
||||||
*/
|
|
||||||
if (!use_dri &&
|
|
||||||
_cogl_check_extension ("GLX_SGI_swap_control", glx_extensions))
|
|
||||||
{
|
{
|
||||||
backend_glx->swap_interval =
|
CLUTTER_NOTE (BACKEND, "Cogl supports swapping buffer regions");
|
||||||
(SwapIntervalProc) cogl_get_proc_address ("glXSwapIntervalSGI");
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "attempting glXSwapIntervalSGI vblank setup");
|
|
||||||
|
|
||||||
if (backend_glx->swap_interval != NULL &&
|
|
||||||
backend_glx->swap_interval (1) == 0)
|
|
||||||
{
|
|
||||||
backend_glx->vblank_type = CLUTTER_VBLANK_GLX_SWAP;
|
|
||||||
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "glXSwapIntervalSGI setup success");
|
|
||||||
|
|
||||||
#ifdef GLX_INTEL_swap_event
|
|
||||||
/* GLX_INTEL_swap_event allows us to avoid blocking the CPU
|
|
||||||
* while we wait for glXSwapBuffers to complete, and instead
|
|
||||||
* we get an X event notifying us of completion...
|
|
||||||
*/
|
|
||||||
if (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_SWAP_EVENTS) &&
|
|
||||||
_cogl_check_extension ("GLX_INTEL_swap_event", glx_extensions))
|
|
||||||
{
|
|
||||||
flags |= CLUTTER_FEATURE_SWAP_EVENTS;
|
|
||||||
}
|
|
||||||
#endif /* GLX_INTEL_swap_event */
|
|
||||||
|
|
||||||
goto vblank_setup_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "glXSwapIntervalSGI vblank setup failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!use_dri &&
|
|
||||||
!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK) &&
|
|
||||||
_cogl_check_extension ("GLX_SGI_video_sync", glx_extensions))
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (BACKEND, "attempting glXGetVideoSyncSGI vblank setup");
|
|
||||||
|
|
||||||
if ((backend_glx->get_video_sync != NULL) &&
|
|
||||||
(backend_glx->wait_video_sync != NULL))
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (BACKEND, "glXGetVideoSyncSGI vblank setup success");
|
|
||||||
|
|
||||||
backend_glx->vblank_type = CLUTTER_VBLANK_GLX;
|
|
||||||
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
|
|
||||||
|
|
||||||
goto vblank_setup_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "glXGetVideoSyncSGI vblank setup failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
/*
|
|
||||||
* DRI is really an extreme fallback -rumoured to work with Via chipsets
|
|
||||||
*/
|
|
||||||
if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK))
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (BACKEND, "attempting DRI vblank setup");
|
|
||||||
|
|
||||||
backend_glx->dri_fd = open("/dev/dri/card0", O_RDWR);
|
|
||||||
if (backend_glx->dri_fd >= 0)
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (BACKEND, "DRI vblank setup success");
|
|
||||||
|
|
||||||
backend_glx->vblank_type = CLUTTER_VBLANK_DRI;
|
|
||||||
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
|
|
||||||
|
|
||||||
goto vblank_setup_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "DRI vblank setup failed");
|
|
||||||
}
|
|
||||||
#endif /* __linux__ */
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "no use-able vblank mechanism found");
|
|
||||||
|
|
||||||
vblank_setup_done:
|
|
||||||
|
|
||||||
if (_cogl_check_extension ("GLX_MESA_copy_sub_buffer", glx_extensions))
|
|
||||||
{
|
|
||||||
backend_glx->copy_sub_buffer =
|
|
||||||
(CopySubBufferProc) cogl_get_proc_address ("glXCopySubBufferMESA");
|
|
||||||
backend_glx->can_blit_sub_buffer = TRUE;
|
backend_glx->can_blit_sub_buffer = TRUE;
|
||||||
backend_glx->blit_sub_buffer_is_synchronized = TRUE;
|
|
||||||
}
|
|
||||||
else if (_cogl_check_extension ("GL_EXT_framebuffer_blit", gl_extensions))
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
|
||||||
"Using glBlitFramebuffer fallback for sub_buffer copies");
|
|
||||||
backend_glx->blit_framebuffer =
|
|
||||||
(BlitFramebufferProc) cogl_get_proc_address ("glBlitFramebuffer");
|
|
||||||
backend_glx->can_blit_sub_buffer = TRUE;
|
|
||||||
backend_glx->blit_sub_buffer_is_synchronized = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "backend features checked");
|
CLUTTER_NOTE (BACKEND, "backend features checked");
|
||||||
@ -410,375 +222,77 @@ vblank_setup_done:
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It seems the GLX spec never defined an invalid GLXFBConfig that
|
|
||||||
* we could overload as an indication of error, so we have to return
|
|
||||||
* an explicit boolean status. */
|
|
||||||
gboolean
|
|
||||||
_clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_glx,
|
|
||||||
GLXFBConfig *config)
|
|
||||||
{
|
|
||||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend_glx);
|
|
||||||
GLXFBConfig *configs = NULL;
|
|
||||||
gboolean use_argb = clutter_x11_get_use_argb_visual ();
|
|
||||||
int n_configs, i;
|
|
||||||
static const int attributes[] = {
|
|
||||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
|
||||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
|
||||||
GLX_DOUBLEBUFFER, GL_TRUE,
|
|
||||||
GLX_RED_SIZE, 1,
|
|
||||||
GLX_GREEN_SIZE, 1,
|
|
||||||
GLX_BLUE_SIZE, 1,
|
|
||||||
GLX_ALPHA_SIZE, 1,
|
|
||||||
GLX_DEPTH_SIZE, 1,
|
|
||||||
GLX_STENCIL_SIZE, 1,
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if (backend_x11->xdpy == NULL || backend_x11->xscreen == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* If we don't already have a cached config then try to get one */
|
|
||||||
if (!backend_glx->found_fbconfig)
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
|
||||||
"Retrieving GL fbconfig, dpy: %p, xscreen; %p (%d)",
|
|
||||||
backend_x11->xdpy,
|
|
||||||
backend_x11->xscreen,
|
|
||||||
backend_x11->xscreen_num);
|
|
||||||
|
|
||||||
configs = glXChooseFBConfig (backend_x11->xdpy,
|
|
||||||
backend_x11->xscreen_num,
|
|
||||||
attributes,
|
|
||||||
&n_configs);
|
|
||||||
if (configs)
|
|
||||||
{
|
|
||||||
if (use_argb)
|
|
||||||
{
|
|
||||||
for (i = 0; i < n_configs; i++)
|
|
||||||
{
|
|
||||||
XVisualInfo *vinfo;
|
|
||||||
|
|
||||||
vinfo = glXGetVisualFromFBConfig (backend_x11->xdpy,
|
|
||||||
configs[i]);
|
|
||||||
if (vinfo == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (vinfo->depth == 32 &&
|
|
||||||
(vinfo->red_mask == 0xff0000 &&
|
|
||||||
vinfo->green_mask == 0x00ff00 &&
|
|
||||||
vinfo->blue_mask == 0x0000ff))
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
|
||||||
"Found an ARGB FBConfig [index:%d]",
|
|
||||||
i);
|
|
||||||
|
|
||||||
backend_glx->found_fbconfig = TRUE;
|
|
||||||
backend_glx->fbconfig = configs[i];
|
|
||||||
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we make it here then we didn't find an RGBA config so
|
|
||||||
we'll fall back to using an RGB config */
|
|
||||||
CLUTTER_NOTE (BACKEND, "ARGB visual requested, but none found");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_configs >= 1)
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (BACKEND, "Using the first available FBConfig");
|
|
||||||
backend_glx->found_fbconfig = TRUE;
|
|
||||||
backend_glx->fbconfig = configs[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
XFree (configs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (G_LIKELY (backend_glx->found_fbconfig))
|
|
||||||
{
|
|
||||||
*config = backend_glx->fbconfig;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_clutter_backend_glx_blit_sub_buffer (ClutterBackendGLX *backend_glx,
|
|
||||||
GLXDrawable drawable,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend_glx);
|
|
||||||
|
|
||||||
if (backend_glx->copy_sub_buffer)
|
|
||||||
{
|
|
||||||
backend_glx->copy_sub_buffer (backend_x11->xdpy, drawable,
|
|
||||||
x, y, width, height);
|
|
||||||
}
|
|
||||||
else if (backend_glx->blit_framebuffer)
|
|
||||||
{
|
|
||||||
glDrawBuffer (GL_FRONT);
|
|
||||||
backend_glx->blit_framebuffer (x, y, x + width, y + height,
|
|
||||||
x, y, x + width, y + height,
|
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
glDrawBuffer (GL_BACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NB: unlike glXSwapBuffers, glXCopySubBuffer and
|
|
||||||
* glBlitFramebuffer don't issue an implicit glFlush() so we
|
|
||||||
* have to flush ourselves if we want the request to complete in
|
|
||||||
* finite amount of time since otherwise the driver can batch
|
|
||||||
* the command indefinitely. */
|
|
||||||
glFlush();
|
|
||||||
}
|
|
||||||
|
|
||||||
static XVisualInfo *
|
static XVisualInfo *
|
||||||
clutter_backend_glx_get_visual_info (ClutterBackendX11 *backend_x11)
|
clutter_backend_glx_get_visual_info (ClutterBackendX11 *backend_x11)
|
||||||
{
|
{
|
||||||
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend_x11);
|
return cogl_clutter_winsys_xlib_get_visual_info ();
|
||||||
GLXFBConfig config;
|
|
||||||
|
|
||||||
if (!_clutter_backend_glx_get_fbconfig (backend_glx, &config))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return glXGetVisualFromFBConfig (backend_x11->xdpy, config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
clutter_backend_glx_create_context (ClutterBackend *backend,
|
clutter_backend_glx_create_context (ClutterBackend *backend,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
|
|
||||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||||
GLXFBConfig config;
|
CoglSwapChain *swap_chain = NULL;
|
||||||
gboolean is_direct;
|
CoglOnscreenTemplate *onscreen_template = NULL;
|
||||||
Window root_xwin;
|
|
||||||
XSetWindowAttributes attrs;
|
|
||||||
XVisualInfo *xvisinfo;
|
|
||||||
Display *xdisplay;
|
|
||||||
int major;
|
|
||||||
int minor;
|
|
||||||
GLXDrawable dummy_drawable;
|
|
||||||
|
|
||||||
if (backend_glx->gl_context != NULL)
|
if (backend->cogl_context)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
xdisplay = clutter_x11_get_default_display ();
|
backend->cogl_renderer = cogl_renderer_new ();
|
||||||
root_xwin = clutter_x11_get_root_window ();
|
cogl_renderer_xlib_set_foreign_display (backend->cogl_renderer,
|
||||||
|
backend_x11->xdpy);
|
||||||
|
if (!cogl_renderer_connect (backend->cogl_renderer, error))
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (!_clutter_backend_glx_get_fbconfig (backend_glx, &config))
|
swap_chain = cogl_swap_chain_new ();
|
||||||
{
|
cogl_swap_chain_set_has_alpha (swap_chain,
|
||||||
g_set_error_literal (error, CLUTTER_INIT_ERROR,
|
clutter_x11_get_use_argb_visual ());
|
||||||
CLUTTER_INIT_ERROR_BACKEND,
|
|
||||||
"Unable to find suitable fbconfig for the GLX context");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Creating GLX Context (display: %p)", xdisplay);
|
onscreen_template = cogl_onscreen_template_new (swap_chain);
|
||||||
|
cogl_object_unref (swap_chain);
|
||||||
|
|
||||||
backend_glx->gl_context = glXCreateNewContext (xdisplay,
|
if (!cogl_renderer_check_onscreen_template (backend->cogl_renderer,
|
||||||
config,
|
onscreen_template,
|
||||||
GLX_RGBA_TYPE,
|
error))
|
||||||
NULL,
|
goto error;
|
||||||
True);
|
|
||||||
if (backend_glx->gl_context == NULL)
|
|
||||||
{
|
|
||||||
g_set_error_literal (error, CLUTTER_INIT_ERROR,
|
|
||||||
CLUTTER_INIT_ERROR_BACKEND,
|
|
||||||
"Unable to create suitable GL context");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
is_direct = glXIsDirect (xdisplay, backend_glx->gl_context);
|
backend->cogl_display = cogl_display_new (backend->cogl_renderer,
|
||||||
|
onscreen_template);
|
||||||
|
cogl_object_unref (backend->cogl_renderer);
|
||||||
|
cogl_object_unref (onscreen_template);
|
||||||
|
|
||||||
CLUTTER_NOTE (GL, "Setting %s context",
|
if (!cogl_display_setup (backend->cogl_display, error))
|
||||||
is_direct ? "direct"
|
goto error;
|
||||||
: "indirect");
|
|
||||||
_cogl_set_indirect_context (!is_direct);
|
|
||||||
|
|
||||||
/* COGL assumes that there is always a GL context selected; in order
|
backend->cogl_context = cogl_context_new (backend->cogl_display, error);
|
||||||
* to make sure that a GLX context exists and is made current, we use
|
if (!backend->cogl_context)
|
||||||
* a dummy, offscreen override-redirect window to which we can always
|
goto error;
|
||||||
* fall back if no stage is available
|
|
||||||
*
|
|
||||||
* XXX - we need to do this dance because GLX does not allow creating
|
|
||||||
* a context and querying it for basic information (even the function
|
|
||||||
* pointers) unless it's made current to a real Drawable. it should be
|
|
||||||
* possible to avoid this in future releases of Mesa and X11, but right
|
|
||||||
* now this is the best solution available.
|
|
||||||
*/
|
|
||||||
xvisinfo = glXGetVisualFromFBConfig (xdisplay, config);
|
|
||||||
if (xvisinfo == NULL)
|
|
||||||
{
|
|
||||||
g_set_error_literal (error, CLUTTER_INIT_ERROR,
|
|
||||||
CLUTTER_INIT_ERROR_BACKEND,
|
|
||||||
"Unable to retrieve the X11 visual");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
clutter_x11_trap_x_errors ();
|
/* XXX: eventually this should go away but a lot of Cogl code still
|
||||||
|
* depends on a global default context. */
|
||||||
attrs.override_redirect = True;
|
cogl_set_default_context (backend->cogl_context);
|
||||||
attrs.colormap = XCreateColormap (xdisplay,
|
|
||||||
root_xwin,
|
|
||||||
xvisinfo->visual,
|
|
||||||
AllocNone);
|
|
||||||
attrs.border_pixel = 0;
|
|
||||||
|
|
||||||
backend_glx->dummy_xwin = XCreateWindow (xdisplay, root_xwin,
|
|
||||||
-100, -100, 1, 1,
|
|
||||||
0,
|
|
||||||
xvisinfo->depth,
|
|
||||||
CopyFromParent,
|
|
||||||
xvisinfo->visual,
|
|
||||||
CWOverrideRedirect | CWColormap | CWBorderPixel,
|
|
||||||
&attrs);
|
|
||||||
|
|
||||||
/* Try and create a GLXWindow to use with extensions dependent on
|
|
||||||
* GLX versions >= 1.3 that don't accept regular X Windows as GLX
|
|
||||||
* drawables. */
|
|
||||||
if (glXQueryVersion (backend_x11->xdpy, &major, &minor) &&
|
|
||||||
major == 1 && minor >= 3)
|
|
||||||
{
|
|
||||||
backend_glx->dummy_glxwin = glXCreateWindow (backend_x11->xdpy,
|
|
||||||
config,
|
|
||||||
backend_glx->dummy_xwin,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backend_glx->dummy_glxwin)
|
|
||||||
dummy_drawable = backend_glx->dummy_glxwin;
|
|
||||||
else
|
|
||||||
dummy_drawable = backend_glx->dummy_xwin;
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Selecting dummy 0x%x for the GLX context",
|
|
||||||
(unsigned int) dummy_drawable);
|
|
||||||
|
|
||||||
glXMakeContextCurrent (xdisplay,
|
|
||||||
dummy_drawable,
|
|
||||||
dummy_drawable,
|
|
||||||
backend_glx->gl_context);
|
|
||||||
|
|
||||||
XFree (xvisinfo);
|
|
||||||
|
|
||||||
if (clutter_x11_untrap_x_errors ())
|
|
||||||
{
|
|
||||||
g_set_error_literal (error, CLUTTER_INIT_ERROR,
|
|
||||||
CLUTTER_INIT_ERROR_BACKEND,
|
|
||||||
"Unable to select the newly created GLX context");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: remove this interface in favour of
|
error:
|
||||||
* _clutter_stage_window_make_current () */
|
if (backend->cogl_display)
|
||||||
static void
|
|
||||||
clutter_backend_glx_ensure_context (ClutterBackend *backend,
|
|
||||||
ClutterStage *stage)
|
|
||||||
{
|
|
||||||
ClutterStageWindow *impl;
|
|
||||||
|
|
||||||
/* if there is no stage, the stage is being destroyed or it has no
|
|
||||||
* implementation attached to it then we clear the GL context
|
|
||||||
*/
|
|
||||||
if (stage == NULL ||
|
|
||||||
CLUTTER_ACTOR_IN_DESTRUCTION (stage) ||
|
|
||||||
((impl = _clutter_stage_get_window (stage)) == NULL))
|
|
||||||
{
|
{
|
||||||
ClutterBackendX11 *backend_x11;
|
cogl_object_unref (backend->cogl_display);
|
||||||
|
backend->cogl_display = NULL;
|
||||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
|
||||||
CLUTTER_NOTE (MULTISTAGE, "Clearing all context");
|
|
||||||
|
|
||||||
glXMakeContextCurrent (backend_x11->xdpy, None, None, NULL);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (onscreen_template)
|
||||||
|
cogl_object_unref (onscreen_template);
|
||||||
|
if (swap_chain)
|
||||||
|
cogl_object_unref (swap_chain);
|
||||||
|
|
||||||
|
if (backend->cogl_renderer)
|
||||||
{
|
{
|
||||||
ClutterBackendGLX *backend_glx;
|
cogl_object_unref (backend->cogl_renderer);
|
||||||
ClutterBackendX11 *backend_x11;
|
backend->cogl_renderer = NULL;
|
||||||
ClutterStageGLX *stage_glx;
|
|
||||||
ClutterStageX11 *stage_x11;
|
|
||||||
GLXDrawable drawable;
|
|
||||||
|
|
||||||
g_assert (impl != NULL);
|
|
||||||
|
|
||||||
stage_glx = CLUTTER_STAGE_GLX (impl);
|
|
||||||
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
|
||||||
backend_glx = CLUTTER_BACKEND_GLX (backend);
|
|
||||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
|
||||||
|
|
||||||
drawable = stage_glx->glxwin ? stage_glx->glxwin : stage_x11->xwin;
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
|
||||||
"Setting context for stage of type %s, window: 0x%x",
|
|
||||||
G_OBJECT_TYPE_NAME (impl),
|
|
||||||
(unsigned int) drawable);
|
|
||||||
|
|
||||||
/* no GL context to set */
|
|
||||||
if (backend_glx->gl_context == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
clutter_x11_trap_x_errors ();
|
|
||||||
|
|
||||||
/* we might get here inside the final dispose cycle, so we
|
|
||||||
* need to handle this gracefully
|
|
||||||
*/
|
|
||||||
if (drawable == None)
|
|
||||||
{
|
|
||||||
GLXDrawable dummy_drawable;
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
|
||||||
"Received a stale stage, clearing all context");
|
|
||||||
|
|
||||||
if (backend_glx->dummy_glxwin)
|
|
||||||
dummy_drawable = backend_glx->dummy_glxwin;
|
|
||||||
else
|
|
||||||
dummy_drawable = backend_glx->dummy_xwin;
|
|
||||||
|
|
||||||
if (dummy_drawable == None)
|
|
||||||
glXMakeContextCurrent (backend_x11->xdpy, None, None, NULL);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glXMakeContextCurrent (backend_x11->xdpy,
|
|
||||||
dummy_drawable,
|
|
||||||
dummy_drawable,
|
|
||||||
backend_glx->gl_context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
|
||||||
"MakeContextCurrent dpy: %p, window: 0x%x (%s), context: %p",
|
|
||||||
backend_x11->xdpy,
|
|
||||||
(unsigned int) drawable,
|
|
||||||
stage_x11->is_foreign_xwin ? "foreign" : "native",
|
|
||||||
backend_glx->gl_context);
|
|
||||||
|
|
||||||
glXMakeContextCurrent (backend_x11->xdpy,
|
|
||||||
drawable,
|
|
||||||
drawable,
|
|
||||||
backend_glx->gl_context);
|
|
||||||
/*
|
|
||||||
* In case we are using GLX_SGI_swap_control for vblank syncing we need call
|
|
||||||
* glXSwapIntervalSGI here to make sure that it affects the current drawable.
|
|
||||||
*/
|
|
||||||
if (backend_glx->vblank_type == CLUTTER_VBLANK_GLX_SWAP && backend_glx->swap_interval != NULL)
|
|
||||||
backend_glx->swap_interval (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clutter_x11_untrap_x_errors ())
|
|
||||||
g_critical ("Unable to make the stage window 0x%x the current "
|
|
||||||
"GLX drawable",
|
|
||||||
(unsigned int) drawable);
|
|
||||||
}
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterStageWindow *
|
static ClutterStageWindow *
|
||||||
@ -812,6 +326,16 @@ clutter_backend_glx_create_stage (ClutterBackend *backend,
|
|||||||
return stage_window;
|
return stage_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_backend_glx_ensure_context (ClutterBackend *backend,
|
||||||
|
ClutterStage *stage)
|
||||||
|
{
|
||||||
|
ClutterStageGLX *stage_glx =
|
||||||
|
CLUTTER_STAGE_GLX (_clutter_stage_get_window (stage));
|
||||||
|
|
||||||
|
cogl_set_framebuffer (COGL_FRAMEBUFFER (stage_glx->onscreen));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_glx_class_init (ClutterBackendGLXClass *klass)
|
clutter_backend_glx_class_init (ClutterBackendGLXClass *klass)
|
||||||
{
|
{
|
||||||
|
@ -47,30 +47,11 @@ typedef struct _ClutterBackendGLXClass ClutterBackendGLXClass;
|
|||||||
|
|
||||||
typedef enum ClutterGLXVBlankType {
|
typedef enum ClutterGLXVBlankType {
|
||||||
CLUTTER_VBLANK_NONE = 0,
|
CLUTTER_VBLANK_NONE = 0,
|
||||||
CLUTTER_VBLANK_GLX_SWAP,
|
CLUTTER_VBLANK_AUTOMATIC_THROTTLE,
|
||||||
CLUTTER_VBLANK_GLX,
|
CLUTTER_VBLANK_VBLANK_COUNTER,
|
||||||
CLUTTER_VBLANK_DRI
|
CLUTTER_VBLANK_MANUAL_WAIT
|
||||||
} ClutterGLXVBlankType;
|
} ClutterGLXVBlankType;
|
||||||
|
|
||||||
typedef int (*GetVideoSyncProc) (unsigned int *count);
|
|
||||||
typedef int (*WaitVideoSyncProc) (int divisor,
|
|
||||||
int remainder,
|
|
||||||
unsigned int *count);
|
|
||||||
typedef int (*SwapIntervalProc) (int interval);
|
|
||||||
typedef void (*CopySubBufferProc)(Display *dpy,
|
|
||||||
GLXDrawable drawable,
|
|
||||||
int x, int y, int width, int height);
|
|
||||||
typedef void (*BlitFramebufferProc) (GLint srcX0,
|
|
||||||
GLint srcY0,
|
|
||||||
GLint srcX1,
|
|
||||||
GLint srcY1,
|
|
||||||
GLint dstX0,
|
|
||||||
GLint dstY0,
|
|
||||||
GLint dstX1,
|
|
||||||
GLint dstY1,
|
|
||||||
GLbitfield mask,
|
|
||||||
GLenum filter);
|
|
||||||
|
|
||||||
struct _ClutterBackendGLX
|
struct _ClutterBackendGLX
|
||||||
{
|
{
|
||||||
ClutterBackendX11 parent_instance;
|
ClutterBackendX11 parent_instance;
|
||||||
@ -78,25 +59,13 @@ struct _ClutterBackendGLX
|
|||||||
int error_base;
|
int error_base;
|
||||||
int event_base;
|
int event_base;
|
||||||
|
|
||||||
/* Single context for all wins */
|
CoglContext *cogl_context;
|
||||||
gboolean found_fbconfig;
|
|
||||||
GLXFBConfig fbconfig;
|
|
||||||
GLXContext gl_context;
|
|
||||||
Window dummy_xwin;
|
|
||||||
GLXWindow dummy_glxwin;
|
|
||||||
|
|
||||||
/* Vblank stuff */
|
/* Vblank stuff */
|
||||||
GetVideoSyncProc get_video_sync;
|
|
||||||
WaitVideoSyncProc wait_video_sync;
|
|
||||||
SwapIntervalProc swap_interval;
|
|
||||||
gint dri_fd;
|
|
||||||
ClutterGLXVBlankType vblank_type;
|
ClutterGLXVBlankType vblank_type;
|
||||||
unsigned int last_video_sync_count;
|
unsigned int last_video_sync_count;
|
||||||
|
|
||||||
gboolean can_blit_sub_buffer;
|
gboolean can_blit_sub_buffer;
|
||||||
CopySubBufferProc copy_sub_buffer;
|
|
||||||
BlitFramebufferProc blit_framebuffer;
|
|
||||||
gboolean blit_sub_buffer_is_synchronized;
|
|
||||||
|
|
||||||
/* props */
|
/* props */
|
||||||
Atom atom_WM_STATE;
|
Atom atom_WM_STATE;
|
||||||
@ -110,14 +79,8 @@ struct _ClutterBackendGLXClass
|
|||||||
|
|
||||||
GType _clutter_backend_glx_get_type (void) G_GNUC_CONST;
|
GType _clutter_backend_glx_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
gboolean
|
G_CONST_RETURN gchar*
|
||||||
_clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_x11,
|
_clutter_backend_glx_get_vblank (void);
|
||||||
GLXFBConfig *config);
|
|
||||||
|
|
||||||
void
|
|
||||||
_clutter_backend_glx_blit_sub_buffer (ClutterBackendGLX *backend_glx,
|
|
||||||
GLXDrawable drawable,
|
|
||||||
int x, int y, int width, int height);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -53,10 +53,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
|
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
|
||||||
static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface);
|
|
||||||
|
|
||||||
static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
|
static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
|
||||||
static ClutterEventTranslatorIface *clutter_event_translator_parent_iface = NULL;
|
|
||||||
|
|
||||||
#define clutter_stage_glx_get_type _clutter_stage_glx_get_type
|
#define clutter_stage_glx_get_type _clutter_stage_glx_get_type
|
||||||
|
|
||||||
@ -64,33 +62,37 @@ G_DEFINE_TYPE_WITH_CODE (ClutterStageGLX,
|
|||||||
clutter_stage_glx,
|
clutter_stage_glx,
|
||||||
CLUTTER_TYPE_STAGE_X11,
|
CLUTTER_TYPE_STAGE_X11,
|
||||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
|
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
|
||||||
clutter_stage_window_iface_init)
|
clutter_stage_window_iface_init));
|
||||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_TRANSLATOR,
|
|
||||||
clutter_event_translator_iface_init));
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_glx_unrealize (ClutterStageWindow *stage_window)
|
clutter_stage_glx_unrealize (ClutterStageWindow *stage_window)
|
||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
|
||||||
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window);
|
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window);
|
||||||
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
|
||||||
|
|
||||||
/* Note unrealize should free up any backend stage related resources */
|
/* Note unrealize should free up any backend stage related resources */
|
||||||
CLUTTER_NOTE (BACKEND, "Unrealizing GLX stage [%p]", stage_glx);
|
CLUTTER_NOTE (BACKEND, "Unrealizing GLX stage [%p]", stage_glx);
|
||||||
|
|
||||||
clutter_x11_trap_x_errors ();
|
cogl_object_unref (stage_glx->onscreen);
|
||||||
|
stage_glx->onscreen = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (stage_glx->glxwin != None)
|
static void
|
||||||
{
|
handle_swap_complete_cb (CoglFramebuffer *framebuffer,
|
||||||
glXDestroyWindow (backend_x11->xdpy, stage_glx->glxwin);
|
void *user_data)
|
||||||
stage_glx->glxwin = None;
|
{
|
||||||
}
|
ClutterStageGLX *stage_glx = user_data;
|
||||||
|
|
||||||
_clutter_stage_x11_destroy_window_untrapped (stage_x11);
|
/* Early versions of the swap_event implementation in Mesa
|
||||||
|
* deliver BufferSwapComplete event when not selected for,
|
||||||
XSync (backend_x11->xdpy, False);
|
* so if we get a swap event we aren't expecting, just ignore it.
|
||||||
|
*
|
||||||
clutter_x11_untrap_x_errors ();
|
* https://bugs.freedesktop.org/show_bug.cgi?id=27962
|
||||||
|
*
|
||||||
|
* FIXME: This issue can be hidden inside Cogl so we shouldn't
|
||||||
|
* need to care about this bug here.
|
||||||
|
*/
|
||||||
|
if (stage_glx->pending_swaps > 0)
|
||||||
|
stage_glx->pending_swaps--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -98,56 +100,53 @@ clutter_stage_glx_realize (ClutterStageWindow *stage_window)
|
|||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||||
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window);
|
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window);
|
||||||
ClutterBackendX11 *backend_x11;
|
ClutterBackend *backend;
|
||||||
ClutterBackendGLX *backend_glx;
|
ClutterBackendGLX *backend_glx;
|
||||||
|
CoglFramebuffer *framebuffer;
|
||||||
|
GError *error = NULL;
|
||||||
|
gfloat width;
|
||||||
|
gfloat height;
|
||||||
|
const char *clutter_vblank;
|
||||||
|
|
||||||
CLUTTER_NOTE (ACTOR, "Realizing stage '%s' [%p]",
|
CLUTTER_NOTE (ACTOR, "Realizing stage '%s' [%p]",
|
||||||
G_OBJECT_TYPE_NAME (stage_window),
|
G_OBJECT_TYPE_NAME (stage_window),
|
||||||
stage_window);
|
stage_window);
|
||||||
|
|
||||||
if (!_clutter_stage_x11_create_window (stage_x11))
|
backend = CLUTTER_BACKEND (stage_x11->backend);
|
||||||
return FALSE;
|
backend_glx = CLUTTER_BACKEND_GLX (stage_x11->backend);
|
||||||
|
|
||||||
backend_x11 = stage_x11->backend;
|
clutter_actor_get_size (CLUTTER_ACTOR (stage_x11->wrapper), &width, &height);
|
||||||
backend_glx = CLUTTER_BACKEND_GLX (backend_x11);
|
|
||||||
|
|
||||||
if (stage_glx->glxwin == None)
|
stage_glx->onscreen = cogl_onscreen_new (backend->cogl_context,
|
||||||
|
width, height);
|
||||||
|
if (stage_x11->xwin != None)
|
||||||
|
cogl_onscreen_x11_set_foreign_window_xid (stage_glx->onscreen,
|
||||||
|
stage_x11->xwin);
|
||||||
|
|
||||||
|
clutter_vblank = _clutter_backend_glx_get_vblank ();
|
||||||
|
if (clutter_vblank && strcmp (clutter_vblank, "none") == 0)
|
||||||
|
cogl_onscreen_set_swap_throttled (stage_glx->onscreen, FALSE);
|
||||||
|
|
||||||
|
framebuffer = COGL_FRAMEBUFFER (stage_glx->onscreen);
|
||||||
|
if (!cogl_framebuffer_allocate (framebuffer, &error))
|
||||||
{
|
{
|
||||||
int major;
|
g_warning ("Failed to allocate stage: %s", error->message);
|
||||||
int minor;
|
g_error_free (error);
|
||||||
GLXFBConfig config;
|
cogl_object_unref (stage_glx->onscreen);
|
||||||
|
stage_glx->onscreen = NULL;
|
||||||
/* Try and create a GLXWindow to use with extensions dependent on
|
return FALSE;
|
||||||
* GLX versions >= 1.3 that don't accept regular X Windows as GLX
|
|
||||||
* drawables.
|
|
||||||
*/
|
|
||||||
if (glXQueryVersion (backend_x11->xdpy, &major, &minor) &&
|
|
||||||
major == 1 && minor >= 3 &&
|
|
||||||
_clutter_backend_glx_get_fbconfig (backend_glx, &config))
|
|
||||||
{
|
|
||||||
stage_glx->glxwin = glXCreateWindow (backend_x11->xdpy,
|
|
||||||
config,
|
|
||||||
stage_x11->xwin,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GLX_INTEL_swap_event
|
if (stage_x11->xwin == None)
|
||||||
if (clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS))
|
stage_x11->xwin = cogl_onscreen_x11_get_window_xid (stage_glx->onscreen);
|
||||||
{
|
|
||||||
GLXDrawable drawable = stage_glx->glxwin
|
|
||||||
? stage_glx->glxwin
|
|
||||||
: stage_x11->xwin;
|
|
||||||
|
|
||||||
/* we unconditionally select this event because we rely on it to
|
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT))
|
||||||
* advance the master clock, and drive redraw/relayout, animations
|
{
|
||||||
* and event handling.
|
stage_glx->swap_callback_id =
|
||||||
*/
|
cogl_framebuffer_add_swap_buffers_callback (framebuffer,
|
||||||
glXSelectEvent (backend_x11->xdpy,
|
handle_swap_complete_cb,
|
||||||
drawable,
|
stage_glx);
|
||||||
GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK);
|
|
||||||
}
|
}
|
||||||
#endif /* GLX_INTEL_swap_event */
|
|
||||||
|
|
||||||
/* chain up to the StageX11 implementation */
|
/* chain up to the StageX11 implementation */
|
||||||
return clutter_stage_window_parent_iface->realize (stage_window);
|
return clutter_stage_window_parent_iface->realize (stage_window);
|
||||||
@ -311,65 +310,12 @@ clutter_stage_glx_add_redraw_clip (ClutterStageWindow *stage_window,
|
|||||||
stage_glx->initialized_redraw_clip = TRUE;
|
stage_glx->initialized_redraw_clip = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DRM
|
|
||||||
static int
|
|
||||||
drm_wait_vblank(int fd, drm_wait_vblank_t *vbl)
|
|
||||||
{
|
|
||||||
int ret, rc;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
|
|
||||||
vbl->request.type &= ~_DRM_VBLANK_RELATIVE;
|
|
||||||
rc = errno;
|
|
||||||
}
|
|
||||||
while (ret && rc == EINTR);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_DRM */
|
|
||||||
|
|
||||||
static void
|
|
||||||
wait_for_vblank (ClutterBackendGLX *backend_glx)
|
|
||||||
{
|
|
||||||
if (backend_glx->vblank_type == CLUTTER_VBLANK_NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (backend_glx->wait_video_sync)
|
|
||||||
{
|
|
||||||
unsigned int retraceCount;
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Waiting for vblank (wait_video_sync)");
|
|
||||||
backend_glx->get_video_sync (&retraceCount);
|
|
||||||
backend_glx->wait_video_sync (2,
|
|
||||||
(retraceCount + 1) % 2,
|
|
||||||
&retraceCount);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef HAVE_DRM
|
|
||||||
drm_wait_vblank_t blank;
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Waiting for vblank (drm)");
|
|
||||||
blank.request.type = _DRM_VBLANK_RELATIVE;
|
|
||||||
blank.request.sequence = 1;
|
|
||||||
blank.request.signal = 0;
|
|
||||||
drm_wait_vblank (backend_glx->dri_fd, &blank);
|
|
||||||
#else
|
|
||||||
CLUTTER_NOTE (BACKEND, "No vblank mechanism found");
|
|
||||||
#endif /* HAVE_DRM */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_glx_redraw (ClutterStageWindow *stage_window)
|
clutter_stage_glx_redraw (ClutterStageWindow *stage_window)
|
||||||
{
|
{
|
||||||
ClutterBackendX11 *backend_x11;
|
|
||||||
ClutterBackendGLX *backend_glx;
|
ClutterBackendGLX *backend_glx;
|
||||||
ClutterStageX11 *stage_x11;
|
ClutterStageX11 *stage_x11;
|
||||||
ClutterStageGLX *stage_glx;
|
ClutterStageGLX *stage_glx;
|
||||||
GLXDrawable drawable;
|
|
||||||
unsigned int video_sync_count;
|
|
||||||
gboolean may_use_clipped_redraw;
|
gboolean may_use_clipped_redraw;
|
||||||
gboolean use_clipped_redraw;
|
gboolean use_clipped_redraw;
|
||||||
|
|
||||||
@ -395,8 +341,7 @@ clutter_stage_glx_redraw (ClutterStageWindow *stage_window)
|
|||||||
|
|
||||||
stage_glx = CLUTTER_STAGE_GLX (stage_window);
|
stage_glx = CLUTTER_STAGE_GLX (stage_window);
|
||||||
|
|
||||||
backend_x11 = stage_x11->backend;
|
backend_glx = CLUTTER_BACKEND_GLX (stage_x11->backend);
|
||||||
backend_glx = CLUTTER_BACKEND_GLX (backend_x11);
|
|
||||||
|
|
||||||
CLUTTER_TIMER_START (_clutter_uprof_context, painting_timer);
|
CLUTTER_TIMER_START (_clutter_uprof_context, painting_timer);
|
||||||
|
|
||||||
@ -502,173 +447,75 @@ clutter_stage_glx_redraw (ClutterStageWindow *stage_window)
|
|||||||
cogl_object_unref (vbo);
|
cogl_object_unref (vbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
cogl_flush ();
|
|
||||||
CLUTTER_TIMER_STOP (_clutter_uprof_context, painting_timer);
|
CLUTTER_TIMER_STOP (_clutter_uprof_context, painting_timer);
|
||||||
|
|
||||||
drawable = stage_glx->glxwin
|
|
||||||
? stage_glx->glxwin
|
|
||||||
: stage_x11->xwin;
|
|
||||||
|
|
||||||
/* If we might ever use _clutter_backend_glx_blit_sub_buffer then we
|
|
||||||
* always need to keep track of the video_sync_count so that we can
|
|
||||||
* throttle blits.
|
|
||||||
*
|
|
||||||
* Note: we get the count *before* we issue any glXCopySubBuffer or
|
|
||||||
* blit_sub_buffer request in case the count would go up before
|
|
||||||
* returning control to us.
|
|
||||||
*/
|
|
||||||
if (backend_glx->can_blit_sub_buffer && backend_glx->get_video_sync)
|
|
||||||
backend_glx->get_video_sync (&video_sync_count);
|
|
||||||
|
|
||||||
/* push on the screen */
|
/* push on the screen */
|
||||||
if (use_clipped_redraw)
|
if (use_clipped_redraw)
|
||||||
{
|
{
|
||||||
ClutterGeometry *clip = &stage_glx->bounding_redraw_clip;
|
ClutterGeometry *clip = &stage_glx->bounding_redraw_clip;
|
||||||
ClutterGeometry copy_area;
|
int copy_area[4];
|
||||||
ClutterActor *actor;
|
ClutterActor *actor;
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
|
||||||
"_glx_blit_sub_buffer (window: 0x%lx, "
|
|
||||||
"x: %d, y: %d, "
|
|
||||||
"width: %d, height: %d)",
|
|
||||||
(unsigned long) drawable,
|
|
||||||
stage_glx->bounding_redraw_clip.x,
|
|
||||||
stage_glx->bounding_redraw_clip.y,
|
|
||||||
stage_glx->bounding_redraw_clip.width,
|
|
||||||
stage_glx->bounding_redraw_clip.height);
|
|
||||||
|
|
||||||
/* XXX: It seems there will be a race here in that the stage
|
/* XXX: It seems there will be a race here in that the stage
|
||||||
* window may be resized before glXCopySubBufferMESA is handled
|
* window may be resized before the cogl_framebuffer_swap_region
|
||||||
* and so we may copy the wrong region. I can't really see how
|
* is handled and so we may copy the wrong region. I can't
|
||||||
* we can handle this with the current state of X but at least
|
* really see how we can handle this with the current state of X
|
||||||
* in this case a full redraw should be queued by the resize
|
* but at least in this case a full redraw should be queued by
|
||||||
* anyway so it should only exhibit temporary artefacts.
|
* the resize anyway so it should only exhibit temporary
|
||||||
|
* artefacts.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
actor = CLUTTER_ACTOR (stage_x11->wrapper);
|
actor = CLUTTER_ACTOR (stage_x11->wrapper);
|
||||||
copy_area.y = clutter_actor_get_height (actor)
|
|
||||||
- clip->y
|
|
||||||
- clip->height;
|
|
||||||
copy_area.x = clip->x;
|
|
||||||
copy_area.width = clip->width;
|
|
||||||
copy_area.height = clip->height;
|
|
||||||
|
|
||||||
/* We need to ensure that all the rendering is done, otherwise
|
copy_area[0] = clip->x;
|
||||||
* redraw operations that are slower than the framerate can
|
copy_area[1] = clutter_actor_get_height (actor) - clip->y - clip->height;
|
||||||
* queue up in the pipeline during a heavy animation, causing a
|
copy_area[2] = clip->width;
|
||||||
* larger and larger backlog of rendering visible as lag to the
|
copy_area[3] = clip->height;
|
||||||
* user.
|
|
||||||
*
|
|
||||||
* Note: since calling glFinish() and sycnrhonizing the CPU with
|
|
||||||
* the GPU is far from ideal, we hope that this is only a short
|
|
||||||
* term solution.
|
|
||||||
* - One idea is to using sync objects to track render
|
|
||||||
* completion so we can throttle the backlog (ideally with an
|
|
||||||
* additional extension that lets us get notifications in our
|
|
||||||
* mainloop instead of having to busy wait for the
|
|
||||||
* completion.)
|
|
||||||
* - Another option is to support clipped redraws by reusing the
|
|
||||||
* contents of old back buffers such that we can flip instead
|
|
||||||
* of using a blit and then we can use GLX_INTEL_swap_events
|
|
||||||
* to throttle. For this though we would still probably want an
|
|
||||||
* additional extension so we can report the limited region of
|
|
||||||
* the window damage to X/compositors.
|
|
||||||
*/
|
|
||||||
glFinish ();
|
|
||||||
|
|
||||||
/* glXCopySubBufferMESA and glBlitFramebuffer are not integrated
|
CLUTTER_NOTE (BACKEND,
|
||||||
* with the glXSwapIntervalSGI mechanism which we usually use to
|
"cogl_framebuffer_swap_region (onscreen: %p, "
|
||||||
* throttle the Clutter framerate to the vertical refresh and so
|
"x: %d, y: %d, "
|
||||||
* we have to manually wait for the vblank period...
|
"width: %d, height: %d)",
|
||||||
*/
|
stage_glx->onscreen,
|
||||||
|
copy_area[0], copy_area[1], copy_area[2], copy_area[3]);
|
||||||
/* Here 'is_synchronized' only means that the blit won't cause a
|
|
||||||
* tear, ie it won't prevent multiple blits per retrace if they
|
|
||||||
* can all be performed in the blanking period. If that's the
|
|
||||||
* case then we still want to use the vblank sync menchanism but
|
|
||||||
* we only need it to throttle redraws.
|
|
||||||
*/
|
|
||||||
if (!backend_glx->blit_sub_buffer_is_synchronized)
|
|
||||||
{
|
|
||||||
/* XXX: note that glXCopySubBuffer, at least for Intel, is
|
|
||||||
* synchronized with the vblank but glBlitFramebuffer may
|
|
||||||
* not be so we use the same scheme we do when calling
|
|
||||||
* glXSwapBuffers without the swap_control extension and
|
|
||||||
* call glFinish () before waiting for the vblank period.
|
|
||||||
*
|
|
||||||
* See where we call glXSwapBuffers for more details.
|
|
||||||
*/
|
|
||||||
wait_for_vblank (backend_glx);
|
|
||||||
}
|
|
||||||
else if (backend_glx->get_video_sync)
|
|
||||||
{
|
|
||||||
/* If we have the GLX_SGI_video_sync extension then we can
|
|
||||||
* be a bit smarter about how we throttle blits by avoiding
|
|
||||||
* any waits if we can see that the video sync count has
|
|
||||||
* already progressed. */
|
|
||||||
if (backend_glx->last_video_sync_count == video_sync_count)
|
|
||||||
wait_for_vblank (backend_glx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
wait_for_vblank (backend_glx);
|
|
||||||
|
|
||||||
CLUTTER_TIMER_START (_clutter_uprof_context, blit_sub_buffer_timer);
|
CLUTTER_TIMER_START (_clutter_uprof_context, blit_sub_buffer_timer);
|
||||||
_clutter_backend_glx_blit_sub_buffer (backend_glx,
|
|
||||||
drawable,
|
cogl_framebuffer_swap_region (COGL_FRAMEBUFFER (stage_glx->onscreen),
|
||||||
copy_area.x,
|
copy_area, 1);
|
||||||
copy_area.y,
|
|
||||||
copy_area.width,
|
|
||||||
copy_area.height);
|
|
||||||
CLUTTER_TIMER_STOP (_clutter_uprof_context, blit_sub_buffer_timer);
|
CLUTTER_TIMER_STOP (_clutter_uprof_context, blit_sub_buffer_timer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (BACKEND, "glXSwapBuffers (display: %p, window: 0x%lx)",
|
CLUTTER_NOTE (BACKEND, "cogl_framebuffer_swap_buffers (onscreen: %p)",
|
||||||
backend_x11->xdpy,
|
stage_glx->onscreen);
|
||||||
(unsigned long) drawable);
|
|
||||||
|
|
||||||
/* If we have GLX swap buffer events then glXSwapBuffers will return
|
/* If we have swap buffer events then
|
||||||
* immediately and we need to track that there is a swap in
|
* cogl_framebuffer_swap_buffers will return immediately and we
|
||||||
* progress... */
|
* need to track that there is a swap in progress... */
|
||||||
if (clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS))
|
if (clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS))
|
||||||
stage_glx->pending_swaps++;
|
stage_glx->pending_swaps++;
|
||||||
|
|
||||||
if (backend_glx->vblank_type != CLUTTER_VBLANK_GLX_SWAP &&
|
|
||||||
backend_glx->vblank_type != CLUTTER_VBLANK_NONE)
|
|
||||||
{
|
|
||||||
/* If we are going to wait for VBLANK manually, we not only
|
|
||||||
* need to flush out pending drawing to the GPU before we
|
|
||||||
* sleep, we need to wait for it to finish. Otherwise, we
|
|
||||||
* may end up with the situation:
|
|
||||||
*
|
|
||||||
* - We finish drawing - GPU drawing continues
|
|
||||||
* - We go to sleep - GPU drawing continues
|
|
||||||
* VBLANK - We call glXSwapBuffers - GPU drawing continues
|
|
||||||
* - GPU drawing continues
|
|
||||||
* - Swap buffers happens
|
|
||||||
*
|
|
||||||
* Producing a tear. Calling glFinish() first will cause us
|
|
||||||
* to properly wait for the next VBLANK before we swap. This
|
|
||||||
* obviously does not happen when we use _GLX_SWAP and let
|
|
||||||
* the driver do the right thing
|
|
||||||
*/
|
|
||||||
glFinish ();
|
|
||||||
|
|
||||||
wait_for_vblank (backend_glx);
|
|
||||||
}
|
|
||||||
|
|
||||||
CLUTTER_TIMER_START (_clutter_uprof_context, swapbuffers_timer);
|
CLUTTER_TIMER_START (_clutter_uprof_context, swapbuffers_timer);
|
||||||
glXSwapBuffers (backend_x11->xdpy, drawable);
|
cogl_framebuffer_swap_buffers (COGL_FRAMEBUFFER (stage_glx->onscreen));
|
||||||
CLUTTER_TIMER_STOP (_clutter_uprof_context, swapbuffers_timer);
|
CLUTTER_TIMER_STOP (_clutter_uprof_context, swapbuffers_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
backend_glx->last_video_sync_count = video_sync_count;
|
|
||||||
|
|
||||||
/* reset the redraw clipping for the next paint... */
|
/* reset the redraw clipping for the next paint... */
|
||||||
stage_glx->initialized_redraw_clip = FALSE;
|
stage_glx->initialized_redraw_clip = FALSE;
|
||||||
|
|
||||||
stage_glx->frame_count++;
|
stage_glx->frame_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CoglFramebuffer *
|
||||||
|
clutter_stage_glx_get_active_framebuffer (ClutterStageWindow *stage_window)
|
||||||
|
{
|
||||||
|
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window);
|
||||||
|
|
||||||
|
return COGL_FRAMEBUFFER (stage_glx->onscreen);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||||
{
|
{
|
||||||
@ -682,55 +529,7 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
|||||||
iface->has_redraw_clips = clutter_stage_glx_has_redraw_clips;
|
iface->has_redraw_clips = clutter_stage_glx_has_redraw_clips;
|
||||||
iface->ignoring_redraw_clips = clutter_stage_glx_ignoring_redraw_clips;
|
iface->ignoring_redraw_clips = clutter_stage_glx_ignoring_redraw_clips;
|
||||||
iface->redraw = clutter_stage_glx_redraw;
|
iface->redraw = clutter_stage_glx_redraw;
|
||||||
|
iface->get_active_framebuffer = clutter_stage_glx_get_active_framebuffer;
|
||||||
|
|
||||||
/* the rest is inherited from ClutterStageX11 */
|
/* the rest is inherited from ClutterStageX11 */
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterTranslateReturn
|
|
||||||
clutter_stage_glx_translate_event (ClutterEventTranslator *translator,
|
|
||||||
gpointer native,
|
|
||||||
ClutterEvent *event)
|
|
||||||
{
|
|
||||||
#ifdef GLX_INTEL_swap_event
|
|
||||||
ClutterBackendGLX *backend_glx;
|
|
||||||
XEvent *xevent = native;
|
|
||||||
|
|
||||||
backend_glx = CLUTTER_BACKEND_GLX (clutter_get_default_backend ());
|
|
||||||
|
|
||||||
if (xevent->type == (backend_glx->event_base + GLX_BufferSwapComplete))
|
|
||||||
{
|
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (translator);
|
|
||||||
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (translator);
|
|
||||||
GLXBufferSwapComplete *swap_complete_event;
|
|
||||||
|
|
||||||
swap_complete_event = (GLXBufferSwapComplete *) xevent;
|
|
||||||
|
|
||||||
if (stage_x11->xwin == swap_complete_event->drawable)
|
|
||||||
{
|
|
||||||
/* Early versions of the swap_event implementation in Mesa
|
|
||||||
* deliver BufferSwapComplete event when not selected for,
|
|
||||||
* so if we get a swap event we aren't expecting, just ignore it.
|
|
||||||
*
|
|
||||||
* https://bugs.freedesktop.org/show_bug.cgi?id=27962
|
|
||||||
*/
|
|
||||||
if (stage_glx->pending_swaps > 0)
|
|
||||||
stage_glx->pending_swaps--;
|
|
||||||
|
|
||||||
return CLUTTER_TRANSLATE_REMOVE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* chain up to the common X11 implementation */
|
|
||||||
return clutter_event_translator_parent_iface->translate_event (translator,
|
|
||||||
native,
|
|
||||||
event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface)
|
|
||||||
{
|
|
||||||
clutter_event_translator_parent_iface = g_type_interface_peek_parent (iface);
|
|
||||||
|
|
||||||
iface->translate_event = clutter_stage_glx_translate_event;
|
|
||||||
}
|
|
||||||
|
@ -50,8 +50,9 @@ struct _ClutterStageGLX
|
|||||||
|
|
||||||
gint pending_swaps;
|
gint pending_swaps;
|
||||||
|
|
||||||
GLXPixmap glxpixmap;
|
CoglOnscreen *onscreen;
|
||||||
GLXWindow glxwin;
|
|
||||||
|
unsigned int swap_callback_id;
|
||||||
|
|
||||||
/* We only enable clipped redraws after 2 frames, since we've seen
|
/* We only enable clipped redraws after 2 frames, since we've seen
|
||||||
* a lot of drivers can struggle to get going and may output some
|
* a lot of drivers can struggle to get going and may output some
|
||||||
|
@ -134,7 +134,7 @@ cogl_xlib_filter (XEvent *xevent,
|
|||||||
ClutterX11FilterReturn retval;
|
ClutterX11FilterReturn retval;
|
||||||
CoglXlibFilterReturn ret;
|
CoglXlibFilterReturn ret;
|
||||||
|
|
||||||
ret = _cogl_xlib_handle_event (xevent);
|
ret = cogl_xlib_handle_event (xevent);
|
||||||
switch (ret)
|
switch (ret)
|
||||||
{
|
{
|
||||||
case COGL_XLIB_FILTER_REMOVE:
|
case COGL_XLIB_FILTER_REMOVE:
|
||||||
@ -390,7 +390,7 @@ _clutter_backend_x11_post_parse (ClutterBackend *backend,
|
|||||||
|
|
||||||
/* Cogl needs to know the Xlib display connection for
|
/* Cogl needs to know the Xlib display connection for
|
||||||
CoglTexturePixmapX11 */
|
CoglTexturePixmapX11 */
|
||||||
_cogl_xlib_set_display (backend_x11->xdpy);
|
cogl_xlib_set_display (backend_x11->xdpy);
|
||||||
|
|
||||||
/* add event filter for Cogl events */
|
/* add event filter for Cogl events */
|
||||||
clutter_x11_add_filter (cogl_xlib_filter, NULL);
|
clutter_x11_add_filter (cogl_xlib_filter, NULL);
|
||||||
|
@ -379,6 +379,13 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
|
|||||||
ClutterDeviceManager *device_manager;
|
ClutterDeviceManager *device_manager;
|
||||||
int event_flags;
|
int event_flags;
|
||||||
|
|
||||||
|
if (clutter_stages_by_xid == NULL)
|
||||||
|
clutter_stages_by_xid = g_hash_table_new (NULL, NULL);
|
||||||
|
|
||||||
|
g_hash_table_insert (clutter_stages_by_xid,
|
||||||
|
GINT_TO_POINTER (stage_x11->xwin),
|
||||||
|
stage_x11);
|
||||||
|
|
||||||
set_wm_pid (stage_x11);
|
set_wm_pid (stage_x11);
|
||||||
set_wm_title (stage_x11);
|
set_wm_title (stage_x11);
|
||||||
set_cursor_visible (stage_x11);
|
set_cursor_visible (stage_x11);
|
||||||
@ -1436,13 +1443,6 @@ _clutter_stage_x11_create_window (ClutterStageX11 *stage_x11)
|
|||||||
|
|
||||||
XFree (xvisinfo);
|
XFree (xvisinfo);
|
||||||
|
|
||||||
if (clutter_stages_by_xid == NULL)
|
|
||||||
clutter_stages_by_xid = g_hash_table_new (NULL, NULL);
|
|
||||||
|
|
||||||
g_hash_table_insert (clutter_stages_by_xid,
|
|
||||||
GINT_TO_POINTER (stage_x11->xwin),
|
|
||||||
stage_x11);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,6 +447,8 @@ AS_IF([test "x$SUPPORT_GLX" = "x1"],
|
|||||||
[
|
[
|
||||||
AC_DEFINE([COGL_HAS_GLX_SUPPORT], [1], [Cogl supports OpenGL using the GLX API])
|
AC_DEFINE([COGL_HAS_GLX_SUPPORT], [1], [Cogl supports OpenGL using the GLX API])
|
||||||
|
|
||||||
|
AC_DEFINE([COGL_HAS_FULL_WINSYS], [1], [Cogl can create its own OpenGL context])
|
||||||
|
|
||||||
AC_DEFINE([HAVE_CLUTTER_GLX], [1], [Have the GLX backend])
|
AC_DEFINE([HAVE_CLUTTER_GLX], [1], [Have the GLX backend])
|
||||||
|
|
||||||
AC_CHECK_HEADERS([GL/glx.h],
|
AC_CHECK_HEADERS([GL/glx.h],
|
||||||
|
Loading…
Reference in New Issue
Block a user