Add a CoglTexturePixmapX11 texture backend

This is a publicly exposed texture backend to create a texture which
contains the contents of an X11 pixmap. The API is currently marked as
experimental.

The backend internally holds a handle to another texture. All of the
backend virtuals simply redirect to the internal texture.

The texture can optionally be automatically updated if the
automatic_updates parameter is TRUE. If set then Cogl will listen for
damage events on the pixmap and update the texture accordingly.
Alternatively a damage object can be created externally and passed
down to Cogl.

The updates can be performed with XGetImage, XShmGetImage or the
GLX_EXT_texture_pixmap extension. If the TFP extension is used it will
optionally try to create a rectangle texture if the driver does not
support NPOTs or it is forced through the
COGL_PIXMAP_TEXTURE_RECTANGLE or CLUTTER_PIXMAP_TEXTURE_RECTANGLE
environment variables.

If the GLXFBConfig does not support mipmapping then it will fallback
to using X{Shm,}GetImage. It keeps a separate texture around for this
so that it can later start using the TFP texture again if the texture
is later drawn with mipmaps disabled.
This commit is contained in:
Neil Roberts 2010-05-25 18:56:14 +01:00
parent 9c62265939
commit 8458fb7e20
9 changed files with 1758 additions and 7 deletions

View File

@ -162,9 +162,14 @@ libclutter_cogl_la_LIBADD = -lm $(CLUTTER_LIBS) $(top_builddir)/clutter/cogl/cog
libclutter_cogl_la_SOURCES = $(BUILT_SOURCES) $(cogl_sources_c)
if SUPPORT_XLIB
cogl_public_h += \
$(srcdir)/winsys/cogl-texture-pixmap-x11.h
libclutter_cogl_la_SOURCES += \
$(srcdir)/winsys/cogl-xlib.h \
$(srcdir)/winsys/cogl-xlib.c
$(srcdir)/winsys/cogl-xlib.c \
$(srcdir)/winsys/cogl-texture-pixmap-x11.c \
$(srcdir)/winsys/cogl-texture-pixmap-x11-private.h
endif
if SUPPORT_GLX
libclutter_cogl_la_SOURCES += \

View File

@ -51,7 +51,8 @@ static const GDebugKey cogl_log_debug_keys[] = {
{ "opengl", COGL_DEBUG_OPENGL },
{ "pango", COGL_DEBUG_PANGO },
{ "show-source", COGL_DEBUG_SHOW_SOURCE},
{ "offscreen", COGL_DEBUG_OFFSCREEN }
{ "offscreen", COGL_DEBUG_OFFSCREEN },
{ "texture-pixmap", COGL_DEBUG_TEXTURE_PIXMAP }
};
static const int n_cogl_log_debug_keys =
G_N_ELEMENTS (cogl_log_debug_keys);
@ -113,6 +114,7 @@ _cogl_parse_debug_string (const char *value,
/* XXX: we should replace the "draw" option its very hand wavy... */
OPT ("draw:", "misc tracing of some drawing operations");
OPT ("pango:", "trace the pango renderer");
OPT ("texture-pixmap:", "trace the Cogl texture pixmap backend");
OPT ("rectangles:", "add wire outlines for all rectangular geometry");
OPT ("disable-batching:", "disable the journal batching");
OPT ("disable-vbos:", "disable use of OpenGL vertex buffer objects");

View File

@ -51,7 +51,8 @@ typedef enum {
COGL_DEBUG_DISABLE_ARBFP = 1 << 20,
COGL_DEBUG_DISABLE_GLSL = 1 << 21,
COGL_DEBUG_SHOW_SOURCE = 1 << 22,
COGL_DEBUG_DISABLE_BLENDING = 1 << 23
COGL_DEBUG_DISABLE_BLENDING = 1 << 23,
COGL_DEBUG_TEXTURE_PIXMAP = 1 << 24
} CoglDebugFlags;
#ifdef COGL_ENABLE_DEBUG

View File

@ -93,9 +93,31 @@ void
_cogl_create_context_winsys (CoglContext *context)
{
#ifdef COGL_HAS_XLIB_SUPPORT
context->winsys.event_filters = NULL;
{
Display *display = _cogl_xlib_get_display ();
int damage_error;
context->winsys.trap_state = NULL;
/* 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);

View File

@ -25,12 +25,17 @@
#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_STUB /* no features are defined yet */
COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP = 1
} CoglWinsysFeatureFlags;
#ifdef COGL_HAS_XLIB_SUPPORT
@ -47,7 +52,28 @@ struct _CoglXlibTrapState
CoglXlibTrapState *old_state;
};
#endif
#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;
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
{
@ -55,12 +81,22 @@ typedef struct
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)

View File

@ -0,0 +1,92 @@
/*
* 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_TEXTURE_PIXMAP_X11_PRIVATE_H
#define __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/Xdamage.h>
#include <sys/shm.h>
#ifdef COGL_HAS_GLX_SUPPORT
#include <GL/glx.h>
#endif
#include "cogl-handle.h"
#include "cogl-texture-private.h"
#define COGL_TEXTURE_PIXMAP_X11(tex) ((CoglTexturePixmapX11 *) tex)
typedef struct _CoglDamageRectangle CoglDamageRectangle;
struct _CoglDamageRectangle
{
unsigned int x1;
unsigned int y1;
unsigned int x2;
unsigned int y2;
};
typedef struct _CoglTexturePixmapX11 CoglTexturePixmapX11;
struct _CoglTexturePixmapX11
{
CoglTexture _parent;
Pixmap pixmap;
CoglHandle tex;
unsigned int depth;
Visual *visual;
unsigned int width;
unsigned int height;
XImage *image;
XShmSegmentInfo shm_info;
Damage damage;
CoglTexturePixmapX11ReportLevel damage_report_level;
gboolean damage_owned;
CoglDamageRectangle damage_rect;
#ifdef COGL_HAS_GLX_SUPPORT
/* During the pre_paint method, this will be set to TRUE if we
should use the GLX texture, otherwise we will use the regular
texture */
gboolean use_glx_texture;
CoglHandle glx_tex;
GLXPixmap glx_pixmap;
gboolean glx_pixmap_has_mipmap;
gboolean glx_can_mipmap;
gboolean bind_tex_image_queued;
gboolean pixmap_bound;
#endif
};
GQuark
_cogl_handle_texture_pixmap_x11_get_type (void);
#endif /* __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,176 @@
/*
* 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_TEXTURE_PIXMAP_X11_H
#define __COGL_TEXTURE_PIXMAP_X11_H
#include <cogl/cogl.h>
#ifdef COGL_ENABLE_EXPERIMENTAL_API
typedef enum
{
COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES,
COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES,
COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX,
COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY
} CoglTexturePixmapX11ReportLevel;
/**
* cogl_texture_pixmap_x11_new:
* @pixmap: A X11 pixmap ID
* @automatic_updates: Whether to automatically copy the contents of
* the pixmap to the texture.
*
* Creates a texture that contains the contents of @pixmap. If
* @automatic_updates is %TRUE then Cogl will attempt to listen for
* damage events on the pixmap and automatically update the texture
* when it changes.
*
* Return value: a CoglHandle to a texture
*
* Since: 1.2
* Stability: Unstable
*/
CoglHandle
cogl_texture_pixmap_x11_new (guint32 pixmap,
gboolean automatic_updates);
/**
* cogl_texture_pixmap_x11_update_area:
* @handle: A CoglHandle to a CoglTexturePixmapX11 instance
* @x: x coordinate of the area to update
* @y: y coordinate of the area to update
* @width: width of the area to update
* @height: height of the area to update
*
* Forces an update of the texture pointed to by @handle so that it is
* refreshed with the contents of the pixmap that was given to
* cogl_texture_pixmap_x11_new().
*
* Since: 1.2
* Stability: Unstable
*/
void
cogl_texture_pixmap_x11_update_area (CoglHandle handle,
int x,
int y,
int width,
int height);
/**
* cogl_texture_pixmap_x11_is_using_tfp_extension:
* @handle: A CoglHandle to a CoglTexturePixmapX11 instance
*
* Return value: whether the texture is using the
* GLX_EXT_texture_from_pixmap or similar extension to copy the
* contents of the pixmap to the texture. This extension is usually
* implemented as zero-copy so it implies the updates are working
* efficiently.
*
* Since: 1.2
* Stability: Unstable
*/
gboolean
cogl_texture_pixmap_x11_is_using_tfp_extension (CoglHandle handle);
/**
* cogl_texture_pixmap_x11_set_damage_object:
* @handle: A CoglHandle
* @damage: A X11 Damage object or 0
* @report_level: The report level which describes how to interpret
* the damage events. This should match the level that the damage
* object was created with.
*
* Sets the damage object that will be used to track automatic updates
* to the texture. Damage tracking can be disabled by passing 0 for
* @damage. Otherwise this damage will replace the one used if %TRUE
* was passed for automatic_updates to cogl_texture_pixmap_x11_new().
*
* Note that Cogl will subtract from the damage region as it processes
* damage events.
*/
void
cogl_texture_pixmap_x11_set_damage_object (CoglHandle handle,
guint32 damage,
CoglTexturePixmapX11ReportLevel
report_level);
/**
* cogl_is_texture_pixmap_x11:
* @handle: A CoglHandle
*
* Return value: whether @handle points to a CoglTexturePixmapX11
* instance.
*
* Since: 1.2
* Stability: Unstable
*/
gboolean
cogl_is_texture_pixmap_x11 (CoglHandle handle);
/* All of the cogl-texture-pixmap-x11 API is currently experimental so
we suffix the actual symbols with _EXP to ensure ABI
compatibility. A bunch of defines translates the symbols documented
above into the real symbols */
CoglHandle
cogl_texture_pixmap_x11_new_EXP (guint32 pixmap,
gboolean automatic_updates);
#define cogl_texture_pixmap_x11_new cogl_texture_pixmap_x11_new_EXP
void
cogl_texture_pixmap_x11_update_area_EXP (CoglHandle handle,
int x,
int y,
int width,
int height);
#define cogl_texture_pixmap_x11_update_area \
cogl_texture_pixmap_x11_update_area_EXP
gboolean
cogl_texture_pixmap_x11_is_using_tfp_extension_EXP (CoglHandle handle);
#define cogl_texture_pixmap_x11_is_using_tfp_extension \
cogl_texture_pixmap_x11_is_using_tfp_extension_EXP
gboolean
cogl_is_texture_pixmap_x11_EXP (CoglHandle handle);
#define cogl_is_texture_pixmap_x11 \
cogl_is_texture_pixmap_x11_EXP
void
cogl_texture_pixmap_x11_set_damage_object_EXP (CoglHandle handle,
guint32 damage,
CoglTexturePixmapX11ReportLevel
report_level);
#define cogl_texture_pixmap_x11_set_damage_object \
cogl_texture_pixmap_x11_set_damage_object_EXP
#endif /* COGL_ENABLE_EXPERIMENTAL_API */
#endif /* __COGL_TEXTURE_PIXMAP_X11_H */

View File

@ -23,3 +23,23 @@
/* 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