[Mesa-dev] [PATCH 1/4] mesa: only lock framebuffer in compat profile
Timothy Arceri
tarceri at itsqueeze.com
Mon Apr 24 10:45:29 UTC 2017
On 24/04/17 20:06, Nicolai Hähnle wrote:
> On 24.04.2017 07:28, Timothy Arceri wrote:
>> From the EXT_framebuffer_object spec:
>>
>> "Framebuffer objects created with the commands defined
>> by the GL_EXT_framebuffer_object extension are defined
>> to be shared, while FBOs created with commands defined
>> by the OpenGL core or GL_ARB_framebuffer_object
>> extension are defined *not* to be shared. However, the
>> following functions are viewed as aliases (in particular
>> the opcodes for X are also the same) between the functions
>> of GL_EXT_framebuffer_object and
>> GL_ARB_framebuffer_object:
>>
>> ...
>>
>> Since the above pairs are aliases, the functions of a
>> pair are equivalent. Note that the functions
>> BindFramebuffer and BindFramebufferEXT are not aliases
>> and neither are the functions BindRenderbuffer and
>> BindRenderbufferEXT. Because object creation occurs
>> when the framebuffer object is bound for the first time,
>> a framebuffer object can be shared across contexts only
>> if it was first bound with BindFramebufferEXT.
>> Framebuffers first bound with BindFramebuffer may not
>> be shared across contexts. Framebuffer objects created
>> with BindFramebufferEXT may subsequently be bound using
>> BindFramebuffer. Framebuffer objects created with
>> BindFramebuffer may be bound with BindFramebufferEXT
>> provided they are bound to the same context they were
>> created on."
>>
>> So in theory we could have a flag that is set by the bind
>> functions to decide if to lock or not. However we only
>> expose GL_EXT_framebuffer_object in compat profile so this
>> change just uses that to decide if we should lock or not.
>> ---
>> src/mesa/main/fbobject.c | 45 ++++++++++++++++++++++++++--------
>> src/mesa/main/framebuffer.c | 60
>> +++++++++++++++++++++++++++++++--------------
>> 2 files changed, 76 insertions(+), 29 deletions(-)
> [snip]
>> diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
>> index 9002020..b42bfba 100644
>> --- a/src/mesa/main/framebuffer.c
>> +++ b/src/mesa/main/framebuffer.c
>> @@ -234,42 +234,64 @@ _mesa_free_framebuffer_data(struct
>> gl_framebuffer *fb)
>>
>> /**
>> * Set *ptr to point to fb, with refcounting and locking.
>> * This is normally only called from the
>> _mesa_reference_framebuffer() macro
>> * when there's a real pointer change.
>> */
>> void
>> _mesa_reference_framebuffer_(struct gl_framebuffer **ptr,
>> struct gl_framebuffer *fb)
>> {
>> - if (*ptr) {
>> - /* unreference old renderbuffer */
>> - GLboolean deleteFlag = GL_FALSE;
>> - struct gl_framebuffer *oldFb = *ptr;
>> -
>> - mtx_lock(&oldFb->Mutex);
>> - assert(oldFb->RefCount > 0);
>> - oldFb->RefCount--;
>> - deleteFlag = (oldFb->RefCount == 0);
>> - mtx_unlock(&oldFb->Mutex);
>> + GET_CURRENT_CONTEXT(ctx);
>> +
>> + if (!ctx || ctx->API != API_OPENGL_COMPAT) {
>
> When does !ctx happen, and does it really guarantee not having a
> compatibility context?
When _mesa_make_current() is called with a NULL ctx and during some
destruction calls. Looking at this again I think you are right it's
probably more safe to do:
if (ctx && ctx->API != API_OPENGL_COMPAT)
I'll change this.
>
> BTW, what are the rules for having contexts of different GL versions /
> different compatibility vs. core type in the same share group?
Hmm ... it doesn't seem to say anything about this, maybe this isn't
going to work.
>
> Cheers,
> Nicolai
>
>
>> + if (*ptr) {
>> + /* unreference old renderbuffer */
>> + struct gl_framebuffer *oldFb = *ptr;
>> +
>> + assert(oldFb->RefCount > 0);
>> + oldFb->RefCount--;
>>
>> - if (deleteFlag)
>> - oldFb->Delete(oldFb);
>> + if (oldFb->RefCount == 0)
>> + oldFb->Delete(oldFb);
>>
>> - *ptr = NULL;
>> - }
>> + *ptr = NULL;
>> + }
>>
>> - if (fb) {
>> - mtx_lock(&fb->Mutex);
>> - fb->RefCount++;
>> - mtx_unlock(&fb->Mutex);
>> - *ptr = fb;
>> + if (fb) {
>> + fb->RefCount++;
>> + *ptr = fb;
>> + }
>> + } else {
>> + if (*ptr) {
>> + /* unreference old renderbuffer */
>> + bool deleteFlag = false;
>> + struct gl_framebuffer *oldFb = *ptr;
>> +
>> + mtx_lock(&oldFb->Mutex);
>> + assert(oldFb->RefCount > 0);
>> + oldFb->RefCount--;
>> + deleteFlag = (oldFb->RefCount == 0);
>> + mtx_unlock(&oldFb->Mutex);
>> +
>> + if (deleteFlag)
>> + oldFb->Delete(oldFb);
>> +
>> + *ptr = NULL;
>> + }
>> +
>> + if (fb) {
>> + mtx_lock(&fb->Mutex);
>> + fb->RefCount++;
>> + mtx_unlock(&fb->Mutex);
>> + *ptr = fb;
>> + }
>> }
>> }
>>
>>
>> /**
>> * Resize the given framebuffer's renderbuffers to the new width and
>> height.
>> * This should only be used for window-system framebuffers, not
>> * user-created renderbuffers (i.e. made with
>> GL_EXT_framebuffer_object).
>> * This will typically be called directly from a device driver.
>> *
>>
>
>
More information about the mesa-dev
mailing list