Search code examples
androidloggingopengl-eslogcat

What is causing SharedBufferStack messages in Android's LogCat?


I'm am doing Android OpenGL ES experiments to see how it performs on different phones. In my Logcat, I get log messages of tag "SharedBufferStack" with either of the lines below

dequeue: tail=0, head=1, avail=2, queued=0

dequeue: tail=1, head=0, avail=2, queued=0

repeated a few times, even though I leave the application alone (no touch or button presses and prevented it from sleeping). I'm wondering what is causing it even though it is not an error. Does it affect performance?

More importantly, how do I remove it?

I'm using the standard Eclipse with Android SDK


Solution

  • TLDR Version: Caused by invoking Thread.sleep() inside OpenGL ES's onDrawFrame().

    I figured some of it by looking at their code at the link below. https://android.googlesource.com/platform/frameworks/native/+/9cce325fae8adcf7560a28eef394489f09bad74d/libs/surfaceflinger_client/SharedBufferStack.cpp

    So this SharedBufferStack is part of SurfaceFlinger of Android which is described at http://rahulonblog.blogspot.sg/2013/06/an-overview-of-surfaceflinger.html

    Surfaceflinger : It is a system-wide surface composer function which resides in android framework. It takes data( which is surface) from different application which could be 2D or 3D and finally combine it to obtain a main surface which will be fed to memory( which is framebuffer). Surfaceflinger synthesize all the surface according to their position, size and other parameters, although this synthesis is done by OpenGL(which is invoked by Surfaceflinger), but we need Surfaceflinger to calculate the relevant parameters like overlapping function.

    Which means that the SharedBufferStack is for different applications to share the memory for the graphical interface (correct me if I'm wrong).

    Turns out at lines 281 and 282, it where the LOGW(Logcat invoked warning) gets called.

    LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d",
                tail, stack.head, stack.available, stack.queued);
    

    Which if you read the rest of the function block, SharedBufferClient::dequeue is trying to warn that the stack is empty/close to empty.

    If I make a wild guess, I think that the "graphics" stack needs to at least have something on or else its got nothing to show. I still don't know why it invokes stack.head==tail when tail = 0 and stack.head = 1. I don't see how its actually a stack.

    === UPDATE 1

    Apparently after more testing, it happens to be my Thread.sleep I call in the onDrawFrame of the OpenGL ES loop. Since RENDERMODE_CONTINUOUSLY does not control framerate properly (since I want to limit it to 30 frames per second rather than make it run crazy fast), I made the thread sleep for the time remaining.

    Thread.sleep(16 - diffTime);
    

    Which if I'm correct, sleeps the opengl thread. Apparently it causes the messages above to appear and doesn't sound too good since you take the graphics thread off the stack. One way that I think I could do is to run a separate thread that calls onDrawFrame to render with RENDERMODE_WHEN_DIRTY. Another way would be to let it run as fast, but call your logic loop or controller every 0.017s(60 fps) interval for stuff like animation and other things.

    === Update 2

    I did the one where you allow the image to be rendered as fast as possible, but use the time to find out when to run the logic.