summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c8
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c2
-rw-r--r--src/mesa/state_tracker/st_cb_flush.c27
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c33
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.h3
-rw-r--r--src/mesa/state_tracker/st_context.h9
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c1
7 files changed, 54 insertions, 29 deletions
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index 02573af8f0..8a95096ec9 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -81,6 +81,14 @@ update_framebuffer_state( struct st_context *st )
}
cso_set_framebuffer(st->cso_context, framebuffer);
+
+ if (fb->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT) {
+ if (st->frontbuffer_status == FRONT_STATUS_COPY_OF_BACK) {
+ /* XXX copy back buf to front? */
+ }
+ /* we're assuming we'll really draw to the front buffer */
+ st->frontbuffer_status = FRONT_STATUS_DIRTY;
+ }
}
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index b1affc4a91..5f8c90cbba 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -961,7 +961,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
}
if (type == GL_COLOR) {
- rbRead = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
+ rbRead = st_get_color_read_renderbuffer(ctx);
color = NULL;
stfp = combined_drawpix_fragment_program(ctx);
stvp = st_make_passthrough_vertex_shader(ctx->st, GL_FALSE);
diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c
index 1bcd1b4cd9..1b3402cee2 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -44,30 +44,10 @@
#include "pipe/p_winsys.h"
-static GLboolean
+static INLINE GLboolean
is_front_buffer_dirty(struct st_context *st)
{
- GLframebuffer *fb = st->ctx->DrawBuffer;
-
- if (!fb)
- return GL_FALSE;
-
- /* 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);
-
- return st->flags.frontbuffer_dirty;
+ return st->frontbuffer_status == FRONT_STATUS_DIRTY;
}
@@ -86,7 +66,8 @@ display_front_buffer(struct st_context *st)
*/
st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf,
st->pipe->priv );
- st->flags.frontbuffer_dirty = 0;
+
+ st->frontbuffer_status = FRONT_STATUS_UNDEFINED;
}
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 2bcc8c99fb..29a06ffaa9 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -129,6 +129,34 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
/**
+ * Return renderbuffer to use for reading color pixels for glRead/CopyPixel
+ * commands.
+ * Special care is needed for the front buffer.
+ */
+struct st_renderbuffer *
+st_get_color_read_renderbuffer(GLcontext *ctx)
+{
+ struct gl_framebuffer *fb = ctx->ReadBuffer;
+ struct st_renderbuffer *strb =
+ st_renderbuffer(fb->_ColorReadBuffer);
+ struct st_renderbuffer *front =
+ st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+
+ if (strb == front
+ && ctx->st->frontbuffer_status == FRONT_STATUS_COPY_OF_BACK) {
+ /* reading from front color buffer, which is a logical copy of the
+ * back color buffer.
+ */
+ struct st_renderbuffer *back =
+ st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+ strb = back;
+ }
+
+ return strb;
+}
+
+
+/**
* Do glReadPixels by getting rows from the framebuffer surface with
* get_tile(). Convert to requested format/type with Mesa image routines.
* Image transfer ops are done in software too.
@@ -173,12 +201,13 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
strb = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
}
else {
- strb = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
+ /* Read color buffer */
+ strb = st_get_color_read_renderbuffer(ctx);
}
+
if (!strb)
return;
-
if (format == GL_RGBA && type == GL_FLOAT) {
/* write tile(row) directly into user's buffer */
df = (GLfloat *) _mesa_image_address2d(&clippedPacking, dest, width,
diff --git a/src/mesa/state_tracker/st_cb_readpixels.h b/src/mesa/state_tracker/st_cb_readpixels.h
index 79acdad88e..9e151be51f 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.h
+++ b/src/mesa/state_tracker/st_cb_readpixels.h
@@ -29,6 +29,9 @@
#ifndef ST_CB_READPIXELS_H
#define ST_CB_READPIXELS_H
+extern struct st_renderbuffer *
+st_get_color_read_renderbuffer(GLcontext *ctx);
+
extern void
st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height, GLenum type,
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 212687cf4a..d89e54c43c 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -45,6 +45,11 @@ struct blit_state;
struct bitmap_cache;
+#define FRONT_STATUS_UNDEFINED 0
+#define FRONT_STATUS_DIRTY 1
+#define FRONT_STATUS_COPY_OF_BACK 2
+
+
#define ST_NEW_MESA 0x1 /* Mesa state has changed */
#define ST_NEW_FRAGMENT_PROGRAM 0x2
#define ST_NEW_VERTEX_PROGRAM 0x4
@@ -104,9 +109,7 @@ struct st_context
struct gl_fragment_program *fragment_program;
} cb;
- struct {
- GLuint frontbuffer_dirty:1;
- } flags;
+ GLuint frontbuffer_status; /**< one of FRONT_STATUS_ */
char vendor[100];
char renderer[100];
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index ea09d9234c..47466c97d8 100644
--- a/src/mesa/state_tracker/st_framebuffer.c
+++ b/src/mesa/state_tracker/st_framebuffer.c
@@ -188,6 +188,7 @@ st_notify_swapbuffers(struct st_framebuffer *stfb)
st_flush( ctx->st,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS,
NULL );
+ ctx->st->frontbuffer_status = FRONT_STATUS_COPY_OF_BACK;
}
}