summaryrefslogtreecommitdiff
path: root/src/mesa/state_tracker/st_cb_flush.c
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2008-01-21 20:22:49 +0000
committerJosé Fonseca <jrfonseca@tungstengraphics.com>2008-01-26 10:30:31 +0900
commit596a92ee7590cd3819aad0139cf779d28e57874d (patch)
tree948e66f40ea7c11e8b6cd763907e677cd7904e2d /src/mesa/state_tracker/st_cb_flush.c
parenta97b3f64b36aa8d5905a7ed8b7c9f00324661060 (diff)
gallium: specialize glFlush vs other flush semantics
Diffstat (limited to 'src/mesa/state_tracker/st_cb_flush.c')
-rw-r--r--src/mesa/state_tracker/st_cb_flush.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c
index 9808b1f8f6..dbec993f1b 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -45,21 +45,32 @@
void st_flush( struct st_context *st, uint pipeFlushFlags )
{
- GLframebuffer *fb = st->ctx->DrawBuffer;
-
FLUSH_VERTICES(st->ctx, 0);
- /* If there has been no rendering to the frontbuffer, consider
- * short-circuiting this, or perhaps pass an "optional" flag down
- * to the driver so that it can make the decision.
- */
st->pipe->flush( st->pipe, pipeFlushFlags );
+}
+
+
+static void st_gl_flush( struct st_context *st, uint pipeFlushFlags )
+{
+ GLframebuffer *fb = st->ctx->DrawBuffer;
+
+ FLUSH_VERTICES(st->ctx, 0);
if (!fb)
return;
/* XXX: temporary hack. This flag should only be set if we do any
* rendering to the front buffer.
+ *
+ * Further more, the scissor rectangle could be tracked to
+ * construct a dirty region of the front buffer, to avoid
+ * situations where it must be copied repeatedly.
+ *
+ * In the extreme case, some kind of timer could be set up to allow
+ * coalescing of multiple flushes to the frontbuffer, which can be
+ * quite a performance drain if there are a sufficient number of
+ * them.
*/
st->flags.frontbuffer_dirty
= (fb->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT);
@@ -69,6 +80,15 @@ void st_flush( struct st_context *st, uint pipeFlushFlags )
= st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
struct pipe_surface *front_surf = strb->surface;
+ /* If we aren't rendering to the frontbuffer, this is a noop.
+ * This should be uncontroversial for glFlush, though people may
+ * feel more strongly about glFinish.
+ *
+ * Additionally, need to make sure that the frontbuffer_dirty
+ * flag really gets set on frontbuffer rendering.
+ */
+ st->pipe->flush( st->pipe, pipeFlushFlags );
+
/* Hook for copying "fake" frontbuffer if necessary:
*/
st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf,
@@ -81,23 +101,23 @@ void st_flush( struct st_context *st, uint pipeFlushFlags )
/**
* Called via ctx->Driver.Flush()
*/
-static void st_Flush(GLcontext *ctx)
+static void st_glFlush(GLcontext *ctx)
{
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE);
+ st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE);
}
/**
* Called via ctx->Driver.Finish()
*/
-static void st_Finish(GLcontext *ctx)
+static void st_glFinish(GLcontext *ctx)
{
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT);
+ st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT);
}
void st_init_flush_functions(struct dd_function_table *functions)
{
- functions->Flush = st_Flush;
- functions->Finish = st_Finish;
+ functions->Flush = st_glFlush;
+ functions->Finish = st_glFinish;
}