2006-06-08 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-main.c: * clutter/clutter-private.h: * clutter/clutter-stage.c: Rework and fix offscreen rendering, also rejig GLX context handling, moving mostly into stage. Require at least OpenGL 1.2 ( CLAMP_TO_EDGE ) * clutter/clutter-texture.c: Explicity set props on _init() as to avoid nasty can_create bug failing miserably in certain situations. Switch to CLAMP_TO_EDGE for textures to avoid tile seams. Add some more GL error checks. * clutter/clutter-label.c: Extra debug info * configure.ac: Require gdk-pixbuf-xlib-2.0
This commit is contained in:
parent
f00e84606c
commit
9c572ff45a
@ -317,6 +317,7 @@ clutter_label_init (ClutterLabel *self)
|
|||||||
pango_ft2_font_map_substitute_changed (font_map);
|
pango_ft2_font_map_substitute_changed (font_map);
|
||||||
g_object_unref (font_map);
|
g_object_unref (font_map);
|
||||||
*/
|
*/
|
||||||
|
CLUTTER_MARK();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -332,6 +333,8 @@ ClutterElement *
|
|||||||
clutter_label_new_with_text (const gchar *font_name,
|
clutter_label_new_with_text (const gchar *font_name,
|
||||||
const gchar *text)
|
const gchar *text)
|
||||||
{
|
{
|
||||||
|
CLUTTER_MARK();
|
||||||
|
|
||||||
return g_object_new (CLUTTER_TYPE_LABEL,
|
return g_object_new (CLUTTER_TYPE_LABEL,
|
||||||
"font-name", font_name,
|
"font-name", font_name,
|
||||||
"text", text,
|
"text", text,
|
||||||
|
@ -42,9 +42,6 @@ typedef struct
|
|||||||
}
|
}
|
||||||
ClutterXEventSource;
|
ClutterXEventSource;
|
||||||
|
|
||||||
#define GLX_SAMPLE_BUFFERS_ARB 100000
|
|
||||||
#define GLX_SAMPLES_ARB 100001
|
|
||||||
|
|
||||||
typedef void (*ClutterXEventFunc) (XEvent *xev, gpointer user_data);
|
typedef void (*ClutterXEventFunc) (XEvent *xev, gpointer user_data);
|
||||||
|
|
||||||
static gboolean __clutter_has_debug = FALSE;
|
static gboolean __clutter_has_debug = FALSE;
|
||||||
@ -289,19 +286,21 @@ clutter_redraw (void)
|
|||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
unsigned int retraceCount;
|
unsigned int retraceCount;
|
||||||
|
/* Wait for vertical retrace */
|
||||||
// Wait for vertical retrace
|
/* glXGetVideoSyncSGI(&retraceCount); */
|
||||||
// glXGetVideoSyncSGI(&retraceCount);
|
/* glXWaitVideoSyncSGI(2, (retraceCount+1)%2, &retraceCount); */
|
||||||
// glXWaitVideoSyncSGI(2, (retraceCount+1)%2, &retraceCount);
|
|
||||||
glXWaitVideoSyncSGI(1, 0, &retraceCount);
|
glXWaitVideoSyncSGI(1, 0, &retraceCount);
|
||||||
#endif
|
#endif
|
||||||
glXSwapBuffers(ctx->xdpy, clutter_stage_get_xwindow (stage));
|
glXSwapBuffers(ctx->xdpy, clutter_stage_get_xwindow (stage));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glFlush();
|
glXWaitGL();
|
||||||
|
CLUTTER_GLERR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (clutter_want_fps ())
|
if (clutter_want_fps ())
|
||||||
{
|
{
|
||||||
timer_n_frames++;
|
timer_n_frames++;
|
||||||
@ -439,19 +438,6 @@ clutter_root_xwindow (void)
|
|||||||
return ClutterCntx->xwin_root;
|
return ClutterCntx->xwin_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* clutter_xvisual:
|
|
||||||
*
|
|
||||||
* FIXME
|
|
||||||
*
|
|
||||||
* Return value: FIXME
|
|
||||||
*/
|
|
||||||
XVisualInfo*
|
|
||||||
clutter_xvisual (void)
|
|
||||||
{
|
|
||||||
return ClutterCntx->xvinfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_want_debug:
|
* clutter_want_debug:
|
||||||
*
|
*
|
||||||
@ -465,18 +451,6 @@ clutter_want_debug (void)
|
|||||||
return __clutter_has_debug;
|
return __clutter_has_debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* clutter_gl_context_set_indirect:
|
|
||||||
* @indirect: FIXME
|
|
||||||
*
|
|
||||||
* FIXME
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
clutter_gl_context_set_indirect (gboolean indirect)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ClutterMainContext*
|
ClutterMainContext*
|
||||||
clutter_context_get_default (void)
|
clutter_context_get_default (void)
|
||||||
{
|
{
|
||||||
@ -493,6 +467,32 @@ clutter_context_get_default (void)
|
|||||||
return ClutterCntx;
|
return ClutterCntx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_gl_version_at_least_12 (void)
|
||||||
|
{
|
||||||
|
#define NON_VENDOR_VERSION_MAX_LEN 32
|
||||||
|
gchar non_vendor_version[NON_VENDOR_VERSION_MAX_LEN];
|
||||||
|
const gchar *version;
|
||||||
|
gint i = 0;
|
||||||
|
|
||||||
|
version = (const gchar*)glGetString(GL_VERSION);
|
||||||
|
|
||||||
|
while ( ((version[i] <= '9' && version[i] >= '0') || version[i] == '.')
|
||||||
|
&& i < NON_VENDOR_VERSION_MAX_LEN)
|
||||||
|
{
|
||||||
|
non_vendor_version[i] = version[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
non_vendor_version[i] = '\0';
|
||||||
|
|
||||||
|
if (strstr (non_vendor_version, "1.0") == NULL
|
||||||
|
&& strstr (non_vendor_version, "1.0") == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_init:
|
* clutter_init:
|
||||||
* @argc: FIXME
|
* @argc: FIXME
|
||||||
@ -506,20 +506,8 @@ int
|
|||||||
clutter_init (int *argc, char ***argv)
|
clutter_init (int *argc, char ***argv)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context;
|
ClutterMainContext *context;
|
||||||
XVisualInfo *vinfo;
|
|
||||||
static gboolean is_initialized = FALSE;
|
static gboolean is_initialized = FALSE;
|
||||||
|
|
||||||
int gl_attributes[] = {
|
|
||||||
GLX_RGBA,
|
|
||||||
GLX_DOUBLEBUFFER,
|
|
||||||
GLX_RED_SIZE, 1,
|
|
||||||
GLX_GREEN_SIZE, 1,
|
|
||||||
GLX_BLUE_SIZE, 1,
|
|
||||||
/* GLX_DEPTH_SIZE, 1, */
|
|
||||||
/* GLX_DEPTH_SIZE, 32, */
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
if (is_initialized)
|
if (is_initialized)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -545,22 +533,13 @@ clutter_init (int *argc, char ***argv)
|
|||||||
|
|
||||||
if ((context->xdpy = XOpenDisplay (g_getenv ("DISPLAY"))) == NULL)
|
if ((context->xdpy = XOpenDisplay (g_getenv ("DISPLAY"))) == NULL)
|
||||||
{
|
{
|
||||||
g_warning("Unable to connect to X DISPLAY.");
|
g_critical ("Unable to connect to X DISPLAY.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->xscreen = DefaultScreen(context->xdpy);
|
context->xscreen = DefaultScreen(context->xdpy);
|
||||||
context->xwin_root = RootWindow(context->xdpy,
|
context->xwin_root = RootWindow(context->xdpy,
|
||||||
context->xscreen);
|
context->xscreen);
|
||||||
context->xvinfo = glXChooseVisual (context->xdpy,
|
|
||||||
context->xscreen,
|
|
||||||
gl_attributes);
|
|
||||||
if (!context->xvinfo)
|
|
||||||
{
|
|
||||||
g_warning ("Unable to find suitable GL visual.");
|
|
||||||
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
context->font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
|
context->font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
|
||||||
pango_ft2_font_map_set_resolution (context->font_map, 96.0, 96.0);
|
pango_ft2_font_map_set_resolution (context->font_map, 96.0, 96.0);
|
||||||
@ -571,6 +550,12 @@ clutter_init (int *argc, char ***argv)
|
|||||||
g_return_val_if_fail (CLUTTER_IS_STAGE (context->stage), -3);
|
g_return_val_if_fail (CLUTTER_IS_STAGE (context->stage), -3);
|
||||||
clutter_element_realize (CLUTTER_ELEMENT (context->stage));
|
clutter_element_realize (CLUTTER_ELEMENT (context->stage));
|
||||||
|
|
||||||
|
g_return_val_if_fail
|
||||||
|
(CLUTTER_ELEMENT_IS_REALIZED(CLUTTER_ELEMENT(context->stage)), -4);
|
||||||
|
|
||||||
|
/* At least GL 1.2 is needed for CLAMP_TO_EDGE */
|
||||||
|
g_return_val_if_fail(is_gl_version_at_least_12 (), -5);
|
||||||
|
|
||||||
events_init ();
|
events_init ();
|
||||||
|
|
||||||
context->is_initialized = TRUE;
|
context->is_initialized = TRUE;
|
||||||
|
@ -52,8 +52,6 @@ struct _ClutterMainContext
|
|||||||
Display *xdpy;
|
Display *xdpy;
|
||||||
Window xwin_root;
|
Window xwin_root;
|
||||||
int xscreen;
|
int xscreen;
|
||||||
XVisualInfo *xvinfo;
|
|
||||||
|
|
||||||
GC xgc;
|
GC xgc;
|
||||||
|
|
||||||
PangoFT2FontMap *font_map;
|
PangoFT2FontMap *font_map;
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
|
||||||
|
#include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
|
||||||
|
|
||||||
/* the stage is a singleton instance */
|
/* the stage is a singleton instance */
|
||||||
static ClutterStage *stage_singleton = NULL;
|
static ClutterStage *stage_singleton = NULL;
|
||||||
|
|
||||||
@ -45,6 +47,7 @@ G_DEFINE_TYPE (ClutterStage, clutter_stage, CLUTTER_TYPE_GROUP);
|
|||||||
|
|
||||||
struct _ClutterStagePrivate
|
struct _ClutterStagePrivate
|
||||||
{
|
{
|
||||||
|
XVisualInfo *xvisinfo;
|
||||||
Window xwin;
|
Window xwin;
|
||||||
Pixmap xpixmap;
|
Pixmap xpixmap;
|
||||||
gint xwin_width, xwin_height; /* FIXME target_width / height */
|
gint xwin_width, xwin_height; /* FIXME target_width / height */
|
||||||
@ -52,6 +55,7 @@ struct _ClutterStagePrivate
|
|||||||
GLXPixmap glxpixmap;
|
GLXPixmap glxpixmap;
|
||||||
GLXContext gl_context;
|
GLXContext gl_context;
|
||||||
|
|
||||||
|
|
||||||
ClutterColor color;
|
ClutterColor color;
|
||||||
|
|
||||||
guint want_fullscreen : 1;
|
guint want_fullscreen : 1;
|
||||||
@ -245,8 +249,12 @@ clutter_stage_unrealize (ClutterElement *element)
|
|||||||
stage = CLUTTER_STAGE(element);
|
stage = CLUTTER_STAGE(element);
|
||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
|
|
||||||
|
CLUTTER_MARK();
|
||||||
|
|
||||||
if (priv->want_offscreen)
|
if (priv->want_offscreen)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
if (priv->glxpixmap)
|
if (priv->glxpixmap)
|
||||||
{
|
{
|
||||||
glXDestroyGLXPixmap (clutter_xdisplay(), priv->glxpixmap);
|
glXDestroyGLXPixmap (clutter_xdisplay(), priv->glxpixmap);
|
||||||
@ -267,6 +275,10 @@ clutter_stage_unrealize (ClutterElement *element)
|
|||||||
priv->xwin = None;
|
priv->xwin = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glXMakeCurrent(clutter_xdisplay(), None, NULL);
|
||||||
|
glXDestroyContext (clutter_xdisplay(), priv->gl_context);
|
||||||
|
priv->gl_context = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -279,31 +291,105 @@ clutter_stage_realize (ClutterElement *element)
|
|||||||
|
|
||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
|
|
||||||
|
CLUTTER_MARK();
|
||||||
|
|
||||||
if (priv->want_offscreen)
|
if (priv->want_offscreen)
|
||||||
{
|
{
|
||||||
priv->xpixmap = XCreatePixmap (clutter_xdisplay(),
|
int gl_attributes[] = {
|
||||||
clutter_root_xwindow(),
|
GLX_RGBA,
|
||||||
priv->xwin_width, priv->xwin_height,
|
GLX_RED_SIZE, 1,
|
||||||
clutter_xvisual()->depth);
|
GLX_GREEN_SIZE, 1,
|
||||||
|
GLX_BLUE_SIZE, 1,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
priv->glxpixmap = glXCreateGLXPixmap(clutter_xdisplay(),
|
if (priv->xvisinfo)
|
||||||
clutter_xvisual(),
|
XFree(priv->xvisinfo);
|
||||||
priv->xpixmap);
|
|
||||||
sync_fullscreen (stage);
|
priv->xvisinfo = glXChooseVisual (clutter_xdisplay(),
|
||||||
|
clutter_xscreen(),
|
||||||
|
gl_attributes);
|
||||||
|
if (!priv->xvisinfo)
|
||||||
|
{
|
||||||
|
g_critical ("Unable to find suitable GL visual.");
|
||||||
|
CLUTTER_ELEMENT_UNSET_FLAGS (element, CLUTTER_ELEMENT_REALIZED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->gl_context)
|
if (priv->gl_context)
|
||||||
glXDestroyContext (clutter_xdisplay(), priv->gl_context);
|
glXDestroyContext (clutter_xdisplay(), priv->gl_context);
|
||||||
|
|
||||||
|
priv->xpixmap = XCreatePixmap (clutter_xdisplay(),
|
||||||
|
clutter_root_xwindow(),
|
||||||
|
priv->xwin_width,
|
||||||
|
priv->xwin_height,
|
||||||
|
priv->xvisinfo->depth);
|
||||||
|
|
||||||
|
priv->glxpixmap = glXCreateGLXPixmap(clutter_xdisplay(),
|
||||||
|
priv->xvisinfo,
|
||||||
|
priv->xpixmap);
|
||||||
|
sync_fullscreen (stage);
|
||||||
|
|
||||||
/* indirect */
|
/* indirect */
|
||||||
priv->gl_context = glXCreateContext (clutter_xdisplay(),
|
priv->gl_context = glXCreateContext (clutter_xdisplay(),
|
||||||
clutter_xvisual(),
|
priv->xvisinfo,
|
||||||
0,
|
0,
|
||||||
False);
|
False);
|
||||||
|
|
||||||
glXMakeCurrent(clutter_xdisplay(), priv->glxpixmap, priv->gl_context);
|
glXMakeCurrent(clutter_xdisplay(), priv->glxpixmap, priv->gl_context);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Debug code for monitoring a off screen pixmap via window */
|
||||||
|
{
|
||||||
|
Colormap cmap;
|
||||||
|
XSetWindowAttributes swa;
|
||||||
|
|
||||||
|
cmap = XCreateColormap(clutter_xdisplay(),
|
||||||
|
clutter_root_xwindow(),
|
||||||
|
priv->xvisinfo->visual, AllocNone);
|
||||||
|
|
||||||
|
/* create a window */
|
||||||
|
swa.colormap = cmap;
|
||||||
|
|
||||||
|
foo_win = XCreateWindow(clutter_xdisplay(),
|
||||||
|
clutter_root_xwindow(),
|
||||||
|
0, 0,
|
||||||
|
priv->xwin_width, priv->xwin_height,
|
||||||
|
0,
|
||||||
|
priv->xvisinfo->depth,
|
||||||
|
InputOutput,
|
||||||
|
priv->xvisinfo->visual,
|
||||||
|
CWColormap, &swa);
|
||||||
|
|
||||||
|
XMapWindow(clutter_xdisplay(), foo_win);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int gl_attributes[] =
|
||||||
|
{
|
||||||
|
GLX_RGBA,
|
||||||
|
GLX_DOUBLEBUFFER,
|
||||||
|
GLX_RED_SIZE, 1,
|
||||||
|
GLX_GREEN_SIZE, 1,
|
||||||
|
GLX_BLUE_SIZE, 1,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
if (priv->xvisinfo)
|
||||||
|
XFree(priv->xvisinfo);
|
||||||
|
|
||||||
|
priv->xvisinfo = glXChooseVisual (clutter_xdisplay(),
|
||||||
|
clutter_xscreen(),
|
||||||
|
gl_attributes);
|
||||||
|
if (!priv->xvisinfo)
|
||||||
|
{
|
||||||
|
g_critical ("Unable to find suitable GL visual.");
|
||||||
|
CLUTTER_ELEMENT_UNSET_FLAGS (element, CLUTTER_ELEMENT_REALIZED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
priv->xwin = XCreateSimpleWindow(clutter_xdisplay(),
|
priv->xwin = XCreateSimpleWindow(clutter_xdisplay(),
|
||||||
clutter_root_xwindow(),
|
clutter_root_xwindow(),
|
||||||
0, 0,
|
0, 0,
|
||||||
@ -329,13 +415,20 @@ clutter_stage_realize (ClutterElement *element)
|
|||||||
glXDestroyContext (clutter_xdisplay(), priv->gl_context);
|
glXDestroyContext (clutter_xdisplay(), priv->gl_context);
|
||||||
|
|
||||||
priv->gl_context = glXCreateContext (clutter_xdisplay(),
|
priv->gl_context = glXCreateContext (clutter_xdisplay(),
|
||||||
clutter_xvisual(),
|
priv->xvisinfo,
|
||||||
0,
|
0,
|
||||||
True);
|
True);
|
||||||
|
|
||||||
glXMakeCurrent(clutter_xdisplay(), priv->xwin, priv->gl_context);
|
glXMakeCurrent(clutter_xdisplay(), priv->xwin, priv->gl_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLUTTER_DBG("===========================================")
|
||||||
|
CLUTTER_DBG("GL_VENDOR: %s\n", glGetString(GL_VENDOR));
|
||||||
|
CLUTTER_DBG("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
|
||||||
|
CLUTTER_DBG("GL_VERSION: %s\n", glGetString(GL_VERSION));
|
||||||
|
CLUTTER_DBG("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));
|
||||||
|
CLUTTER_DBG("===========================================")
|
||||||
|
|
||||||
sync_gl_viewport (stage);
|
sync_gl_viewport (stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,6 +532,12 @@ clutter_stage_set_property (GObject *object,
|
|||||||
if (priv->want_offscreen != g_value_get_boolean (value))
|
if (priv->want_offscreen != g_value_get_boolean (value))
|
||||||
{
|
{
|
||||||
clutter_element_unrealize (CLUTTER_ELEMENT(stage));
|
clutter_element_unrealize (CLUTTER_ELEMENT(stage));
|
||||||
|
/* NOTE: as we are changing GL contexts here. so
|
||||||
|
* all textures will need unreleasing as they will
|
||||||
|
* likely have set up ( i.e labels ) in the old
|
||||||
|
* context. We should probably somehow do this
|
||||||
|
* automatically
|
||||||
|
*/
|
||||||
priv->want_offscreen = g_value_get_boolean (value);
|
priv->want_offscreen = g_value_get_boolean (value);
|
||||||
clutter_element_realize (CLUTTER_ELEMENT(stage));
|
clutter_element_realize (CLUTTER_ELEMENT(stage));
|
||||||
}
|
}
|
||||||
@ -530,7 +629,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
|||||||
"Fullscreen",
|
"Fullscreen",
|
||||||
"Make Clutter stage fullscreen",
|
"Make Clutter stage fullscreen",
|
||||||
FALSE,
|
FALSE,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(gobject_class, PROP_OFFSCREEN,
|
(gobject_class, PROP_OFFSCREEN,
|
||||||
@ -538,7 +637,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
|||||||
"Offscreen",
|
"Offscreen",
|
||||||
"Make Clutter stage offscreen",
|
"Make Clutter stage offscreen",
|
||||||
FALSE,
|
FALSE,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
@ -547,7 +646,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
|||||||
"Hide Cursor",
|
"Hide Cursor",
|
||||||
"Make Clutter stage cursor-less",
|
"Make Clutter stage cursor-less",
|
||||||
FALSE,
|
FALSE,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(gobject_class, PROP_COLOR,
|
(gobject_class, PROP_COLOR,
|
||||||
@ -693,6 +792,20 @@ clutter_stage_get_xwindow (ClutterStage *stage)
|
|||||||
return stage->priv->xwin;
|
return stage->priv->xwin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_stage_get_xvisual
|
||||||
|
* @stage: A #ClutterStage
|
||||||
|
*
|
||||||
|
* Get the stages XVisualInfo.
|
||||||
|
*
|
||||||
|
* Return Value: Thes Stages XVisualInfo
|
||||||
|
**/
|
||||||
|
const XVisualInfo*
|
||||||
|
clutter_stage_get_xvisual (ClutterStage *stage)
|
||||||
|
{
|
||||||
|
return stage->priv->xvisinfo;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_stage_set_color
|
* clutter_stage_set_color
|
||||||
* @stage: A #ClutterStage
|
* @stage: A #ClutterStage
|
||||||
@ -776,10 +889,13 @@ clutter_stage_snapshot (ClutterStage *stage,
|
|||||||
guchar *data;
|
guchar *data;
|
||||||
GdkPixbuf *pixb, *fpixb;
|
GdkPixbuf *pixb, *fpixb;
|
||||||
ClutterElement *element;
|
ClutterElement *element;
|
||||||
|
ClutterStagePrivate *priv;
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||||
g_return_val_if_fail (x >= 0 && y >= 0, NULL);
|
g_return_val_if_fail (x >= 0 && y >= 0, NULL);
|
||||||
|
|
||||||
|
priv = stage->priv;
|
||||||
|
|
||||||
element = CLUTTER_ELEMENT (stage);
|
element = CLUTTER_ELEMENT (stage);
|
||||||
|
|
||||||
if (width < 0)
|
if (width < 0)
|
||||||
@ -788,32 +904,46 @@ clutter_stage_snapshot (ClutterStage *stage,
|
|||||||
if (height < 0)
|
if (height < 0)
|
||||||
height = clutter_element_get_height (element);
|
height = clutter_element_get_height (element);
|
||||||
|
|
||||||
data = g_malloc0 (sizeof (guchar) * width * height * 3);
|
|
||||||
|
if (priv->want_offscreen)
|
||||||
|
{
|
||||||
|
gdk_pixbuf_xlib_init (clutter_xdisplay(), clutter_xscreen());
|
||||||
|
|
||||||
|
pixb = gdk_pixbuf_xlib_get_from_drawable
|
||||||
|
(NULL,
|
||||||
|
(Drawable)priv->xpixmap,
|
||||||
|
DefaultColormap(clutter_xdisplay(),
|
||||||
|
clutter_xscreen()),
|
||||||
|
priv->xvisinfo->visual,
|
||||||
|
x, y, 0, 0, width, height);
|
||||||
|
return pixb;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = g_malloc0 (sizeof (guchar) * width * height * 4);
|
||||||
|
|
||||||
glReadPixels (x,
|
glReadPixels (x,
|
||||||
clutter_element_get_height (element)
|
clutter_element_get_height (element)
|
||||||
- y - height,
|
- y - height,
|
||||||
width,
|
width,
|
||||||
height, GL_RGB, GL_UNSIGNED_BYTE, data);
|
height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
|
||||||
pixb = gdk_pixbuf_new_from_data (data,
|
pixb = gdk_pixbuf_new_from_data (data,
|
||||||
GDK_COLORSPACE_RGB,
|
GDK_COLORSPACE_RGB,
|
||||||
FALSE,
|
TRUE,
|
||||||
8,
|
8,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
width * 3,
|
width * 4,
|
||||||
snapshot_pixbuf_free,
|
snapshot_pixbuf_free,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (pixb == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
fpixb = gdk_pixbuf_flip (pixb, TRUE);
|
fpixb = gdk_pixbuf_flip (pixb, TRUE);
|
||||||
|
|
||||||
g_object_unref (pixb);
|
g_object_unref (pixb);
|
||||||
|
|
||||||
return fpixb;
|
return fpixb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,7 +40,7 @@ G_DEFINE_TYPE (ClutterTexture, clutter_texture, CLUTTER_TYPE_ELEMENT);
|
|||||||
#define PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
|
#define PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define OVERLAP 0
|
#define OVERLAP 0 /* Dont need as CLAMP_TO_EDGE */
|
||||||
|
|
||||||
/* FIXME: actually use */
|
/* FIXME: actually use */
|
||||||
typedef struct ClutterTextureTileDimention
|
typedef struct ClutterTextureTileDimention
|
||||||
@ -103,15 +103,15 @@ can_create (int width,
|
|||||||
|
|
||||||
CLUTTER_DBG("checking %ix%i", width, height);
|
CLUTTER_DBG("checking %ix%i", width, height);
|
||||||
|
|
||||||
|
|
||||||
glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA,
|
glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA,
|
||||||
width, height, 0 /* border */,
|
width, height, 0 /* border */,
|
||||||
pixel_format, pixel_type, NULL);
|
pixel_format, pixel_type, NULL);
|
||||||
|
|
||||||
|
CLUTTER_GLERR();
|
||||||
|
|
||||||
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0,
|
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0,
|
||||||
GL_TEXTURE_WIDTH, &new_width);
|
GL_TEXTURE_WIDTH, &new_width);
|
||||||
|
|
||||||
|
|
||||||
return new_width != 0;
|
return new_width != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,9 +165,6 @@ init_tiles (ClutterTexture *texture)
|
|||||||
x_pot = clutter_util_next_p2 (priv->width);
|
x_pot = clutter_util_next_p2 (priv->width);
|
||||||
y_pot = clutter_util_next_p2 (priv->height);
|
y_pot = clutter_util_next_p2 (priv->height);
|
||||||
|
|
||||||
if (x_pot - priv->width > priv->max_tile_waste
|
|
||||||
&& y_pot - priv->height > priv->max_tile_waste)
|
|
||||||
{
|
|
||||||
while (!(can_create (x_pot, y_pot, priv->pixel_format, priv->pixel_type)
|
while (!(can_create (x_pot, y_pot, priv->pixel_format, priv->pixel_type)
|
||||||
&& (x_pot - priv->width < priv->max_tile_waste)
|
&& (x_pot - priv->width < priv->max_tile_waste)
|
||||||
&& (y_pot - priv->height < priv->max_tile_waste)))
|
&& (y_pot - priv->height < priv->max_tile_waste)))
|
||||||
@ -183,7 +180,6 @@ init_tiles (ClutterTexture *texture)
|
|||||||
else
|
else
|
||||||
y_pot /= 2;
|
y_pot /= 2;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->x_tiles)
|
if (priv->x_tiles)
|
||||||
g_free(priv->x_tiles);
|
g_free(priv->x_tiles);
|
||||||
@ -290,11 +286,11 @@ texture_render_to_gl_quad (ClutterTexture *texture,
|
|||||||
glTexCoord2f (tx, 0); glVertex2i (qx2, qy1);
|
glTexCoord2f (tx, 0); glVertex2i (qx2, qy1);
|
||||||
glEnd ();
|
glEnd ();
|
||||||
|
|
||||||
lasty += qy2 - qy1;
|
lasty += (qy2 - qy1) ;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
lastx += qx2 - qx1;
|
lastx += (qx2 - qx1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,11 +372,11 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture)
|
|||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D,
|
glTexParameteri(GL_TEXTURE_2D,
|
||||||
GL_TEXTURE_WRAP_S,
|
GL_TEXTURE_WRAP_S,
|
||||||
priv->repeat_x ? GL_REPEAT : GL_CLAMP);
|
priv->repeat_x ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D,
|
glTexParameteri(GL_TEXTURE_2D,
|
||||||
GL_TEXTURE_WRAP_T,
|
GL_TEXTURE_WRAP_T,
|
||||||
priv->repeat_y ? GL_REPEAT : GL_CLAMP);
|
priv->repeat_y ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||||
priv->filter_quality ? GL_LINEAR : GL_NEAREST);
|
priv->filter_quality ? GL_LINEAR : GL_NEAREST);
|
||||||
@ -490,11 +486,11 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture)
|
|||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D,
|
glTexParameteri(GL_TEXTURE_2D,
|
||||||
GL_TEXTURE_WRAP_S,
|
GL_TEXTURE_WRAP_S,
|
||||||
priv->repeat_x ? GL_REPEAT : GL_CLAMP);
|
priv->repeat_x ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D,
|
glTexParameteri(GL_TEXTURE_2D,
|
||||||
GL_TEXTURE_WRAP_T,
|
GL_TEXTURE_WRAP_T,
|
||||||
priv->repeat_y ? GL_REPEAT : GL_CLAMP);
|
priv->repeat_y ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||||
priv->filter_quality ? GL_LINEAR : GL_NEAREST);
|
priv->filter_quality ? GL_LINEAR : GL_NEAREST);
|
||||||
@ -876,8 +872,23 @@ clutter_texture_init (ClutterTexture *self)
|
|||||||
ClutterTexturePrivate *priv;
|
ClutterTexturePrivate *priv;
|
||||||
|
|
||||||
priv = g_new0 (ClutterTexturePrivate, 1);
|
priv = g_new0 (ClutterTexturePrivate, 1);
|
||||||
|
|
||||||
|
/* FIXME: It seems defaults via props do not get set
|
||||||
|
* on all props for sub classes ( ie labels ).
|
||||||
|
* Should they be ?
|
||||||
|
*
|
||||||
|
* Setting them here also to be sure + safe.
|
||||||
|
*/
|
||||||
|
priv->max_tile_waste = 64;
|
||||||
|
priv->filter_quality = 0;
|
||||||
|
priv->tiled = TRUE;
|
||||||
|
priv->pixel_type = PIXEL_TYPE;
|
||||||
|
priv->pixel_format = GL_RGBA;
|
||||||
|
priv->repeat_x = FALSE;
|
||||||
|
priv->repeat_y = FALSE;
|
||||||
priv->pixbuf = NULL;
|
priv->pixbuf = NULL;
|
||||||
|
|
||||||
|
|
||||||
self->priv = priv;
|
self->priv = priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user