diff options
author | Jesse Hall <jessehall@google.com> | 2014-05-23 16:39:09 -0700 |
---|---|---|
committer | Jesse Hall <jessehall@google.com> | 2014-05-27 16:55:32 -0700 |
commit | 40e0b05e6dbceced8b666108d100e5a28e81b7dd (patch) | |
tree | ea734a41c68024924002c1a9e0df728dadea498d | |
parent | 93aa02793ea1594d788a3ec67139db183dc307b4 (diff) | |
download | sdk-40e0b05e6dbceced8b666108d100e5a28e81b7dd.zip sdk-40e0b05e6dbceced8b666108d100e5a28e81b7dd.tar.gz sdk-40e0b05e6dbceced8b666108d100e5a28e81b7dd.tar.bz2 |
opengl: rcOpenColorBuffer must be synchronous
The gralloc register_buffer() function, which calls rcOpenColorBuffer,
must actually increment the reference count before returning.
Otherwise the buffer allocator may release its reference before the
client has obtained one, and the buffer will be freed prematurely.
Since rcOpenColorBuffer was just sending a message to the host without
waiting for it to be received/processed, this guarantee was not met.
Adding a return value makes the call synchronous.
Bug: 12988668
Change-Id: I8b2399cfb0f600f99b3387f630343291b59bc9a6
6 files changed, 24 insertions, 13 deletions
diff --git a/emulator/opengl/gen-encoder.sh b/emulator/opengl/gen-encoder.sh index 23ecf03..c55a170 100755 --- a/emulator/opengl/gen-encoder.sh +++ b/emulator/opengl/gen-encoder.sh @@ -12,17 +12,12 @@ if [ -z "$ANDROID_BUILD_TOP" ]; then fi cd "$ANDROID_BUILD_TOP" >/dev/null SRCDIR="sdk/emulator/opengl/host/libs" -DSTDIR="development/tools/emulator/opengl/system" +DSTDIR="device/generic/goldfish/opengl/system" +EMUGEN="external/qemu/objs/emugen" if [ ! -d "$SRCDIR" -o ! -d "$DSTDIR" ]; then echo error: can\'t find source and/or destination directory exit 1 fi - -if [ -z "$ANDROID_HOST_OUT" ]; then - echo error: ANDROID_HOST_OUT not set - exit 1 -fi -EMUGEN="$ANDROID_HOST_OUT/bin/emugen" if [ ! -x "$EMUGEN" ]; then echo error: emugen not available, did you forget to build? exit 1 diff --git a/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp b/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp index 532ffe7..e612294 100644 --- a/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp +++ b/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp @@ -298,6 +298,7 @@ bool ColorBuffer::bind_fbo() GL_TEXTURE_2D, m_tex, 0); GLenum status = s_gl.glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); if (status != GL_FRAMEBUFFER_COMPLETE_OES) { + ERR("ColorBuffer::bind_fbo: FBO not complete: %#x\n", status); s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); s_gl.glDeleteFramebuffersOES(1, &m_fbo); m_fbo = 0; diff --git a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp index 238f2c9..e7a7960 100644 --- a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp +++ b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp @@ -551,15 +551,17 @@ void FrameBuffer::DestroyWindowSurface(HandleType p_surface) m_windows.erase(p_surface); } -void FrameBuffer::openColorBuffer(HandleType p_colorbuffer) +int FrameBuffer::openColorBuffer(HandleType p_colorbuffer) { emugl::Mutex::AutoLock mutex(m_lock); ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); if (c == m_colorbuffers.end()) { // bad colorbuffer handle - return; + ERR("FB: openColorBuffer cb handle %#x not found\n", p_colorbuffer); + return -1; } (*c).second.refcount++; + return 0; } void FrameBuffer::closeColorBuffer(HandleType p_colorbuffer) @@ -567,6 +569,7 @@ void FrameBuffer::closeColorBuffer(HandleType p_colorbuffer) emugl::Mutex::AutoLock mutex(m_lock); ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); if (c == m_colorbuffers.end()) { + ERR("FB: closeColorBuffer cb handle %#x not found\n", p_colorbuffer); // bad colorbuffer handle return; } @@ -581,6 +584,7 @@ bool FrameBuffer::flushWindowSurfaceColorBuffer(HandleType p_surface) WindowSurfaceMap::iterator w( m_windows.find(p_surface) ); if (w == m_windows.end()) { + ERR("FB::flushWindowSurfaceColorBuffer: window handle %#x not found\n", p_surface); // bad surface handle return false; } @@ -596,11 +600,13 @@ bool FrameBuffer::setWindowSurfaceColorBuffer(HandleType p_surface, WindowSurfaceMap::iterator w( m_windows.find(p_surface) ); if (w == m_windows.end()) { // bad surface handle + ERR("%s: bad window surface handle %#x\n", __FUNCTION__, p_surface); return false; } ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); if (c == m_colorbuffers.end()) { + ERR("%s: bad color buffer handle %#x\n", __FUNCTION__, p_colorbuffer); // bad colorbuffer handle return false; } diff --git a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h index 5b03624..f8683b2 100644 --- a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h +++ b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h @@ -73,7 +73,7 @@ public: HandleType createColorBuffer(int p_width, int p_height, GLenum p_internalFormat); void DestroyRenderContext(HandleType p_context); void DestroyWindowSurface(HandleType p_surface); - void openColorBuffer(HandleType p_colorbuffer); + int openColorBuffer(HandleType p_colorbuffer); void closeColorBuffer(HandleType p_colorbuffer); bool bindContext(HandleType p_context, HandleType p_drawSurface, HandleType p_readSurface); diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp b/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp index 6a15138..83ba9c5 100644 --- a/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp +++ b/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp @@ -215,13 +215,20 @@ static uint32_t rcCreateColorBuffer(uint32_t width, return fb->createColorBuffer(width, height, internalFormat); } -static void rcOpenColorBuffer(uint32_t colorbuffer) +static int rcOpenColorBuffer2(uint32_t colorbuffer) { FrameBuffer *fb = FrameBuffer::getFB(); if (!fb) { - return; + return -1; } - fb->openColorBuffer( colorbuffer ); + return fb->openColorBuffer( colorbuffer ); +} + +// Deprecated, kept for compatibility with old system images only. +// Use rcOpenColorBuffer2 instead. +static void rcOpenColorBuffer(uint32_t colorbuffer) +{ + (void) rcOpenColorBuffer2(colorbuffer); } static void rcCloseColorBuffer(uint32_t colorbuffer) @@ -359,4 +366,5 @@ void initRenderControlContext(renderControl_decoder_context_t *dec) dec->set_rcColorBufferCacheFlush(rcColorBufferCacheFlush); dec->set_rcReadColorBuffer(rcReadColorBuffer); dec->set_rcUpdateColorBuffer(rcUpdateColorBuffer); + dec->set_rcOpenColorBuffer2(rcOpenColorBuffer2); } diff --git a/emulator/opengl/host/libs/renderControl_dec/renderControl.in b/emulator/opengl/host/libs/renderControl_dec/renderControl.in index 8281fd9..55539f9 100644 --- a/emulator/opengl/host/libs/renderControl_dec/renderControl.in +++ b/emulator/opengl/host/libs/renderControl_dec/renderControl.in @@ -23,3 +23,4 @@ GL_ENTRY(void, rcBindRenderbuffer, uint32_t colorBuffer) GL_ENTRY(EGLint, rcColorBufferCacheFlush, uint32_t colorbuffer, EGLint postCount,int forRead) GL_ENTRY(void, rcReadColorBuffer, uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void *pixels) GL_ENTRY(int, rcUpdateColorBuffer, uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void *pixels) +GL_ENTRY(int, rcOpenColorBuffer2, uint32_t colorbuffer) |