[Mesa-dev] Question about the texture's reference count processing in _mesa_update_texture

zhigang gong zhigang.gong at gmail.com
Fri Nov 25 03:15:09 PST 2011

Sorry, forgot to copy to the mail list.

---------- Forwarded message ----------
From: zhigang gong <zhigang.gong at gmail.com>
Date: Fri, Nov 25, 2011 at 5:18 PM
Subject: Re: [Mesa-dev] Question about the texture's reference count
processing in _mesa_update_texture
To: Brian Paul <brianp at vmware.com>

Hi Brian,

The test case is attached. It is based on the eglkms.c in mesa-demos package.
Here is a explaintation of the case:

1. use gbm to create two bos. one is shadow bo and the other is screen bo.
2. create a shadow image by using the shadow bo's handle.
   Then creat shadow texture from the shadow image.
3. create a screen image by using the screen bo directly.
   Then create screen texture from the screen image.
4. create two frame buffer objects, one is screen fbo and the other is
screen fbo.
5. bind shadow texture to shadow fbo, and bind screen texture to screen fbo.
6. choose shadow fbo as render target, and use shader to fill a rectangle in it.
7. choose screen fbo as render target, set the shadow texture as a
source texture.
  use shader to copy shadow texture to screen fbo.
8. Use KMS to show the screen fbo to the hardware frame buffer.
9. delete all fbos.
10. delete all textures.
11. destroy all images.
12. use the shadow bo's handle to create another shadow image.
13. destroy the shadow image.
14. destroy all gbm bos.
15. other cleanups.

Now the key step is in 7 and 12. By default, the function will fail at step 12.
It will fail to create another shadow image from the shadow bo's handle,
EGL will complain:
"Region for name 1 already exists but is not compatible "
But this confused me, as the previous shadow image is already destroied at
step 11. Why EGL can still find a image region with the same handle?

I traced into mesa and got some finding:

 glDrawArray will implicitly increase the shadow texture's reference count.
 And then latter when we delete the texture, the count will remain 1 rather
 then zero, and then it will not decrease the corresponding image region's
 reference counter and then when we destroy the shadow image,   the
 image's reference counter will also be 1 and can't be freed. Then next time
 we use the same handle to create a new image, it will find the previou zombie
image region and find they are not compatible.

Just simply comment out the glDrawArray in step 7 can avoid this case
to hit the problem, and it can create the second smaller image successfully.

Any hint here.

BTW, Sorry I can't make a simpler test case here, as it seems that
using the shadow
texture as a source texture is a must condition to hit this problem.

Any hint to fix this problem? Thanks.

On Wed, Nov 23, 2011 at 11:49 PM, Brian Paul <brianp at vmware.com> wrote:
> On 11/23/2011 12:28 AM, zhigang gong wrote:
>> Hi guys,
>> I have a question about the internal implementation of glDrawArrays or
>> any rendering functions.
>> In the code path, it calls to _mesa_update_texture(), and if there is
>> really a complete texture,
>> it will call _mesa_reference_texobj to set it to _Current, and
>> increase the texture object's reference
>> counter.
>> My question is when it will decrease the reference counter? This
>> implicit increasing seems
>> causes the reference counter unbalanced, and then will cause
>> unexpected behaviour. Here is an
>> example:
>> 1       glGenTextures(1, &tex);
>> 2       glActiveTexture(GL_TEXTURE0);
>> 3       glBindTexture(GL_TEXTURE_2D, tex);
>> 4       glTexImage2D(GL_TEXTURE_2D, 0, iformat,
>>                                w, h, 0, format, type, bits);
>> 5       glEnable(GL_TEXTURE_2D);
>> 6       glUseProgram(shader_prog);
>> 7        ... /*setup attribute array here.*/
>> 8       glDrawArray(GL_TRIANGLE_FAN, 0, 4);
>> 9       glUseProgram(0);
>> 10     glDeleteTexture(1, &tex);
>> At Line 1, tex object is created with reference count initialized to 1.
>> At Line 3, tex object's reference count increased to 2.
>> At Line 8, it implicit increases tex object's reference count to 3.
>> At Line 10, it implict unbinds the tex object which decreases the
>> count to 2.
>>                  then it try to unreference the tex object which
>> decreases the count to1.
>> You can see that finally, the tex object's reference's count is 1 not
>> zero
>> and thus it will not be freed. This is not what I expected.
>> Is there any mistakes in my use case? Or anyone can tell me how to
>> make sure the texture object get freed after the usage of it.
> As long as the texture object is still bound to unit 0's GL_TEXTURE_2D, the texture will not get deleted.
> When another texture gets bound to the binding point, the "deleted" texture's ref count should go to zero and really be deleted.  For example, binding the default texture object should do that:
> glBindTexture(GL_TEXTURE_2D, 0);
> If this isn't working, can you provide a test program?
> -Brian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: eglkms.c
Type: text/x-csrc
Size: 15920 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20111125/d130bbd5/attachment.c>

More information about the mesa-dev mailing list