升级到4.3后出现屏幕截图客户端错误



我开发了一个本机进程,该进程使用ScreenshotClient来捕获设备屏幕(仅限根设备)我有一个循环,其中ScreenshotClient在每个循环中执行update()。4.3之前一切正常。当我在4.3上运行它时,第一次更新调用成功了,但在第二次调用中,调用结果是-2,我在logcat中得到了这些错误:

E/BufferQueue( 8166): [ScreenshotClient] connect: already connected (cur=1,req=1)
E/libEGL ( 2463): EGLNativeWindowType 0x4116d5f8 already connected to another API
E/libEGL ( 2463): eglCreateWindowSurface:376 error 300b (EGL_BAD_NATIVE_WINDOW)
E/SurfaceFlinger( 2463): captureScreenImplLocked: eglCreateWindowSurface() failed 0x300b

4.3中发生了什么变化导致了这种情况,或者这些错误意味着什么。

我的代码大致如下:

int main(int argc, char** argv) {
    ProcessState::self()->startThreadPool();
    sp < IBinder > display = SurfaceComposerClient::getBuiltInDisplay(
            DEFAULT_DISPLAY_ID);
    ScreenshotClient client;
    while (true) {
        client.update(display);
        pixels = screenshot.getPixels();
        // do something with the data
    }
}

我们的产品中也遇到了类似的问题,通过使用更新版本的头,我们能够部分解决这个问题(它现在适用于Galaxy Nexus,但在4.3上与其他Nexus设备仍然存在问题)

例如:frameworks/native/include/gui/SurfaceComposerClient.h

自4.2以来,这种情况已经发生了变化,因此需要重新编译4.3版的可执行文件。

我仍在努力理解为什么N4和N7同样不起作用,但至少我能够在GN.上取得进展

希望这能有所帮助。

编辑:经过进一步检查,这看起来像是SurfaceFlinger界面中的一个错误。SurfaceComposerClient在内部调用SurfaceFlinger并尝试抓取屏幕。在SurfaceFlinger的4.3版本中,有两种方法可以进行屏幕捕捉。一个用于N4/N7等现代设备(使用某种优化的GL->CPU路线来抓取帧),另一个用于Galaxy Nexus等设备的传统版本(内部使用一种称为"glReadPixels"的方法,使用更昂贵的CPU->CPU路线抓取屏幕)。

现在,在优化的代码路径上,有一个对方法native_window_api_connect的调用,这是第二次调用update()时失败的方法。这是因为之前的更新调用也调用了这个,并获得了与本机窗口的连接,而本机窗口从未发布。它应该通过调用native_window_api_disconnect来释放,但这从未发生过。

但在未优化的代码路径中,会发生连接和随后断开连接的调用,因此一切都很好(假设您首先使用4.3标头构建了本地模块)。

:-)

相关内容

  • 没有找到相关文章