1
0
Fork 0

Moves all GLX code down from Clutter to Cogl

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

View file

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

View file

@ -43,6 +43,12 @@ cogl_clutter_check_extension (const char *name, const char *ext)
return _cogl_check_extension (name, ext);
}
gboolean
cogl_clutter_winsys_has_feature (CoglWinsysFeature feature)
{
return _cogl_winsys_has_feature (feature);
}
void
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);
}
#ifdef COGL_HAS_XLIB_SUPPORT
XVisualInfo *
cogl_clutter_winsys_xlib_get_visual_info (void)
{
return _cogl_winsys_xlib_get_visual_info ();
}
#endif

View file

@ -38,10 +38,20 @@ G_BEGIN_DECLS
gboolean
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
void
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
#endif /* __COGL_CLUTTER_H__ */

View file

@ -26,6 +26,11 @@
#include "cogl-internal.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
#include "cogl-context-driver-gl.h"
@ -35,7 +40,7 @@
#include "cogl-context-driver-gles.h"
#endif
#include "cogl-context-winsys.h"
#include "cogl-display-private.h"
#include "cogl-primitives.h"
#include "cogl-clip-stack.h"
#include "cogl-matrix-stack.h"
@ -55,9 +60,10 @@ struct _CoglContext
{
CoglObject _parent;
CoglDisplay *display;
/* Features cache */
CoglFeatureFlags feature_flags;
CoglFeatureFlagsPrivate feature_flags_private;
CoglFeatureFlags feature_flags;
CoglHandle default_pipeline;
CoglHandle default_layer_0;
@ -70,8 +76,6 @@ struct _CoglContext
gboolean enable_backface_culling;
CoglFrontWinding flushed_front_winding;
gboolean indirect;
/* A few handy matrix constants */
CoglMatrix identity_matrix;
CoglMatrix y_flip_matrix;
@ -237,8 +241,26 @@ struct _CoglContext
GByteArray *buffer_map_fallback_array;
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;
CoglContextWinsys winsys;
CoglBitmask winsys_features;
void *winsys;
gboolean stub_winsys;
};
CoglContext *

View file

@ -28,6 +28,8 @@
#include "cogl.h"
#include "cogl-object.h"
#include "cogl-internal.h"
#include "cogl-private.h"
#include "cogl-winsys-private.h"
#include "cogl-profile.h"
#include "cogl-util.h"
#include "cogl-context-private.h"
@ -56,13 +58,8 @@ COGL_OBJECT_DEFINE (Context, context);
extern void
_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 gboolean gl_is_indirect = FALSE;
static void
_cogl_init_feature_overrides (CoglContext *ctx)
@ -102,15 +99,8 @@ cogl_context_new (CoglDisplay *display,
CoglContext *context;
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
unsigned long enable_flags = 0;
CoglHandle window_buffer;
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
/* We need to be absolutely sure that uprof has been initialized
* 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
* code used to construct a CoglContext. Until all of that code
* 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;
/* Init default values */
_context->feature_flags = 0;
_context->feature_flags_private = 0;
context->feature_flags = 0;
context->texture_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);
else
cogl_object_ref (display);
@ -158,11 +151,32 @@ cogl_context_new (CoglDisplay *display,
return NULL;
}
/* Initialise the driver specific state */
_cogl_gl_context_init (context);
_cogl_init_feature_overrides (context);
context->display = display;
_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_layers ();
@ -174,8 +188,6 @@ cogl_context_new (CoglDisplay *display,
context->enable_backface_culling = FALSE;
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->y_flip_matrix);
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->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 ();
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->current_clip_stack_valid = FALSE;
context->dirty_bound_framebuffer = TRUE;
context->dirty_gl_viewport = TRUE;
@ -347,7 +364,7 @@ cogl_context_new (CoglDisplay *display,
static void
_cogl_context_free (CoglContext *context)
{
_cogl_destroy_context_winsys (context);
_cogl_winsys_context_deinit (context);
_cogl_destroy_texture_units ();
@ -424,6 +441,8 @@ _cogl_context_free (CoglContext *context)
g_byte_array_free (context->buffer_map_fallback_array, TRUE);
_cogl_bitmask_destroy (&context->winsys_features);
cogl_object_unref (context->display);
g_free (context);
@ -448,31 +467,12 @@ _cogl_context_get_default (void)
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
_cogl_set_indirect_context (gboolean indirect)
cogl_set_default_context (CoglContext *context)
{
/* we get called multiple times if someone creates
* 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;
}
cogl_object_ref (context);
gl_is_indirect = indirect;
if (_context)
cogl_object_unref (_context);
_context = context;
}

View file

@ -54,7 +54,12 @@ typedef struct _CoglContext CoglContext;
#define cogl_context_new cogl_context_new_EXP
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

View file

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

View file

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

View file

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

View file

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

View file

@ -31,6 +31,9 @@
#ifndef __COGL_DISPLAY_H__
#define __COGL_DISPLAY_H__
#include <cogl/cogl-renderer.h>
#include <cogl/cogl-onscreen-template.h>
G_BEGIN_DECLS
/**
@ -69,8 +72,15 @@ typedef struct _CoglDisplay CoglDisplay;
#define COGL_DISPLAY(OBJECT) ((CoglDisplay *)OBJECT)
#define cogl_display_new cogl_display_new_EXP
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

View file

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

View file

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

View file

@ -24,11 +24,20 @@
#ifndef __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-clip-state-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 {
COGL_FRAMEBUFFER_TYPE_ONSCREEN,
COGL_FRAMEBUFFER_TYPE_OFFSCREEN
@ -37,12 +46,14 @@ typedef enum _CoglFramebufferType {
struct _CoglFramebuffer
{
CoglObject _parent;
CoglContext *context;
CoglFramebufferType type;
int width;
int height;
/* Format of the pixels in the framebuffer (including the expected
premult state) */
CoglPixelFormat format;
gboolean allocated;
CoglMatrixStack *modelview_stack;
CoglMatrixStack *projection_stack;
@ -85,8 +96,6 @@ struct _CoglFramebuffer
gboolean clear_clip_dirty;
};
#define COGL_FRAMEBUFFER(X) ((CoglFramebuffer *)(X))
typedef struct _CoglOffscreen
{
CoglFramebuffer _parent;
@ -103,12 +112,18 @@ typedef enum
#define COGL_OFFSCREEN(X) ((CoglOffscreen *)(X))
typedef struct _CoglOnscreen
struct _CoglOnscreen
{
CoglFramebuffer _parent;
} CoglOnscreen;
#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X))
#ifdef COGL_HAS_X11_SUPPORT
guint32 foreign_xid;
#endif
gboolean swap_throttled;
void *winsys;
};
void
_cogl_framebuffer_state_init (void);
@ -233,7 +248,11 @@ typedef enum _CoglFramebufferFlushFlags
COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW = 1L<<0,
/* Similarly this flag implies you are going to flush the clip state
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;
void
@ -241,9 +260,6 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer,
CoglFramebufferFlushFlags flags);
CoglHandle
_cogl_onscreen_new (void);
CoglFramebuffer *
_cogl_get_read_framebuffer (void);
@ -339,5 +355,8 @@ _cogl_blit_framebuffer (unsigned int src_x,
unsigned int width,
unsigned int height);
CoglOnscreen *
_cogl_onscreen_new (void);
#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */

View file

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

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

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

View file

@ -29,7 +29,7 @@
#include "cogl-bitmask.h"
#ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
typedef enum
@ -119,99 +119,17 @@ _cogl_transform_point (const CoglMatrix *matrix_mv,
float *x,
float *y);
#ifdef COGL_HAS_XLIB_SUPPORT
#define COGL_DRIVER_ERROR (_cogl_driver_error_quark ())
/*
* CoglX11FilterReturn:
* @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 #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;
typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/
COGL_DRIVER_ERROR_UNKNOWN_VERSION,
COGL_DRIVER_ERROR_INVALID_VERSION
} CoglDriverError;
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 */

View file

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

View file

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

View file

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

View file

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

View file

@ -3,7 +3,7 @@
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010 Intel Corporation.
* 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
@ -15,30 +15,40 @@
* 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/>.
* 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_H
#define __COGL_XLIB_H
#ifndef __COGL_RENDERER_XLIB_PRIVATE_H
#define __COGL_RENDERER_XLIB_PRIVATE_H
#include "cogl.h"
#include "cogl-context-winsys.h"
#include "cogl-object-private.h"
#include "cogl-xlib-private.h"
#include "cogl-renderer-x11-private.h"
#include <X11/Xlib.h>
typedef struct _CoglXlibFilterClosure CoglXlibFilterClosure;
struct _CoglXlibFilterClosure
typedef struct _CoglRendererXlib
{
CoglXlibFilterFunc func;
gpointer data;
};
CoglRendererX11 _parent;
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.
*
* Traps every X error until _cogl_xlib_untrap_errors() called. You
@ -50,10 +60,11 @@ struct _CoglXlibFilterClosure
* pointers in reverse order.
*/
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().
*
* 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
*/
int
_cogl_xlib_untrap_errors (CoglXlibTrapState *state);
_cogl_renderer_xlib_untrap_errors (CoglRenderer *renderer,
CoglXlibTrapState *state);
#endif /* __COGL_XLIB_H */
#endif /* __COGL_RENDERER_XLIB_PRIVATE_H */

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

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

View file

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

View file

@ -30,6 +30,11 @@
#include <glib-object.h>
#include <cogl/cogl-defines.h>
#ifdef COGL_HAS_XLIB
#include <X11/Xlib.h>
#endif
G_BEGIN_DECLS
/* 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_SHADERS_ARBFP = (1 << 20),
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;
/**
@ -582,11 +588,84 @@ typedef enum
COGL_DEPTH_TEST_FUNCTION_GEQUAL = 0x0206,
COGL_DEPTH_TEST_FUNCTION_ALWAYS = 0x0207
} 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 */
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
#endif /* __COGL_TYPES_H__ */

View file

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

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

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

View file

@ -3,7 +3,7 @@
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010 Intel Corporation.
* 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
@ -34,24 +34,36 @@
#include <cogl-handle.h>
#include <cogl-context-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/extensions/Xdamage.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
context is created */
static Display *_cogl_xlib_display = NULL;
CoglXlibFilterReturn
_cogl_xlib_handle_event (XEvent *xevent)
cogl_xlib_handle_event (XEvent *xevent)
{
GSList *l;
_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 */
for (l = ctx->winsys.event_filters; l; l = l->next)
for (l = ctx->event_filters; l; l = l->next)
{
CoglXlibFilterClosure *closure = l->data;
@ -70,10 +82,13 @@ _cogl_xlib_handle_event (XEvent *xevent)
}
Display *
_cogl_xlib_get_display (void)
cogl_xlib_get_display (void)
{
_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 */
g_assert (_cogl_xlib_display != NULL);
@ -81,7 +96,7 @@ _cogl_xlib_get_display (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 */
g_assert (_cogl_xlib_display == NULL);
@ -91,29 +106,43 @@ _cogl_xlib_set_display (Display *display)
void
_cogl_xlib_add_filter (CoglXlibFilterFunc func,
gpointer data)
void *data)
{
CoglXlibFilterClosure *closure;
_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->func = func;
closure->data = data;
ctx->winsys.event_filters =
g_slist_prepend (ctx->winsys.event_filters, closure);
ctx->event_filters =
g_slist_prepend (ctx->event_filters, closure);
}
void
_cogl_xlib_remove_filter (CoglXlibFilterFunc func,
gpointer data)
void *data)
{
GSList *l, *prev = NULL;
_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;
@ -123,8 +152,8 @@ _cogl_xlib_remove_filter (CoglXlibFilterFunc func,
if (prev)
prev->next = g_slist_delete_link (prev->next, l);
else
ctx->winsys.event_filters =
g_slist_delete_link (ctx->winsys.event_filters, l);
ctx->event_filters =
g_slist_delete_link (ctx->event_filters, l);
break;
}
}
@ -136,9 +165,9 @@ error_handler (Display *xdpy,
{
_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;
}
@ -148,11 +177,17 @@ _cogl_xlib_trap_errors (CoglXlibTrapState *state)
{
_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->old_error_handler = XSetErrorHandler (error_handler);
state->old_state = ctxt->winsys.trap_state;
ctxt->winsys.trap_state = state;
state->old_state = ctxt->trap_state;
ctxt->trap_state = state;
}
int
@ -160,11 +195,44 @@ _cogl_xlib_untrap_errors (CoglXlibTrapState *state)
{
_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);
ctxt->winsys.trap_state = state->old_state;
ctxt->trap_state = state->old_state;
return state->trapped_error_code;
}
void
_cogl_xlib_query_damage_extension (void)
{
int damage_error;
_COGL_GET_CONTEXT (ctxt, NO_RETVAL);
/* Check whether damage events are supported on this display */
if (!XDamageQueryExtension (cogl_xlib_get_display (),
&ctxt->damage_base,
&damage_error))
ctxt->damage_base = -1;
}
int
_cogl_xlib_get_damage_base (void)
{
_COGL_GET_CONTEXT (ctxt, -1);
if (!ctxt->stub_winsys)
{
CoglRendererX11 *x11_renderer = ctxt->display->renderer->winsys;
return x11_renderer->damage_base;
}
else
return ctxt->damage_base;
}

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

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

View file

@ -38,7 +38,7 @@
#include "cogl-context-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-winsys.h"
#include "cogl-winsys-private.h"
#include "cogl-framebuffer-private.h"
#include "cogl-matrix-private.h"
#include "cogl-journal-private.h"
@ -394,14 +394,6 @@ cogl_features_available (CoglFeatureFlags 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
* integers, or removed/deprecated and make the
* _cogl_framebuffer_get_viewport* functions public.

View file

@ -67,7 +67,12 @@
#include <cogl/cogl-deprecated.h>
typedef struct _CoglFramebuffer CoglFramebuffer;
#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-buffer.h>
#include <cogl/cogl-pixel-array.h>
@ -79,6 +84,13 @@
#include <cogl/cogl-attribute.h>
#include <cogl/cogl-primitive.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
G_BEGIN_DECLS
@ -90,8 +102,6 @@ G_BEGIN_DECLS
* General utility functions for COGL.
*/
typedef struct _CoglFramebuffer CoglFramebuffer;
/**
* cogl_get_option_group:
*
@ -1245,44 +1255,6 @@ cogl_begin_gl (void);
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
#undef __COGL_H_INSIDE__

View file

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

View file

@ -29,6 +29,7 @@
#include "cogl.h"
#include "cogl-private.h"
#include "cogl-internal.h"
#include "cogl-context-private.h"
#include "cogl-feature-private.h"
@ -95,7 +96,7 @@ _cogl_get_gl_version (int *major_out, int *minor_out)
}
gboolean
_cogl_check_driver_valid (GError **error)
_cogl_gl_check_version (GError **error)
{
int major, minor;
const char *gl_extensions;
@ -161,8 +162,8 @@ _cogl_check_driver_valid (GError **error)
namespaces, extension_names, \
feature_flags, feature_flags_private) \
{ min_gl_major, min_gl_minor, namespaces, \
extension_names, feature_flags, feature_flags_private, \
cogl_feature_ ## name ## _funcs },
extension_names, feature_flags, feature_flags_private, 0, \
cogl_feature_ ## name ## _funcs },
#undef COGL_FEATURE_FUNCTION
#define COGL_FEATURE_FUNCTION(ret, name, args)
#undef COGL_FEATURE_END
@ -182,23 +183,35 @@ static const CoglFeatureData cogl_feature_data[] =
#define COGL_FEATURE_END()
static void
initialize_context_driver (CoglContext *context)
initialize_function_table (CoglContext *context)
{
#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
_cogl_gl_context_init (CoglContext *context)
_cogl_gl_update_features (CoglContext *context)
{
CoglFeatureFlags flags = 0;
CoglFeatureFlagsPrivate flags_private = 0;
const char *gl_extensions;
int max_clip_planes = 0;
int num_stencil_bits = 0;
int gl_major = 0, gl_minor = 0;
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);
@ -235,16 +248,15 @@ _cogl_gl_context_init (CoglContext *context)
if (max_clip_planes >= 4)
flags |= COGL_FEATURE_FOUR_CLIP_PLANES;
initialize_function_table (context);
for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++)
if (_cogl_feature_check ("GL", cogl_feature_data + i,
gl_major, gl_minor,
gl_extensions))
{
flags |= cogl_feature_data[i].feature_flags;
flags_private |= cogl_feature_data[i].feature_flags_private;
}
gl_extensions,
context))
flags |= cogl_feature_data[i].feature_flags;
/* Cache features */
context->feature_flags = flags;
context->feature_flags_private = flags_private;
context->feature_flags |= flags;
}

View file

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

View file

@ -33,7 +33,7 @@
#include "cogl-feature-private.h"
gboolean
_cogl_check_driver_valid (GError **error)
_cogl_gl_check_version (GError **error)
{
/* The GLES backend doesn't have any particular version requirements */
return TRUE;
@ -58,8 +58,8 @@ _cogl_check_driver_valid (GError **error)
namespaces, extension_names, \
feature_flags, feature_flags_private) \
{ min_gl_major, min_gl_minor, namespaces, \
extension_names, feature_flags, feature_flags_private, \
cogl_feature_ ## name ## _funcs },
extension_names, feature_flags, feature_flags_private, 0, \
cogl_feature_ ## name ## _funcs },
#undef COGL_FEATURE_FUNCTION
#define COGL_FEATURE_FUNCTION(ret, name, args)
#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)
#undef COGL_FEATURE_FUNCTION
#define COGL_FEATURE_FUNCTION(ret, name, args) \
_context->drv.pf_ ## name = NULL;
context->drv.pf_ ## name = NULL;
#undef COGL_FEATURE_END
#define COGL_FEATURE_END()
static void
initialize_context_driver (CoglContext *context)
initialize_function_table (CoglContext *context)
{
#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
_cogl_gl_context_init (CoglContext *context)
_cogl_gl_update_features (CoglContext *context)
{
CoglFeatureFlags flags = 0;
const char *gl_extensions;
#ifndef HAVE_COGL_GLES2
int max_clip_planes = 0;
#endif
int num_stencil_bits = 0;
const char *gl_extensions;
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);
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) );
/* 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 */
flags |= COGL_FEATURE_POINT_SPRITE;
/* Cache features */
context->feature_flags = flags;
}
initialize_function_table (context);
for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++)
if (_cogl_feature_check ("GL", cogl_feature_data + i,
0, 0,
gl_extensions,
context))
flags |= cogl_feature_data[i].feature_flags;
/* Cache features */
context->feature_flags |= flags;
}

View file

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

View file

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

View file

@ -42,7 +42,11 @@
#include "cogl-texture-rectangle-private.h"
#include "cogl-context-private.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 <X11/Xlib.h>
@ -55,9 +59,6 @@
#include <string.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);
COGL_TEXTURE_DEFINE (TexturePixmapX11, texture_pixmap_x11);
@ -112,7 +113,7 @@ process_damage_event (CoglTexturePixmapX11 *tex_pixmap,
_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);
@ -206,10 +207,12 @@ static CoglXlibFilterReturn
_cogl_texture_pixmap_x11_filter (XEvent *event, gpointer data)
{
CoglTexturePixmapX11 *tex_pixmap = data;
int damage_base;
_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;
@ -228,26 +231,28 @@ get_fbconfig_for_depth (unsigned int depth,
gboolean *can_mipmap_ret)
{
GLXFBConfig *fbconfigs;
int n_elements, i;
Display *dpy;
int db, stencil, alpha, mipmap, rgba, value;
int spare_cache_slot = 0;
gboolean found = FALSE;
int n_elements, i;
Display *dpy;
int db, stencil, alpha, mipmap, rgba, value;
int spare_cache_slot = 0;
gboolean found = FALSE;
CoglDisplayGLX *glx_display;
_COGL_GET_CONTEXT (ctxt, FALSE);
glx_display = ctxt->display->winsys;
/* Check if we've already got a cached config for this depth */
for (i = 0; i < COGL_WINSYS_N_CACHED_CONFIGS; i++)
if (ctxt->winsys.glx_cached_configs[i].depth == -1)
for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++)
if (glx_display->glx_cached_configs[i].depth == -1)
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;
*can_mipmap_ret = ctxt->winsys.glx_cached_configs[i].can_mipmap;
return ctxt->winsys.glx_cached_configs[i].found;
*fbconfig_ret = glx_display->glx_cached_configs[i].fb_config;
*can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap;
return glx_display->glx_cached_configs[i].found;
}
dpy = _cogl_xlib_get_display ();
dpy = cogl_xlib_get_display ();
fbconfigs = glXGetFBConfigs (dpy, DefaultScreen (dpy),
&n_elements);
@ -349,10 +354,10 @@ get_fbconfig_for_depth (unsigned int depth,
if (n_elements)
XFree (fbconfigs);
ctxt->winsys.glx_cached_configs[spare_cache_slot].depth = depth;
ctxt->winsys.glx_cached_configs[spare_cache_slot].found = found;
ctxt->winsys.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].depth = depth;
glx_display->glx_cached_configs[spare_cache_slot].found = found;
glx_display->glx_cached_configs[spare_cache_slot].fb_config = *fbconfig_ret;
glx_display->glx_cached_configs[spare_cache_slot].can_mipmap = mipmap;
return found;
}
@ -362,7 +367,7 @@ should_use_rectangle (void)
{
_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))
{
@ -378,7 +383,7 @@ should_use_rectangle (void)
the env var is set to 'allow' or not set and NPOTs textures
are not available */
ctxt->winsys.rectangle_state =
ctxt->rectangle_state =
cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) ?
COGL_WINSYS_RECTANGLE_STATE_DISABLE :
COGL_WINSYS_RECTANGLE_STATE_ENABLE;
@ -389,10 +394,10 @@ should_use_rectangle (void)
(rect_env = g_getenv ("CLUTTER_PIXMAP_TEXTURE_RECTANGLE")))
{
if (g_ascii_strcasecmp (rect_env, "force") == 0)
ctxt->winsys.rectangle_state =
ctxt->rectangle_state =
COGL_WINSYS_RECTANGLE_STATE_ENABLE;
else if (g_ascii_strcasecmp (rect_env, "disable") == 0)
ctxt->winsys.rectangle_state =
ctxt->rectangle_state =
COGL_WINSYS_RECTANGLE_STATE_DISABLE;
else if (g_ascii_strcasecmp (rect_env, "allow"))
g_warning ("Unknown value for COGL_PIXMAP_TEXTURE_RECTANGLE, "
@ -400,10 +405,10 @@ should_use_rectangle (void)
}
}
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
@ -425,11 +430,10 @@ try_create_glx_pixmap (CoglTexturePixmapX11 *tex_pixmap,
tex_pixmap->pixmap_bound = FALSE;
tex_pixmap->glx_pixmap = None;
if ((ctxt->winsys.feature_flags &
COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP) == 0)
if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP))
return;
dpy = _cogl_xlib_get_display ();
dpy = cogl_xlib_get_display ();
if (!get_fbconfig_for_depth (tex_pixmap->depth, &fb_config,
&tex_pixmap->glx_can_mipmap))
@ -507,7 +511,7 @@ set_damage_object_internal (CoglTexturePixmapX11 *tex_pixmap,
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;
}
}
@ -524,12 +528,13 @@ cogl_texture_pixmap_x11_new (guint32 pixmap,
gboolean automatic_updates)
{
CoglTexturePixmapX11 *tex_pixmap = g_new (CoglTexturePixmapX11, 1);
Display *display = _cogl_xlib_get_display ();
Display *display = cogl_xlib_get_display ();
Window pixmap_root_window;
int pixmap_x, pixmap_y;
unsigned int pixmap_border_width;
CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
XWindowAttributes window_attributes;
int damage_base;
_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
supports damage events then we'll register a damage object on the
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,
pixmap,
@ -601,7 +607,7 @@ try_alloc_shm (CoglTexturePixmapX11 *tex_pixmap)
XImage *dummy_image;
Display *display;
display = _cogl_xlib_get_display ();
display = cogl_xlib_get_display ();
if (!XShmQueryExtension (display))
return;
@ -709,13 +715,15 @@ cogl_texture_pixmap_x11_set_damage_object (CoglHandle handle,
report_level)
{
CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle);
int damage_base;
_COGL_GET_CONTEXT (ctxt, NO_RETVAL);
if (!cogl_is_texture_pixmap_x11 (tex_pixmap))
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);
}
@ -728,7 +736,7 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
int src_x, src_y;
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 (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)
{
CoglXlibTrapState trap_state;
CoglRendererGLX *glx_renderer;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
glx_renderer = ctx->display->renderer->winsys;
if (tex_pixmap->pixmap_bound)
glXReleaseTexImage (_cogl_xlib_get_display (), tex_pixmap->glx_pixmap,
GLX_FRONT_LEFT_EXT);
glx_renderer->pf_glXReleaseTexImage (cogl_xlib_get_display (),
tex_pixmap->glx_pixmap,
GLX_FRONT_LEFT_EXT);
/* FIXME - we need to trap errors and synchronize here because
* 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
*/
_cogl_xlib_trap_errors (&trap_state);
glXDestroyPixmap (_cogl_xlib_get_display (), tex_pixmap->glx_pixmap);
XSync (_cogl_xlib_get_display (), False);
glXDestroyPixmap (cogl_xlib_get_display (), tex_pixmap->glx_pixmap);
XSync (cogl_xlib_get_display (), False);
_cogl_xlib_untrap_errors (&trap_state);
tex_pixmap->glx_pixmap = None;
@ -927,8 +938,10 @@ _cogl_texture_pixmap_x11_update_glx_texture (CoglTexturePixmapX11 *tex_pixmap,
gboolean needs_mipmap)
{
gboolean ret = TRUE;
CoglRendererGLX *glx_renderer;
_COGL_GET_CONTEXT (ctx, FALSE);
glx_renderer = ctx->display->renderer->winsys;
/* If we don't have a GLX pixmap then fallback */
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) );
if (tex_pixmap->pixmap_bound)
glXReleaseTexImage (_cogl_xlib_get_display (),
tex_pixmap->glx_pixmap,
GLX_FRONT_LEFT_EXT);
glx_renderer->pf_glXReleaseTexImage (cogl_xlib_get_display (),
tex_pixmap->glx_pixmap,
GLX_FRONT_LEFT_EXT);
glXBindTexImage (_cogl_xlib_get_display (),
tex_pixmap->glx_pixmap,
GLX_FRONT_LEFT_EXT,
NULL);
glx_renderer->pf_glXBindTexImage (cogl_xlib_get_display (),
tex_pixmap->glx_pixmap,
GLX_FRONT_LEFT_EXT,
NULL);
/* According to the recommended usage in the spec for
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)
{
XShmDetach (_cogl_xlib_get_display (), &tex_pixmap->shm_info);
XShmDetach (cogl_xlib_get_display (), &tex_pixmap->shm_info);
shmdt (tex_pixmap->shm_info.shmaddr);
shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0);
}

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,95 @@
#ifndef __COGL_WINSYS_PRIVATE_H
#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
_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 */

View file

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

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

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