I have a graphical glitch related to blending in my OpenGL application using Android NDK.
The strange thing is that when I take a screenshot through adb screencap
command, the problem completely disappears and the result looks okay.
My question is:
Is there a way to know what is happening behind the scenes of making screenshots? Is there eglChooseConfig
called with some specific values for the entire frame for example? Or maybe is there some specific initial GL state forced?
Some background:
My device is using Qualcomm Adreno 320.
The glich occurs when I call glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
for some of the geometry.
I have also found that setting glColorMask(1, 1, 1, 0)
results in a black screen on my device (and only on this device), whereas taking a screenshot results in a complete, correct game frame.
The application outputs no glitches on several other Android devices, and other applications work well, even ones that use blending extensively.
Generally speaking, devices don't have a framebuffer full of pixels that you can copy out of when capturing the screen. The "screen capture" functions are actually "redraw the screen into a buffer" functions. It's possible for the screen capture to be slightly different, deliberately so if a "secure" layer or DRM content is on screen.
Is this a single, fully opaque Surface? Or is it being blended with another layer above or below?
The most common reason for differences is bugs in the Hardware Composer, but it sounds like you're seeing issues rendering on a single surface, so that is less likely. If you have a rooted device, you can turn HWC composition on and off using the commands shown here:
adb shell service call SurfaceFlinger 1008 i32 1
will disable overlays and force GLES composition. (If none of that made any sense, read through the graphics architecture doc.)Are you able to post images of the correct and glitched images? (One via screenshot, one by taking a picture of the device with a second device.)
Do you see similar issues if you record the screen with
adb shell screenrecord
?The problem disappeared once I commented out
EGL_ALPHA_SIZE
setting:It looks like with alpha set to 8 bits,
eglChooseConfig
returned a problematic configuration object.Funnily enough, the "correct"
EGLConfig
specifies0
bits forEGL_ALPHA_SIZE
, so at first I would expect it to not work at all. Other devices don't really care about the value and they are doing well provided only RGB channels' depths.I have learned a lesson: if there are graphical glitches on your device, always check all possible EGL configurations!
So my conclusion is: yes, probably there is a custom EGLConfig set inside
adb screencap
.