diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index 8ed47c25825..0a84e0f2c9c 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -672,7 +672,7 @@ dri2_allocate_textures(struct dri_context *ctx, } } -static void +static bool dri2_flush_frontbuffer(struct dri_context *ctx, struct dri_drawable *drawable, enum st_attachment_type statt) @@ -683,7 +683,7 @@ dri2_flush_frontbuffer(struct dri_context *ctx, struct pipe_context *pipe = ctx->st->pipe; if (statt != ST_ATTACHMENT_FRONT_LEFT) - return; + return false; if (drawable->stvis.samples > 1) { /* Resolve the front buffer. */ @@ -704,6 +704,8 @@ dri2_flush_frontbuffer(struct dri_context *ctx, else if (loader->flushFrontBuffer) { loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate); } + + return true; } /** diff --git a/src/gallium/frontends/dri/dri_drawable.c b/src/gallium/frontends/dri/dri_drawable.c index 8a031cc3b48..2c4ba4d2009 100644 --- a/src/gallium/frontends/dri/dri_drawable.c +++ b/src/gallium/frontends/dri/dri_drawable.c @@ -124,9 +124,7 @@ dri_st_framebuffer_flush_front(struct st_context_iface *stctx, (struct dri_drawable *) stfbi->st_manager_private; /* XXX remove this and just set the correct one on the framebuffer */ - drawable->flush_frontbuffer(ctx, drawable, statt); - - return true; + return drawable->flush_frontbuffer(ctx, drawable, statt); } /** diff --git a/src/gallium/frontends/dri/dri_drawable.h b/src/gallium/frontends/dri/dri_drawable.h index 6ba4c64fffc..4626bad0c00 100644 --- a/src/gallium/frontends/dri/dri_drawable.h +++ b/src/gallium/frontends/dri/dri_drawable.h @@ -70,7 +70,7 @@ struct dri_drawable void (*update_drawable_info)(struct dri_drawable *drawable); - void (*flush_frontbuffer)(struct dri_context *ctx, + bool (*flush_frontbuffer)(struct dri_context *ctx, struct dri_drawable *drawable, enum st_attachment_type statt); diff --git a/src/gallium/frontends/dri/drisw.c b/src/gallium/frontends/dri/drisw.c index 498522564c6..bf80d9fc268 100644 --- a/src/gallium/frontends/dri/drisw.c +++ b/src/gallium/frontends/dri/drisw.c @@ -290,15 +290,15 @@ drisw_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y, } } -static void +static bool drisw_flush_frontbuffer(struct dri_context *ctx, struct dri_drawable *drawable, enum st_attachment_type statt) { struct pipe_resource *ptex; - if (!ctx) - return; + if (!ctx || statt != ST_ATTACHMENT_FRONT_LEFT) + return false; if (drawable->stvis.samples > 1) { /* Resolve the front buffer. */ @@ -311,6 +311,8 @@ drisw_flush_frontbuffer(struct dri_context *ctx, if (ptex) { drisw_copy_to_front(ctx->st->pipe, ctx->dPriv, ptex); } + + return true; } /** diff --git a/src/gallium/frontends/glx/xlib/xm_st.c b/src/gallium/frontends/glx/xlib/xm_st.c index b14f9acc90e..ca33df91f92 100644 --- a/src/gallium/frontends/glx/xlib/xm_st.c +++ b/src/gallium/frontends/glx/xlib/xm_st.c @@ -268,6 +268,9 @@ xmesa_st_framebuffer_flush_front(struct st_context_iface *stctx, struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); bool ret; + if (statt != ST_ATTACHMENT_FRONT_LEFT) + return false; + ret = xmesa_st_framebuffer_display(stfbi, stctx, statt, NULL); if (ret && xmesa_strict_invalidate) diff --git a/src/gallium/frontends/hgl/hgl.c b/src/gallium/frontends/hgl/hgl.c index 2773d4955ff..0e100e2fef9 100644 --- a/src/gallium/frontends/hgl/hgl.c +++ b/src/gallium/frontends/hgl/hgl.c @@ -65,6 +65,9 @@ hgl_st_framebuffer_flush_front(struct st_context_iface* stctxi, struct hgl_buffer* buffer = hgl_st_framebuffer(stfbi); struct pipe_resource* ptex = buffer->textures[statt]; + if (statt != ST_ATTACHMENT_FRONT_LEFT) + return false; + if (!ptex) return true; diff --git a/src/gallium/frontends/osmesa/osmesa.c b/src/gallium/frontends/osmesa/osmesa.c index 49764d9b0b2..963888971af 100644 --- a/src/gallium/frontends/osmesa/osmesa.c +++ b/src/gallium/frontends/osmesa/osmesa.c @@ -366,6 +366,9 @@ osmesa_st_framebuffer_flush_front(struct st_context_iface *stctx, unsigned bpp; int dst_stride; + if (statt != ST_ATTACHMENT_FRONT_LEFT) + return false; + if (osmesa->pp) { struct pipe_resource *zsbuf = NULL; unsigned i; diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index 4a0da6ff99c..d0184fa0be6 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -1167,15 +1167,22 @@ st_manager_flush_frontbuffer(struct st_context *st) !stfb->Base.Visual.doubleBufferMode) return; + /* Check front buffer used at the GL API level. */ + enum st_attachment_type statt = ST_ATTACHMENT_FRONT_LEFT; strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_FRONT_LEFT]. Renderbuffer); + if (!strb) { + /* Check back buffer redirected by EGL_KHR_mutable_render_buffer. */ + statt = ST_ATTACHMENT_BACK_LEFT; + strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_BACK_LEFT]. + Renderbuffer); + } /* Do we have a front color buffer and has it been drawn to since last * frontbuffer flush? */ - if (strb && strb->defined) { - stfb->iface->flush_front(&st->iface, stfb->iface, - ST_ATTACHMENT_FRONT_LEFT); + if (strb && strb->defined && + stfb->iface->flush_front(&st->iface, stfb->iface, statt)) { strb->defined = GL_FALSE; /* Trigger an update of strb->defined on next draw */