[Mesa-dev] [PATCH 1/2] st-api: Rework how drawables are invalidated

Thomas Hellstrom thellstrom at vmware.com
Tue Jun 28 22:13:47 PDT 2011


On 06/29/2011 01:26 AM, Chia-I Wu wrote:
> On Tue, Jun 28, 2011 at 9:19 PM, Thomas Hellstrom<thellstrom at vmware.com>  wrote:
>    
>> The api and the state tracker manager code as well as the state tracker code
>> assumed that only a single context could be bound to a drawable. That is not
>> a valid assumption, since multiple contexts can bind to the same drawable.
>>
>> Fix this by making it the state tracker's responsibility to update all
>> contexts binding to a drawable.
>>      
> This looks great.
>
> Just one question.  Would it make things easier for mesa and vega if
> we have st_framebuffer_iface::stamp instead of
> st_framebuffer_iface::invalid?
>    

Yes. Jakob also pointed that out to me yesterday, so  I'll fix the patch 
to take that into account.

In fact there may in general be multiple state tracker framebuffers 
created from the same st_framebuffer_iface, so 
st_framebuffer_iface::stamp is actually needed.


Thanks,
Thomas


>    
>> Signed-off-by: Thomas Hellstrom<thellstrom at vmware.com>
>> ---
>>   src/gallium/include/state_tracker/st_api.h         |   26 ++-----
>>   .../state_trackers/dri/common/dri_drawable.c       |    3 +
>>   src/gallium/state_trackers/dri/drm/dri2.c          |    4 +-
>>   src/gallium/state_trackers/dri/sw/drisw.c          |    4 +-
>>   src/gallium/state_trackers/egl/common/egl_g3d.c    |   12 +--
>>   .../state_trackers/egl/common/egl_g3d_api.c        |    7 --
>>   src/gallium/state_trackers/egl/common/egl_g3d_st.c |    8 ++
>>   src/gallium/state_trackers/vega/vg_context.h       |    4 +-
>>   src/gallium/state_trackers/vega/vg_manager.c       |   40 ++++------
>>   src/gallium/state_trackers/wgl/stw_context.c       |    6 +-
>>   src/gallium/state_trackers/wgl/stw_st.c            |    3 +
>>   src/mesa/state_tracker/st_cb_viewport.c            |   15 +++-
>>   src/mesa/state_tracker/st_context.h                |    5 +-
>>   src/mesa/state_tracker/st_manager.c                |   85 +++++++++++---------
>>   14 files changed, 109 insertions(+), 113 deletions(-)
>>
>> diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
>> index 04fc7c6..b08972f 100644
>> --- a/src/gallium/include/state_tracker/st_api.h
>> +++ b/src/gallium/include/state_tracker/st_api.h
>> @@ -253,6 +253,13 @@ struct st_context_attribs
>>   struct st_framebuffer_iface
>>   {
>>     /**
>> +    * Atomic flag to indicate invalid status, which can only be resolved
>> +    * by a call to validate.
>> +    */
>> +
>> +   int32_t invalid;
>> +
>> +   /**
>>      * Available for the state tracker manager to use.
>>      */
>>     void *st_manager_private;
>> @@ -315,25 +322,6 @@ struct st_context_iface
>>     void (*destroy)(struct st_context_iface *stctxi);
>>
>>     /**
>> -    * Invalidate the current textures that was taken from a framebuffer.
>> -    *
>> -    * The state tracker manager calls this function to let the rendering
>> -    * context know that it should update the textures it got from
>> -    * st_framebuffer_iface::validate.  It should do so at the latest time possible.
>> -    * Possible right before sending triangles to the pipe context.
>> -    *
>> -    * For certain platforms this function might be called from a thread other
>> -    * than the thread that the context is currently bound in, and must
>> -    * therefore be thread safe. But it is the state tracker manager's
>> -    * responsibility to make sure that the framebuffer is bound to the context
>> -    * and the API context is current for the duration of this call.
>> -    *
>> -    * Thus reducing the sync primitive needed to a single atomic flag.
>> -    */
>> -   void (*notify_invalid_framebuffer)(struct st_context_iface *stctxi,
>> -                                      struct st_framebuffer_iface *stfbi);
>> -
>> -   /**
>>      * Flush all drawing from context to the pipe also flushes the pipe.
>>      */
>>     void (*flush)(struct st_context_iface *stctxi, unsigned flags,
>> diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
>> index 28a33ac..09d25bc 100644
>> --- a/src/gallium/state_trackers/dri/common/dri_drawable.c
>> +++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
>> @@ -82,6 +82,8 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
>>        drawable->texture_mask = statt_mask;
>>     }
>>
>> +   p_atomic_set(&drawable->base.invalid, FALSE);
>> +
>>     if (!out)
>>        return TRUE;
>>
>> @@ -136,6 +138,7 @@ dri_create_buffer(__DRIscreen * sPriv,
>>     drawable->sPriv = sPriv;
>>     drawable->dPriv = dPriv;
>>     dPriv->driverPrivate = (void *)drawable;
>> +   p_atomic_set(&drawable->base.invalid, TRUE);
>>
>>     return GL_TRUE;
>>   fail:
>> diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
>> index e471e8e..9e61d7e 100644
>> --- a/src/gallium/state_trackers/dri/drm/dri2.c
>> +++ b/src/gallium/state_trackers/dri/drm/dri2.c
>> @@ -52,13 +52,11 @@ static void
>>   dri2_invalidate_drawable(__DRIdrawable *dPriv)
>>   {
>>     struct dri_drawable *drawable = dri_drawable(dPriv);
>> -   struct dri_context *ctx = drawable->context;
>>
>>     dri2InvalidateDrawable(dPriv);
>>     drawable->dPriv->lastStamp = *drawable->dPriv->pStamp;
>>
>> -   if (ctx)
>> -      ctx->st->notify_invalid_framebuffer(ctx->st,&drawable->base);
>> +   p_atomic_set(&drawable->base.invalid, TRUE);
>>   }
>>
>>   static const __DRI2flushExtension dri2FlushExtension = {
>> diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
>> index ac11f7c..f9ba971 100644
>> --- a/src/gallium/state_trackers/dri/sw/drisw.c
>> +++ b/src/gallium/state_trackers/dri/sw/drisw.c
>> @@ -108,9 +108,7 @@ drisw_invalidate_drawable(__DRIdrawable *dPriv)
>>
>>     drawable->texture_stamp = dPriv->lastStamp - 1;
>>
>> -   /* check if swapping currently bound buffer */
>> -   if (ctx&&  ctx->dPriv == dPriv)
>> -      ctx->st->notify_invalid_framebuffer(ctx->st,&drawable->base);
>> +   p_atomic_set(&drawable->base.invalid, TRUE);
>>   }
>>
>>   static INLINE void
>> diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
>> index 29dbbef..45db90a 100644
>> --- a/src/gallium/state_trackers/egl/common/egl_g3d.c
>> +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
>> @@ -45,15 +45,9 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
>>   {
>>     /* XXX not thread safe? */
>>     struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
>> -   struct egl_g3d_context *gctx;
>> -
>> -   /*
>> -    * Some functions such as egl_g3d_copy_buffers create a temporary native
>> -    * surface.  There is no gsurf associated with it.
>> -    */
>> -   gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
>> -   if (gctx)
>> -      gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
>> +
>> +   if (gsurf&&  gsurf->stfbi)
>> +      p_atomic_set(&gsurf->stfbi->invalid, TRUE);
>>   }
>>
>>   static struct pipe_screen *
>> diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
>> index 8b1821e..f0d6d71 100644
>> --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
>> +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
>> @@ -536,19 +536,12 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
>>              (gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
>>        if (ok) {
>>           if (gdraw) {
>> -            gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
>> -                  gdraw->stfbi);
>> -
>>              if (gdraw->base.Type == EGL_WINDOW_BIT) {
>>                 gctx->base.WindowRenderBuffer =
>>                    (gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
>>                    EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
>>              }
>>           }
>> -         if (gread&&  gread != gdraw) {
>> -            gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
>> -                  gread->stfbi);
>> -         }
>>        }
>>     }
>>     else if (old_gctx) {
>> diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
>> index 2b944b5..cb9c237 100644
>> --- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
>> +++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
>> @@ -182,6 +182,9 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
>>        pipe_resource_reference(&out[i], gsurf->render_texture);
>>     }
>>
>> +   if (gsurf->stfbi)
>> +      p_atomic_set(&gsurf->stfbi->invalid, FALSE);
>> +
>>     return TRUE;
>>   }
>>
>> @@ -278,6 +281,9 @@ egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
>>        }
>>     }
>>
>> +   if (gsurf->stfbi)
>> +      p_atomic_set(&gsurf->stfbi->invalid, FALSE);
>> +
>>     return TRUE;
>>   }
>>
>> @@ -292,6 +298,8 @@ egl_g3d_create_st_framebuffer(_EGLSurface *surf)
>>        return NULL;
>>
>>     stfbi->visual =&gsurf->stvis;
>> +   p_atomic_set(&stfbi->invalid, TRUE);
>> +
>>     if (gsurf->base.Type != EGL_PBUFFER_BIT) {
>>        stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
>>        stfbi->validate = egl_g3d_st_framebuffer_validate;
>> diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
>> index 71491a5..0d91007 100644
>> --- a/src/gallium/state_trackers/vega/vg_context.h
>> +++ b/src/gallium/state_trackers/vega/vg_context.h
>> @@ -65,6 +65,7 @@ struct st_framebuffer {
>>     enum st_attachment_type strb_att;
>>
>>     void *privateData;
>> +   int32_t stamp;
>>   };
>>
>>   enum vg_object_type {
>> @@ -105,7 +106,6 @@ struct vg_context
>>     VGErrorCode _error;
>>
>>     struct st_framebuffer *draw_buffer;
>> -   int32_t draw_buffer_invalid;
>>
>>     struct cso_hash *owned_objects[VG_OBJECT_LAST];
>>
>> @@ -129,6 +129,8 @@ struct vg_context
>>     struct vg_paint *default_paint;
>>
>>     struct blit_state *blit;
>> +
>> +   int32_t draw_stamp;
>>   };
>>
>>
>> diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
>> index eeea686..c9149f8 100644
>> --- a/src/gallium/state_trackers/vega/vg_manager.c
>> +++ b/src/gallium/state_trackers/vega/vg_manager.c
>> @@ -111,30 +111,25 @@ vg_manager_validate_framebuffer(struct vg_context *ctx)
>>     if (!stfb)
>>        return;
>>
>> -   if (!p_atomic_read(&ctx->draw_buffer_invalid))
>> -      return;
>> -
>> -   /* validate the fb */
>> -   if (!stfb->iface->validate(stfb->iface,&stfb->strb_att, 1,&pt) || !pt)
>> -      return;
>> +   if (p_atomic_read(&stfb->iface->invalid)) {
>>
>> -   p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
>> +      /* validate the fb */
>> +      if (!stfb->iface->validate(stfb->iface,&stfb->strb_att, 1,&pt) || !pt)
>> +         return;
>>
>> -   if (vg_context_update_color_rb(ctx, pt) ||
>> -       stfb->width != pt->width0 ||
>> -       stfb->height != pt->height0)
>> -      ctx->state.dirty |= FRAMEBUFFER_DIRTY;
>> +      if (vg_context_update_color_rb(ctx, pt) ||
>> +          stfb->width != pt->width0 ||
>> +          stfb->height != pt->height0)
>> +         ++stfb->stamp;
>>
>> -   stfb->width = pt->width0;
>> -   stfb->height = pt->height0;
>> -}
>> +      stfb->width = pt->width0;
>> +      stfb->height = pt->height0;
>> +   }
>>
>> -static void
>> -vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
>> -                                      struct st_framebuffer_iface *stfbi)
>> -{
>> -   struct vg_context *ctx = (struct vg_context *) stctxi;
>> -   p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
>> +   if (ctx->draw_stamp != stfb->stamp) {
>> +      ctx->state.dirty |= FRAMEBUFFER_DIRTY;
>> +      ctx->draw_stamp = stfb->stamp;
>> +   }
>>   }
>>
>>   static void
>> @@ -187,8 +182,6 @@ vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
>>
>>     ctx->iface.destroy = vg_context_destroy;
>>
>> -   ctx->iface.notify_invalid_framebuffer =
>> -      vg_context_notify_invalid_framebuffer;
>>     ctx->iface.flush = vg_context_flush;
>>
>>     ctx->iface.teximage = NULL;
>> @@ -266,8 +259,6 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi,
>>     if (stdrawi != streadi)
>>        return FALSE;
>>
>> -   p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
>> -
>>     strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID;
>>
>>     if (ctx->draw_buffer) {
>> @@ -318,6 +309,7 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi,
>>     }
>>
>>     ctx->draw_buffer->iface = stdrawi;
>> +   ctx->draw_stamp = ctx->draw_buffer->stamp - 1;
>>
>>     return TRUE;
>>   }
>> diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
>> index 5608d4f..7e29960 100644
>> --- a/src/gallium/state_trackers/wgl/stw_context.c
>> +++ b/src/gallium/state_trackers/wgl/stw_context.c
>> @@ -31,6 +31,7 @@
>>   #include "pipe/p_context.h"
>>   #include "pipe/p_state.h"
>>   #include "util/u_memory.h"
>> +#include "util/u_atomic.h"
>>   #include "state_tracker/st_api.h"
>>
>>   #include "stw_icd.h"
>> @@ -361,10 +362,7 @@ stw_flush_current_locked( struct stw_framebuffer *fb )
>>   void
>>   stw_notify_current_locked( struct stw_framebuffer *fb )
>>   {
>> -   struct stw_context *ctx = stw_current_context();
>> -
>> -   if (ctx&&  ctx->current_framebuffer == fb)
>> -      ctx->st->notify_invalid_framebuffer(ctx->st, fb->stfb);
>> +   p_atomic_set(&fb->stfb->invalid, TRUE);
>>   }
>>
>>   /**
>> diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c
>> index 9174533..7299441 100644
>> --- a/src/gallium/state_trackers/wgl/stw_st.c
>> +++ b/src/gallium/state_trackers/wgl/stw_st.c
>> @@ -27,6 +27,7 @@
>>
>>   #include "util/u_memory.h"
>>   #include "util/u_inlines.h"
>> +#include "util/u_atomic.h"
>>   #include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
>>
>>   #include "stw_st.h"
>> @@ -117,6 +118,7 @@ stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
>>     stwfb->texture_width = width;
>>     stwfb->texture_height = height;
>>     stwfb->texture_mask = mask;
>> +   p_atomic_set(&stfb->invalid, FALSE);
>>   }
>>
>>   static boolean
>> @@ -196,6 +198,7 @@ stw_st_create_framebuffer(struct stw_framebuffer *fb)
>>     stwfb->stvis = fb->pfi->stvis;
>>
>>     stwfb->base.visual =&stwfb->stvis;
>> +   p_atomic_set(&stwfb->base.invalid, TRUE);
>>     stwfb->base.flush_front = stw_st_framebuffer_flush_front;
>>     stwfb->base.validate = stw_st_framebuffer_validate;
>>
>> diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c
>> index 049755e..c74d013 100644
>> --- a/src/mesa/state_tracker/st_cb_viewport.c
>> +++ b/src/mesa/state_tracker/st_cb_viewport.c
>> @@ -56,13 +56,20 @@ static void st_viewport(struct gl_context * ctx, GLint x, GLint y,
>>     if (!st->invalidate_on_gl_viewport)
>>        return;
>>
>> +   /*
>> +    * Normally we'd want the state tracker manager to mark the drawables
>> +    * invalid only when needed. This will force the state tracker manager
>> +    * to revalidate the drawable, rather than just update the context with
>> +    * the latest cached drawable info.
>> +    */
>> +
>>     stdraw = st_ws_framebuffer(st->ctx->DrawBuffer);
>>     stread = st_ws_framebuffer(st->ctx->ReadBuffer);
>>
>> -   if (stdraw)
>> -      p_atomic_set(&stdraw->revalidate, TRUE);
>> -   if (stread&&  stread != stdraw)
>> -      p_atomic_set(&stread->revalidate, TRUE);
>> +   if (stdraw&&  stdraw->iface)
>> +       p_atomic_set(&stdraw->iface->invalid, TRUE);
>> +   if (stread&&  stread != stdraw&&  stread->iface)
>> +       p_atomic_set(&stread->iface->invalid, TRUE);
>>   }
>>
>>   void st_init_viewport_functions(struct dd_function_table *functions)
>> diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
>> index ff20703..f76fae3 100644
>> --- a/src/mesa/state_tracker/st_context.h
>> +++ b/src/mesa/state_tracker/st_context.h
>> @@ -204,6 +204,9 @@ struct st_context
>>     /* Active render condition. */
>>     struct pipe_query *render_condition;
>>     unsigned condition_mode;
>> +
>> +   int32_t draw_stamp;
>> +   int32_t read_stamp;
>>   };
>>
>>
>> @@ -227,7 +230,7 @@ struct st_framebuffer
>>     struct st_framebuffer_iface *iface;
>>     enum st_attachment_type statts[ST_ATTACHMENT_COUNT];
>>     unsigned num_statts;
>> -   int32_t revalidate;
>> +   int32_t stamp;
>>   };
>>
>>
>> diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
>> index a68544d..cc688a3 100644
>> --- a/src/mesa/state_tracker/st_manager.c
>> +++ b/src/mesa/state_tracker/st_manager.c
>> @@ -139,18 +139,52 @@ buffer_index_to_attachment(gl_buffer_index index)
>>   }
>>
>>   /**
>> + * Make sure a context picks up the latest cached state of the
>> + * drawables it binds to.
>> + */
>> +static void
>> +st_context_validate(struct st_context *st,
>> +                    struct st_framebuffer *stdraw,
>> +                    struct st_framebuffer *stread)
>> +{
>> +    if (stdraw&&  stdraw->stamp != st->draw_stamp) {
>> +       st->dirty.st |= ST_NEW_FRAMEBUFFER;
>> +       _mesa_resize_framebuffer(st->ctx,&stdraw->Base,
>> +                                stdraw->Base.Width,
>> +                                stdraw->Base.Height);
>> +       st->draw_stamp = stdraw->stamp;
>> +    }
>> +
>> +    if (stread&&  stread->stamp != st->read_stamp) {
>> +       if (stread != stdraw) {
>> +          st->dirty.st |= ST_NEW_FRAMEBUFFER;
>> +          _mesa_resize_framebuffer(st->ctx,&stread->Base,
>> +                                   stread->Base.Width,
>> +                                   stread->Base.Height);
>> +       }
>> +       st->read_stamp = stread->stamp;
>> +    }
>> +}
>> +
>> +/**
>>   * Validate a framebuffer to make sure up-to-date pipe_textures are used.
>> + * The context we need to pass in is s dummy context needed only to be
>> + * able to get a pipe context to create pipe surfaces, and to have a
>> + * context to call _mesa_resize_framebuffer():
>> + * (That should probably be rethought, since those surfaces become
>> + * drawable state, not context state, and can be freed by another pipe
>> + * context).
>>   */
>>   static void
>> -st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
>> +st_framebuffer_validate(struct st_framebuffer *stfb,
>> +                        struct st_context *st)
>>   {
>> -   struct pipe_context *pipe = st->pipe;
>>     struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
>>     uint width, height;
>>     unsigned i;
>>     boolean changed = FALSE;
>>
>> -   if (!p_atomic_read(&stfb->revalidate))
>> +   if (!p_atomic_read(&stfb->iface->invalid))
>>        return;
>>
>>     /* validate the fb */
>> @@ -184,7 +218,7 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
>>        memset(&surf_tmpl, 0, sizeof(surf_tmpl));
>>        u_surface_default_template(&surf_tmpl, textures[i],
>>                                   PIPE_BIND_RENDER_TARGET);
>> -      ps = pipe->create_surface(pipe, textures[i],&surf_tmpl);
>> +      ps = st->pipe->create_surface(st->pipe, textures[i],&surf_tmpl);
>>        if (ps) {
>>           pipe_surface_reference(&strb->surface, ps);
>>           pipe_resource_reference(&strb->texture, ps->texture);
>> @@ -204,14 +238,9 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
>>     }
>>
>>     if (changed) {
>> -      st->dirty.st |= ST_NEW_FRAMEBUFFER;
>> +      ++stfb->stamp;
>>        _mesa_resize_framebuffer(st->ctx,&stfb->Base, width, height);
>> -
>> -      assert(stfb->Base.Width == width);
>> -      assert(stfb->Base.Height == height);
>>     }
>> -
>> -   p_atomic_set(&stfb->revalidate, FALSE);
>>   }
>>
>>   /**
>> @@ -237,7 +266,7 @@ st_framebuffer_update_attachments(struct st_framebuffer *stfb)
>>           stfb->statts[stfb->num_statts++] = statt;
>>     }
>>
>> -   p_atomic_set(&stfb->revalidate, TRUE);
>> +   stfb->stamp = 0;
>>   }
>>
>>   /**
>> @@ -443,6 +472,7 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi)
>>           &stfb->Base._ColorReadBufferIndex);
>>
>>     stfb->iface = stfbi;
>> +   p_atomic_set(&stfbi->invalid, TRUE);
>>
>>     /* add the color buffer */
>>     idx = stfb->Base._ColorDrawBufferIndexes[0];
>> @@ -473,31 +503,6 @@ st_framebuffer_reference(struct st_framebuffer **ptr,
>>   }
>>
>>   static void
>> -st_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
>> -                                      struct st_framebuffer_iface *stfbi)
>> -{
>> -   struct st_context *st = (struct st_context *) stctxi;
>> -   struct st_framebuffer *stfb;
>> -
>> -   /* either draw or read winsys fb */
>> -   stfb = st_ws_framebuffer(st->ctx->WinSysDrawBuffer);
>> -   if (!stfb || stfb->iface != stfbi)
>> -      stfb = st_ws_framebuffer(st->ctx->WinSysReadBuffer);
>> -
>> -   if (stfb&&  stfb->iface == stfbi) {
>> -      p_atomic_set(&stfb->revalidate, TRUE);
>> -   }
>> -   else {
>> -      /* This function is probably getting called when we've detected a
>> -       * change in a window's size but the currently bound context is
>> -       * not bound to that window.
>> -       * If the st_framebuffer_iface structure had a pointer to the
>> -       * corresponding st_framebuffer we'd be able to handle this.
>> -       */
>> -   }
>> -}
>> -
>> -static void
>>   st_context_flush(struct st_context_iface *stctxi, unsigned flags,
>>                   struct pipe_fence_handle **fence)
>>   {
>> @@ -696,8 +701,6 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
>>        smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE);
>>
>>     st->iface.destroy = st_context_destroy;
>> -   st->iface.notify_invalid_framebuffer =
>> -      st_context_notify_invalid_framebuffer;
>>     st->iface.flush = st_context_flush;
>>     st->iface.teximage = st_context_teximage;
>>     st->iface.copy = st_context_copy;
>> @@ -757,6 +760,10 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
>>           }
>>
>>           ret = _mesa_make_current(st->ctx,&stdraw->Base,&stread->Base);
>> +
>> +         st->draw_stamp = stdraw->stamp - 1;
>> +         st->read_stamp = stread->stamp - 1;
>> +         st_context_validate(st, stdraw, stread);
>>        }
>>        else {
>>           struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer();
>> @@ -857,6 +864,8 @@ st_manager_validate_framebuffers(struct st_context *st)
>>        st_framebuffer_validate(stdraw, st);
>>     if (stread&&  stread != stdraw)
>>        st_framebuffer_validate(stread, st);
>> +
>> +   st_context_validate(st, stdraw, stread);
>>   }
>>
>>   /**
>> --
>> 1.7.4.4
>>
>>
>>      
>
>
>    



More information about the mesa-dev mailing list