adb screencap output is different than on the devi

2019-09-08 14:26发布

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.

2条回答
混吃等死
2楼-- · 2019-09-08 14:56

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?

查看更多
三岁会撩人
3楼-- · 2019-09-08 15:17

The problem disappeared once I commented out EGL_ALPHA_SIZE setting:

const EGLint attribs[] = {
    EGL_BLUE_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_RED_SIZE, 8,
    //EGL_ALPHA_SIZE, 8,
    EGL_NONE
};

It looks like with alpha set to 8 bits, eglChooseConfig returned a problematic configuration object.

Funnily enough, the "correct" EGLConfig specifies 0 bits for EGL_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.

查看更多
登录 后发表回答