summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Reveman <davidr@novell.com>2006-03-13 14:23:44 +0000
committerDavid Reveman <davidr@novell.com>2006-03-13 14:23:44 +0000
commit0ea6d11c7107d774ac0c563aa32578633522ac39 (patch)
treec7b8402737588d1448d981f375e9a62f6c8aa0f5
parent1c50002ff39dc1add5e80394b4a16000c7a2d0cb (diff)
Add support for avoiding context switches
-rw-r--r--ChangeLog23
-rw-r--r--src/agl/glitz_agl_context.c8
-rw-r--r--src/agl/glitz_agl_drawable.c7
-rw-r--r--src/agl/glitz_aglint.h3
-rw-r--r--src/egl/glitz_egl_context.c8
-rw-r--r--src/egl/glitz_egl_surface.c6
-rw-r--r--src/egl/glitz_eglint.h3
-rw-r--r--src/glitz_buffer.c18
-rw-r--r--src/glitz_drawable.c21
-rw-r--r--src/glitz_framebuffer.c14
-rw-r--r--src/glitz_gl.h3
-rw-r--r--src/glitz_pixel.c86
-rw-r--r--src/glitz_surface.c6
-rw-r--r--src/glitzint.h5
-rw-r--r--src/glx/glitz_glx_context.c29
-rw-r--r--src/glx/glitz_glx_drawable.c4
-rw-r--r--src/glx/glitz_glx_info.c6
-rw-r--r--src/glx/glitz_glxint.h3
-rw-r--r--src/wgl/glitz_wgl_context.c8
-rw-r--r--src/wgl/glitz_wgl_drawable.c5
-rw-r--r--src/wgl/glitz_wglint.h3
21 files changed, 220 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index ae57540..1718cf7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,28 @@
2006-03-13 David Reveman <davidr@novell.com>
+ * src/glitz_pixel.c (glitz_set_pixels):
+ * src/glitz_gl.h:
+ Add experimental code for avoiding context switches when uploading
+ pixel data.
+
+ * src/agl/glitz_glx_context.c:
+ * src/agl/glitz_glx_drawable.c:
+ * src/agl/glitz_glxint.h:
+ * src/agl/glitz_egl_context.c:
+ * src/agl/glitz_egl_surface.c:
+ * src/agl/glitz_eglint.h:
+ * src/agl/glitz_wgl_context.c:
+ * src/agl/glitz_wgl_drawable.c:
+ * src/agl/glitz_wglint.h:
+ * src/agl/glitz_agl_context.c:
+ * src/agl/glitz_agl_drawable.c:
+ * src/agl/glitz_aglint.h:
+ * src/glitzint.h:
+ * src/glitz_surface.c:
+ * src/glitz_framebuffer.c:
+ * src/glitz_drawable.c:
+ * src/glitz_buffer.c: Add support for avoiding context switches.
+
* src/egl/glitz_egl_context.c (glitz_egl_context_get):
* src/egl/glitz_wgl_context.c (glitz_wgl_context_get):
* src/egl/glitz_agl_context.c (glitz_agl_context_get):
diff --git a/src/agl/glitz_agl_context.c b/src/agl/glitz_agl_context.c
index 14b54fb..01708f1 100644
--- a/src/agl/glitz_agl_context.c
+++ b/src/agl/glitz_agl_context.c
@@ -424,6 +424,8 @@ _glitz_agl_context_update (glitz_agl_drawable_t *drawable,
{
AGLContext context;
+ drawable->base.flushed = drawable->base.finished = 0;
+
switch (constraint) {
case GLITZ_NONE:
break;
@@ -473,13 +475,17 @@ _glitz_agl_context_update (glitz_agl_drawable_t *drawable,
glitz_bool_t
glitz_agl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
- glitz_constraint_t constraint)
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state)
{
glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *)
abstract_drawable;
glitz_agl_context_info_t *context_info;
int index;
+ if (restore_state)
+ *restore_state = 0;
+
index = drawable->thread_info->context_stack_size++;
context_info = &drawable->thread_info->context_stack[index];
diff --git a/src/agl/glitz_agl_drawable.c b/src/agl/glitz_agl_drawable.c
index 04b1a7b..96fab39 100644
--- a/src/agl/glitz_agl_drawable.c
+++ b/src/agl/glitz_agl_drawable.c
@@ -57,7 +57,7 @@ _glitz_agl_create_drawable (glitz_agl_thread_info_t *thread_info,
width, height);
if (!context->initialized) {
- glitz_agl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT);
+ glitz_agl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT, NULL);
glitz_agl_pop_current (drawable);
}
@@ -203,7 +203,7 @@ glitz_agl_destroy (void *abstract_drawable)
* be our last chance to have a context current.
*/
glitz_agl_push_current (abstract_drawable, NULL,
- GLITZ_CONTEXT_CURRENT);
+ GLITZ_CONTEXT_CURRENT, NULL);
glitz_program_map_fini (drawable->base.backend->gl,
&drawable->thread_info->program_map);
glitz_program_map_init (&drawable->thread_info->program_map);
@@ -241,7 +241,8 @@ glitz_agl_swap_buffers (void *abstract_drawable)
glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *)
abstract_drawable;
- glitz_agl_push_current (abstract_drawable, NULL, GLITZ_DRAWABLE_CURRENT);
+ glitz_agl_push_current (abstract_drawable, NULL, GLITZ_DRAWABLE_CURRENT,
+ NULL);
aglSwapBuffers (drawable->context->context);
glitz_agl_pop_current (abstract_drawable);
diff --git a/src/agl/glitz_aglint.h b/src/agl/glitz_aglint.h
index e25a81f..998bc09 100644
--- a/src/agl/glitz_aglint.h
+++ b/src/agl/glitz_aglint.h
@@ -119,7 +119,8 @@ glitz_agl_create_pbuffer (void *abstract_templ,
extern glitz_bool_t __internal_linkage
glitz_agl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
- glitz_constraint_t constraint);
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state);
extern glitz_surface_t __internal_linkage *
glitz_agl_pop_current (void *abstract_drawable);
diff --git a/src/egl/glitz_egl_context.c b/src/egl/glitz_egl_context.c
index 9ccb557..407b068 100644
--- a/src/egl/glitz_egl_context.c
+++ b/src/egl/glitz_egl_context.c
@@ -325,6 +325,8 @@ _glitz_egl_context_update (glitz_egl_surface_t *drawable,
{
EGLContext egl_context;
+ drawable->base.flushed = drawable->base.finished = 0;
+
switch (constraint) {
case GLITZ_NONE:
break;
@@ -365,12 +367,16 @@ _glitz_egl_context_update (glitz_egl_surface_t *drawable,
glitz_bool_t
glitz_egl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
- glitz_constraint_t constraint)
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state)
{
glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable;
glitz_egl_context_info_t *context_info;
int index;
+ if (restore_state)
+ *restore_state = 0;
+
index = drawable->screen_info->context_stack_size++;
context_info = &drawable->screen_info->context_stack[index];
diff --git a/src/egl/glitz_egl_surface.c b/src/egl/glitz_egl_surface.c
index 6a20688..c42e2fc 100644
--- a/src/egl/glitz_egl_surface.c
+++ b/src/egl/glitz_egl_surface.c
@@ -55,7 +55,7 @@ _glitz_egl_create_surface (glitz_egl_screen_info_t *screen_info,
width, height);
if (!context->initialized) {
- glitz_egl_push_current (surface, NULL, GLITZ_CONTEXT_CURRENT);
+ glitz_egl_push_current (surface, NULL, GLITZ_CONTEXT_CURRENT, NULL);
glitz_egl_pop_current (surface);
}
@@ -212,10 +212,10 @@ glitz_egl_destroy (void *abstract_drawable)
* be our last chance to have a context current.
*/
glitz_egl_push_current (abstract_drawable, NULL,
- GLITZ_CONTEXT_CURRENT);
+ GLITZ_CONTEXT_CURRENT, NULL);
glitz_program_map_fini (surface->base.backend->gl,
&surface->screen_info->program_map);
- glitz_program_map_init (&surface->screen_info->program_map);
+ glitz_program_map_init (&surface->screen_info->program_map);
glitz_egl_pop_current (abstract_drawable);
}
diff --git a/src/egl/glitz_eglint.h b/src/egl/glitz_eglint.h
index 9ed052f..f58ea0a 100644
--- a/src/egl/glitz_eglint.h
+++ b/src/egl/glitz_eglint.h
@@ -143,7 +143,8 @@ glitz_egl_create_pbuffer (void *abstract_templ,
extern glitz_bool_t __internal_linkage
glitz_egl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
- glitz_constraint_t constraint);
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state);
extern glitz_surface_t __internal_linkage *
glitz_egl_pop_current (void *abstract_drawable);
diff --git a/src/glitz_buffer.c b/src/glitz_buffer.c
index d2a64c0..079d8e3 100644
--- a/src/glitz_buffer.c
+++ b/src/glitz_buffer.c
@@ -80,7 +80,7 @@ _glitz_buffer_init (glitz_buffer_t *buffer,
glitz_drawable_reference (drawable);
drawable->backend->push_current (drawable, NULL,
- GLITZ_ANY_CONTEXT_CURRENT);
+ GLITZ_ANY_CONTEXT_CURRENT, NULL);
gl->gen_buffers (1, &buffer->name);
if (buffer->name) {
@@ -219,7 +219,8 @@ glitz_buffer_destroy (glitz_buffer_t *buffer)
if (buffer->drawable) {
buffer->drawable->backend->push_current (buffer->drawable, NULL,
- GLITZ_ANY_CONTEXT_CURRENT);
+ GLITZ_ANY_CONTEXT_CURRENT,
+ NULL);
buffer->drawable->backend->gl->delete_buffers (1, &buffer->name);
buffer->drawable->backend->pop_current (buffer->drawable);
glitz_drawable_destroy (buffer->drawable);
@@ -248,7 +249,8 @@ glitz_buffer_set_data (glitz_buffer_t *buffer,
GLITZ_GL_DRAWABLE (buffer->drawable);
buffer->drawable->backend->push_current (buffer->drawable, NULL,
- GLITZ_ANY_CONTEXT_CURRENT);
+ GLITZ_ANY_CONTEXT_CURRENT,
+ NULL);
gl->bind_buffer (buffer->target, buffer->name);
gl->buffer_sub_data (buffer->target, offset, size, data);
gl->bind_buffer (buffer->target, 0);
@@ -268,8 +270,8 @@ glitz_buffer_get_data (glitz_buffer_t *buffer,
GLITZ_GL_DRAWABLE (buffer->drawable);
buffer->drawable->backend->push_current (buffer->drawable, NULL,
- GLITZ_ANY_CONTEXT_CURRENT);
-
+ GLITZ_ANY_CONTEXT_CURRENT,
+ NULL);
gl->bind_buffer (buffer->target, buffer->name);
gl->get_buffer_sub_data (buffer->target, offset, size, data);
gl->bind_buffer (buffer->target, 0);
@@ -292,7 +294,8 @@ glitz_buffer_map (glitz_buffer_t *buffer,
GLITZ_GL_DRAWABLE (buffer->drawable);
buffer->drawable->backend->push_current (buffer->drawable, NULL,
- GLITZ_ANY_CONTEXT_CURRENT);
+ GLITZ_ANY_CONTEXT_CURRENT,
+ NULL);
switch (access) {
case GLITZ_BUFFER_ACCESS_READ_ONLY:
@@ -328,7 +331,8 @@ glitz_buffer_unmap (glitz_buffer_t *buffer)
GLITZ_GL_DRAWABLE (buffer->drawable);
buffer->drawable->backend->push_current (buffer->drawable, NULL,
- GLITZ_ANY_CONTEXT_CURRENT);
+ GLITZ_ANY_CONTEXT_CURRENT,
+ NULL);
gl->bind_buffer (buffer->target, buffer->name);
diff --git a/src/glitz_drawable.c b/src/glitz_drawable.c
index ea7543e..a434f98 100644
--- a/src/glitz_drawable.c
+++ b/src/glitz_drawable.c
@@ -53,6 +53,8 @@ _glitz_drawable_init (glitz_drawable_t *drawable,
drawable->viewport.height = 65535;
drawable->update_all = 1;
+ drawable->flushed = 0;
+ drawable->finished = 0;
}
void
@@ -273,7 +275,7 @@ glitz_drawable_swap_buffer_region (glitz_drawable_t *drawable,
if (!surface)
{
if (drawable->backend->push_current (drawable, NULL,
- GLITZ_DRAWABLE_CURRENT))
+ GLITZ_DRAWABLE_CURRENT, NULL))
{
drawable->update_all = 1;
@@ -341,6 +343,7 @@ glitz_drawable_swap_buffer_region (glitz_drawable_t *drawable,
}
drawable->backend->gl->flush ();
+ drawable->flushed = 1;
if (surface)
glitz_surface_pop_current (surface);
@@ -365,18 +368,30 @@ slim_hidden_def(glitz_drawable_swap_buffers);
void
glitz_drawable_flush (glitz_drawable_t *drawable)
{
- drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT);
+ if (drawable->flushed)
+ return;
+
+ drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT,
+ NULL);
drawable->backend->gl->flush ();
drawable->backend->pop_current (drawable);
+
+ drawable->flushed = 1;
}
slim_hidden_def(glitz_drawable_flush);
void
glitz_drawable_finish (glitz_drawable_t *drawable)
{
- drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT);
+ if (drawable->finished)
+ return;
+
+ drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT,
+ NULL);
drawable->backend->gl->finish ();
drawable->backend->pop_current (drawable);
+
+ drawable->finished = drawable->flushed = 1;
}
slim_hidden_def(glitz_drawable_finish);
diff --git a/src/glitz_framebuffer.c b/src/glitz_framebuffer.c
index 1ccc877..ca3a2e2 100644
--- a/src/glitz_framebuffer.c
+++ b/src/glitz_framebuffer.c
@@ -201,7 +201,8 @@ _glitz_fbo_attach_notify (void *abstract_drawable,
if (!TEXTURE_ALLOCATED (texture))
{
drawable->other->backend->push_current (drawable->other, NULL,
- GLITZ_ANY_CONTEXT_CURRENT);
+ GLITZ_ANY_CONTEXT_CURRENT,
+ NULL);
glitz_texture_allocate (gl, texture);
drawable->other->backend->pop_current (drawable->other);
@@ -225,7 +226,8 @@ _glitz_fbo_detach_notify (void *abstract_drawable,
GLITZ_GL_DRAWABLE (drawable->other);
drawable->other->backend->push_current (drawable->other, NULL,
- GLITZ_ANY_CONTEXT_CURRENT);
+ GLITZ_ANY_CONTEXT_CURRENT,
+ NULL);
gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, drawable->fb);
@@ -258,13 +260,14 @@ _glitz_fbo_detach_notify (void *abstract_drawable,
static glitz_bool_t
_glitz_fbo_push_current (void *abstract_drawable,
glitz_surface_t *surface,
- glitz_constraint_t constraint)
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state)
{
glitz_fbo_drawable_t *drawable = (glitz_fbo_drawable_t *)
abstract_drawable;
drawable->other->backend->push_current (drawable->other, surface,
- constraint);
+ constraint, restore_state);
if (constraint == GLITZ_DRAWABLE_CURRENT)
{
@@ -350,7 +353,8 @@ _glitz_fbo_destroy (void *abstract_drawable)
GLITZ_GL_DRAWABLE (drawable->other);
drawable->other->backend->push_current (drawable->other, NULL,
- GLITZ_ANY_CONTEXT_CURRENT);
+ GLITZ_ANY_CONTEXT_CURRENT,
+ NULL);
gl->delete_framebuffers (1, &drawable->fb);
diff --git a/src/glitz_gl.h b/src/glitz_gl.h
index 8f04ae4..8020959 100644
--- a/src/glitz_gl.h
+++ b/src/glitz_gl.h
@@ -116,6 +116,9 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t;
#define GLITZ_GL_TEXTURE_HEIGHT 0x1001
#define GLITZ_GL_TEXTURE_BORDER_COLOR 0x1004
+#define GLITZ_GL_TEXTURE_BINDING_2D 0x8069
+#define GLITZ_GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+
#define GLITZ_GL_TEXTURE_ENV 0x2300
#define GLITZ_GL_TEXTURE_ENV_MODE 0x2200
#define GLITZ_GL_TEXTURE_2D 0x0DE1
diff --git a/src/glitz_pixel.c b/src/glitz_pixel.c
index 6c78452..d27b1d5 100644
--- a/src/glitz_pixel.c
+++ b/src/glitz_pixel.c
@@ -901,6 +901,11 @@ glitz_set_pixels (glitz_surface_t *dst,
glitz_image_t src_image, dst_image;
unsigned long color_mask;
glitz_box_t box;
+ glitz_surface_t *surface;
+ glitz_bool_t restore_state;
+ glitz_gl_int_t unpackrowlength, unpackalignment;
+ glitz_gl_int_t unpackskiprows, unpackskippixels;
+ glitz_gl_int_t t2d, tbind2d, trect, tbindrect;
GLITZ_GL_SURFACE (dst);
@@ -1041,12 +1046,49 @@ glitz_set_pixels (glitz_surface_t *dst,
feature_mask);
}
- glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT);
+ /* avoid context switch in this case */
+ if (!dst->attached &&
+ TEXTURE_ALLOCATED (&dst->texture) &&
+ !REGION_NOTEMPTY (&dst->texture_damage))
+ {
+ dst->drawable->backend->push_current (dst->drawable, dst,
+ GLITZ_ANY_CONTEXT_CURRENT,
+ &restore_state);
+ texture = &dst->texture;
+
+ /* we are using a foreign context so we must restore all state when we
+ are done */
+ if (restore_state)
+ {
+ /* get pixel store state */
+ gl->get_integer_v (GLITZ_GL_UNPACK_ROW_LENGTH, &unpackrowlength);
+ gl->get_integer_v (GLITZ_GL_UNPACK_ALIGNMENT, &unpackalignment);
+ gl->get_integer_v (GLITZ_GL_UNPACK_SKIP_ROWS, &unpackskiprows);
+ gl->get_integer_v (GLITZ_GL_UNPACK_SKIP_PIXELS, &unpackskippixels);
+
+ /* get texture bindings */
+ gl->get_integer_v (GLITZ_GL_TEXTURE_2D, &t2d);
+ gl->get_integer_v (GLITZ_GL_TEXTURE_BINDING_2D, &tbind2d);
+ gl->get_integer_v (GLITZ_GL_TEXTURE_RECTANGLE, &trect);
+ gl->get_integer_v (GLITZ_GL_TEXTURE_BINDING_RECTANGLE, &tbindrect);
+
+ /* TODO: save PBO state */
+ }
- texture = glitz_surface_get_texture (dst, 1);
- if (!texture) {
- glitz_surface_pop_current (dst);
- return;
+ surface = NULL;
+ }
+ else
+ {
+ glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT);
+
+ texture = glitz_surface_get_texture (dst, 1);
+ if (!texture) {
+ glitz_surface_pop_current (dst);
+ return;
+ }
+
+ restore_state = 0;
+ surface = dst;
}
if (height > 1) {
@@ -1247,7 +1289,39 @@ glitz_set_pixels (glitz_surface_t *dst,
BAIL:
glitz_texture_unbind (gl, texture);
- glitz_surface_pop_current (dst);
+
+ if (surface)
+ {
+ glitz_surface_pop_current (surface);
+ }
+ else
+ {
+ dst->drawable->backend->pop_current (dst->drawable);
+ }
+
+ if (restore_state)
+ {
+ /* pixel store state */
+ gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, unpackrowlength);
+ gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, unpackalignment);
+ gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, unpackskiprows);
+ gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, unpackskippixels);
+
+ /* get texture bindings */
+ if (t2d)
+ gl->enable (GLITZ_GL_TEXTURE_2D);
+ else
+ gl->disable (GLITZ_GL_TEXTURE_2D);
+
+ gl->bind_texture (GLITZ_GL_TEXTURE_2D, tbind2d);
+
+ if (trect)
+ gl->enable (GLITZ_GL_TEXTURE_RECTANGLE);
+ else
+ gl->disable (GLITZ_GL_TEXTURE_RECTANGLE);
+
+ gl->bind_texture (GLITZ_GL_TEXTURE_RECTANGLE, tbindrect);
+ }
}
void
diff --git a/src/glitz_surface.c b/src/glitz_surface.c
index b32f44e..d870fb3 100644
--- a/src/glitz_surface.c
+++ b/src/glitz_surface.c
@@ -601,7 +601,7 @@ glitz_surface_push_current (glitz_surface_t *surface,
{
drawable = surface->attached;
if (drawable->backend->push_current (drawable, surface,
- constraint))
+ constraint, NULL))
{
if (constraint == GLITZ_DRAWABLE_CURRENT)
{
@@ -641,12 +641,12 @@ glitz_surface_push_current (glitz_surface_t *surface,
if (constraint == GLITZ_DRAWABLE_CURRENT)
{
drawable->backend->push_current (drawable, surface,
- GLITZ_ANY_CONTEXT_CURRENT);
+ GLITZ_ANY_CONTEXT_CURRENT, NULL);
}
else
{
return drawable->backend->push_current (drawable, surface,
- constraint);
+ constraint, NULL);
}
}
diff --git a/src/glitzint.h b/src/glitzint.h
index 6e24d44..2f0684c 100644
--- a/src/glitzint.h
+++ b/src/glitzint.h
@@ -374,7 +374,8 @@ typedef struct glitz_backend {
glitz_bool_t
(*push_current) (void *drawable,
glitz_surface_t *surface,
- glitz_constraint_t constraint);
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state);
glitz_surface_t *
(*pop_current) (void *drawable);
@@ -450,6 +451,8 @@ struct _glitz_drawable {
int width, height;
glitz_rectangle_t viewport;
glitz_bool_t update_all;
+ glitz_bool_t flushed;
+ glitz_bool_t finished;
glitz_surface_t *front;
glitz_surface_t *back;
};
diff --git a/src/glx/glitz_glx_context.c b/src/glx/glitz_glx_context.c
index 9646e64..5fe5478 100644
--- a/src/glx/glitz_glx_context.c
+++ b/src/glx/glitz_glx_context.c
@@ -379,7 +379,10 @@ _glitz_glx_context_make_current (glitz_glx_drawable_t *drawable,
drawable->screen_info->display_info;
if (finish)
+ {
glFinish ();
+ drawable->base.finished = 1;
+ }
if (display_info->thread_info->cctx)
{
@@ -404,11 +407,23 @@ _glitz_glx_context_make_current (glitz_glx_drawable_t *drawable,
static void
_glitz_glx_context_update (glitz_glx_drawable_t *drawable,
- glitz_constraint_t constraint)
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state)
{
glitz_glx_display_info_t *dinfo = drawable->screen_info->display_info;
GLXContext context = NULL;
+ if (restore_state && constraint == GLITZ_ANY_CONTEXT_CURRENT)
+ {
+ if (dinfo->thread_info->cctx)
+ {
+ *restore_state = 1;
+ return;
+ }
+ }
+
+ drawable->base.flushed = drawable->base.finished = 0;
+
switch (constraint) {
case GLITZ_NONE:
break;
@@ -446,13 +461,17 @@ _glitz_glx_context_update (glitz_glx_drawable_t *drawable,
glitz_bool_t
glitz_glx_push_current (void *abstract_drawable,
glitz_surface_t *surface,
- glitz_constraint_t constraint)
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state)
{
glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *)
abstract_drawable;
glitz_glx_context_info_t *context_info;
int index;
+ if (restore_state)
+ *restore_state = 0;
+
index = drawable->screen_info->context_stack_size++;
context_info = &drawable->screen_info->context_stack[index];
@@ -460,7 +479,8 @@ glitz_glx_push_current (void *abstract_drawable,
context_info->surface = surface;
context_info->constraint = constraint;
- _glitz_glx_context_update (context_info->drawable, constraint);
+ _glitz_glx_context_update (context_info->drawable, constraint,
+ restore_state);
return 1;
}
@@ -480,7 +500,8 @@ glitz_glx_pop_current (void *abstract_drawable)
if (context_info->drawable)
_glitz_glx_context_update (context_info->drawable,
- context_info->constraint);
+ context_info->constraint,
+ NULL);
if (context_info->constraint == GLITZ_DRAWABLE_CURRENT)
return context_info->surface;
diff --git a/src/glx/glitz_glx_drawable.c b/src/glx/glitz_glx_drawable.c
index 9685c10..d8c95b6 100644
--- a/src/glx/glitz_glx_drawable.c
+++ b/src/glx/glitz_glx_drawable.c
@@ -57,7 +57,7 @@ _glitz_glx_create_drawable (glitz_glx_screen_info_t *screen_info,
width, height);
if (!context->initialized) {
- glitz_glx_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT);
+ glitz_glx_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT, NULL);
glitz_glx_pop_current (drawable);
}
@@ -213,7 +213,7 @@ glitz_glx_destroy (void *abstract_drawable)
* be our last chance to have a context current.
*/
glitz_glx_push_current (abstract_drawable, NULL,
- GLITZ_CONTEXT_CURRENT);
+ GLITZ_CONTEXT_CURRENT, NULL);
glitz_program_map_fini (drawable->base.backend->gl,
&drawable->screen_info->program_map);
glitz_program_map_init (&drawable->screen_info->program_map);
diff --git a/src/glx/glitz_glx_info.c b/src/glx/glitz_glx_info.c
index dbc9f2a..d7275eb 100644
--- a/src/glx/glitz_glx_info.c
+++ b/src/glx/glitz_glx_info.c
@@ -258,9 +258,9 @@ _glitz_glx_proc_address_lookup (glitz_glx_screen_info_t *screen_info)
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_COPY_SUB_BUFFER_MASK)
{
- screen_info->glx.copy_sub_buffer = (glitz_glx_copy_sub_buffer_t)
- glitz_glx_get_proc_address ("glXCopySubBufferMESA",
- (void *) screen_info);
+ screen_info->glx.copy_sub_buffer = (glitz_glx_copy_sub_buffer_t)
+ glitz_glx_get_proc_address ("glXCopySubBufferMESA",
+ (void *) screen_info);
if (!screen_info->glx.copy_sub_buffer)
screen_info->glx_feature_mask &=
diff --git a/src/glx/glitz_glxint.h b/src/glx/glitz_glxint.h
index ac58212..38ef6fd 100644
--- a/src/glx/glitz_glxint.h
+++ b/src/glx/glitz_glxint.h
@@ -167,7 +167,8 @@ glitz_glx_create_pbuffer (void *abstract_templ,
extern glitz_bool_t __internal_linkage
glitz_glx_push_current (void *abstract_drawable,
glitz_surface_t *surface,
- glitz_constraint_t constraint);
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state);
extern glitz_surface_t __internal_linkage *
glitz_glx_pop_current (void *abstract_drawable);
diff --git a/src/wgl/glitz_wgl_context.c b/src/wgl/glitz_wgl_context.c
index c112885..da0b44f 100644
--- a/src/wgl/glitz_wgl_context.c
+++ b/src/wgl/glitz_wgl_context.c
@@ -266,6 +266,8 @@ _glitz_wgl_context_update (glitz_wgl_drawable_t *drawable,
{
HGLRC context;
+ drawable->base.flushed = drawable->base.finished = 0;
+
switch (constraint) {
case GLITZ_NONE:
break;
@@ -291,12 +293,16 @@ _glitz_wgl_context_update (glitz_wgl_drawable_t *drawable,
glitz_bool_t
glitz_wgl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
- glitz_constraint_t constraint)
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state)
{
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
glitz_wgl_context_info_t *context_info;
int index;
+ if (restore_state)
+ *restore_state = 0;
+
index = drawable->screen_info->context_stack_size++;
context_info = &drawable->screen_info->context_stack[index];
diff --git a/src/wgl/glitz_wgl_drawable.c b/src/wgl/glitz_wgl_drawable.c
index 7bffd6d..7a5e18d 100644
--- a/src/wgl/glitz_wgl_drawable.c
+++ b/src/wgl/glitz_wgl_drawable.c
@@ -75,7 +75,7 @@ _glitz_wgl_create_drawable (glitz_wgl_screen_info_t *screen_info,
height);
if (!context->initialized) {
- glitz_wgl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT);
+ glitz_wgl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT, NULL);
glitz_wgl_pop_current (drawable);
}
@@ -199,7 +199,8 @@ glitz_wgl_destroy (void *abstract_drawable)
* Last drawable? We have to destroy all fragment programs as this may
* be our last chance to have a context current.
*/
- glitz_wgl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT);
+ glitz_wgl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT,
+ NULL);
glitz_program_map_fini (drawable->base.backend->gl,
&drawable->screen_info->program_map);
glitz_program_map_init (&drawable->screen_info->program_map);
diff --git a/src/wgl/glitz_wglint.h b/src/wgl/glitz_wglint.h
index 2e7519e..fd639c0 100644
--- a/src/wgl/glitz_wglint.h
+++ b/src/wgl/glitz_wglint.h
@@ -173,7 +173,8 @@ glitz_wgl_create_pbuffer (void *abstract_templ,
extern glitz_bool_t __internal_linkage
glitz_wgl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
- glitz_constraint_t constraint);
+ glitz_constraint_t constraint,
+ glitz_bool_t *restore_state);
extern glitz_surface_t *__internal_linkage
glitz_wgl_pop_current (void *abstract_drawable);