summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/osmesa/osmesa.c61
1 files changed, 54 insertions, 7 deletions
diff --git a/src/gallium/state_trackers/osmesa/osmesa.c b/src/gallium/state_trackers/osmesa/osmesa.c
index fdd0eda1996..533fb53e4c7 100644
--- a/src/gallium/state_trackers/osmesa/osmesa.c
+++ b/src/gallium/state_trackers/osmesa/osmesa.c
@@ -80,6 +80,8 @@ struct osmesa_buffer
struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
void *map;
+
+ struct osmesa_buffer *next; /**< next in linked list */
};
@@ -99,6 +101,16 @@ struct osmesa_context
};
+/**
+ * Linked list of all osmesa_buffers.
+ * We can re-use an osmesa_buffer from one OSMesaMakeCurrent() call to
+ * the next unless the color/depth/stencil/accum formats change.
+ * We have to do this to be compatible with the original OSMesa implementation
+ * because some apps call OSMesaMakeCurrent() several times during rendering
+ * a frame.
+ */
+static struct osmesa_buffer *BufferList = NULL;
+
/**
* Called from the ST manager.
@@ -400,6 +412,9 @@ osmesa_create_st_framebuffer(void)
}
+/**
+ * Create new buffer and add to linked list.
+ */
static struct osmesa_buffer *
osmesa_create_buffer(enum pipe_format color_format,
enum pipe_format ds_format,
@@ -414,11 +429,38 @@ osmesa_create_buffer(enum pipe_format color_format,
osmesa_init_st_visual(&osbuffer->visual, color_format,
ds_format, accum_format);
+
+ /* insert into linked list */
+ osbuffer->next = BufferList;
+ BufferList = osbuffer;
}
+
return osbuffer;
}
+/**
+ * Search linked list for a buffer with matching pixel formats.
+ */
+static struct osmesa_buffer *
+osmesa_find_buffer(enum pipe_format color_format,
+ enum pipe_format ds_format,
+ enum pipe_format accum_format)
+{
+ struct osmesa_buffer *b;
+
+ /* Check if we already have a suitable buffer for the given formats */
+ for (b = BufferList; b; b = b->next) {
+ if (b->visual.color_format == color_format &&
+ b->visual.depth_stencil_format == ds_format &&
+ b->visual.accum_format == accum_format) {
+ return b;
+ }
+ }
+ return NULL;
+}
+
+
static void
osmesa_destroy_buffer(struct osmesa_buffer *osbuffer)
{
@@ -581,18 +623,23 @@ OSMesaMakeCurrent(OSMesaContext osmesa, void *buffer, GLenum type,
return GL_FALSE;
}
- osbuffer = osmesa_create_buffer(color_format,
- osmesa->depth_stencil_format,
- osmesa->accum_format);
+ /* See if we already have a buffer that uses these pixel formats */
+ osbuffer = osmesa_find_buffer(color_format,
+ osmesa->depth_stencil_format,
+ osmesa->accum_format);
+ if (!osbuffer) {
+ /* Existing buffer found, create new buffer */
+ osbuffer = osmesa_create_buffer(color_format,
+ osmesa->depth_stencil_format,
+ osmesa->accum_format);
+ }
osbuffer->width = width;
osbuffer->height = height;
osbuffer->map = buffer;
- if (osmesa->current_buffer) {
- /* free old buffer */
- osmesa_destroy_buffer(osmesa->current_buffer);
- }
+ /* XXX unused for now */
+ (void) osmesa_destroy_buffer;
osmesa->current_buffer = osbuffer;
osmesa->type = type;