diff options
author | Jesse Hall <jessehall@google.com> | 2012-05-10 21:55:36 -0700 |
---|---|---|
committer | android code review <noreply-gerritcodereview@google.com> | 2012-05-10 21:55:37 -0700 |
commit | 257abb47724bedf562f96d61014551b2c212d419 (patch) | |
tree | 340a3b4170514962883e8644d4e9533b3469c205 /emulator | |
parent | 4485b74e8c374f00493b6e368ad6fb924abc7e35 (diff) | |
parent | ab800d7b0188e840407a61fa931f678d2ef46de6 (diff) | |
download | sdk-257abb47724bedf562f96d61014551b2c212d419.zip sdk-257abb47724bedf562f96d61014551b2c212d419.tar.gz sdk-257abb47724bedf562f96d61014551b2c212d419.tar.bz2 |
Merge "Allow frame callback to be enabled/disabled"
Diffstat (limited to 'emulator')
5 files changed, 84 insertions, 57 deletions
diff --git a/emulator/opengl/host/include/libOpenglRender/render_api.h b/emulator/opengl/host/include/libOpenglRender/render_api.h index ebb02eb..4fe54f4 100644 --- a/emulator/opengl/host/include/libOpenglRender/render_api.h +++ b/emulator/opengl/host/include/libOpenglRender/render_api.h @@ -41,38 +41,6 @@ extern "C" { ret name args #endif -/* If a function with this signature is passed to initOpenGLRenderer(), - * it will be called by the renderer just before each new frame is displayed, - * providing a copy of the framebuffer contents. - * - * The callback will be called from one of the renderer's threads, so will - * probably need synchronization on any data structures it modifies. The - * pixels buffer may be overwritten as soon as the callback returns; if it needs - * the pixels afterwards it must copy them. - * - * The pixels buffer is intentionally not const: the callback may modify the - * data without copying to another buffer if it wants, e.g. in-place RGBA to RGB - * conversion, or in-place y-inversion. - * - * Parameters are: - * context The pointer optionally provided when the callback was - * registered. The client can use this to pass whatever - * information it wants to the callback. - * width, height Dimensions of the image, in pixels. Rows are tightly packed; - * there is no inter-row padding. - * ydir Indicates row order: 1 means top-to-bottom order, -1 means - * bottom-to-top order. - * format, type Format and type GL enums, as used in glTexImage2D() or - * glReadPixels(), describing the pixel format. - * pixels The framebuffer image. - * - * In the first implementation, ydir is always -1 (bottom to top), format and - * type are always GL_RGBA and GL_UNSIGNED_BYTE, and the width and height will - * always be the same as the ones passed to initOpenGLRenderer(). - */ -typedef void (*OnPostFn)(void* context, int width, int height, int ydir, - int format, int type, unsigned char* pixels); - /* initLibrary - initialize the library and tries to load the corresponding * GLES translator libraries. This function must be called before anything * else to ensure that everything works. If it returns an error, then @@ -98,8 +66,7 @@ DECL(int, setStreamMode, (int mode)); * This function is *NOT* thread safe and should be called first * to initialize the renderer after initLibrary(). */ -DECL(int, initOpenGLRenderer, (int width, int height, int portNum, - OnPostFn onPost, void* onPostContext)); +DECL(int, initOpenGLRenderer, (int width, int height, int portNum)); /* getHardwareStrings - describe the GPU hardware and driver. * The underlying GL's vendor/renderer/version strings are returned to the @@ -108,6 +75,40 @@ DECL(int, initOpenGLRenderer, (int width, int height, int portNum, DECL(void, getHardwareStrings, (const char** vendor, const char** renderer, const char** version)); +/* A per-frame callback can be registered with setPostCallback(); to remove it + * pass NULL for both parameters. While a callback is registered, the renderer + * will call it just before each new frame is displayed, providing a copy of + * the framebuffer contents. + * + * The callback will be called from one of the renderer's threads, so will + * probably need synchronization on any data structures it modifies. The + * pixels buffer may be overwritten as soon as the callback returns; if it + * needs the pixels afterwards it must copy them. + * + * The pixels buffer is intentionally not const: the callback may modify the + * data without copying to another buffer if it wants, e.g. in-place RGBA to + * RGB conversion, or in-place y-inversion. + * + * Parameters are: + * context The pointer optionally provided when the callback was + * registered. The client can use this to pass whatever + * information it wants to the callback. + * width, height Dimensions of the image, in pixels. Rows are tightly + * packed; there is no inter-row padding. + * ydir Indicates row order: 1 means top-to-bottom order, -1 means + * bottom-to-top order. + * format, type Format and type GL enums, as used in glTexImage2D() or + * glReadPixels(), describing the pixel format. + * pixels The framebuffer image. + * + * In the first implementation, ydir is always -1 (bottom to top), format and + * type are always GL_RGBA and GL_UNSIGNED_BYTE, and the width and height will + * always be the same as the ones passed to initOpenGLRenderer(). + */ +typedef void (*OnPostFn)(void* context, int width, int height, int ydir, + int format, int type, unsigned char* pixels); +DECL(void, setPostCallback, (OnPostFn onPost, void* onPostContext)); + /* createOpenGLSubwindow - * Create a native subwindow which is a child of 'window' * to be used for framebuffer display. diff --git a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp index fde82a1..2f7cd61 100644 --- a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp +++ b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp @@ -101,7 +101,7 @@ void FrameBuffer::finalize(){ } } -bool FrameBuffer::initialize(int width, int height, OnPostFn onPost, void* onPostContext) +bool FrameBuffer::initialize(int width, int height) { if (s_theFrameBuffer != NULL) { return true; @@ -110,7 +110,7 @@ bool FrameBuffer::initialize(int width, int height, OnPostFn onPost, void* onPos // // allocate space for the FrameBuffer object // - FrameBuffer *fb = new FrameBuffer(width, height, onPost, onPostContext); + FrameBuffer *fb = new FrameBuffer(width, height); if (!fb) { ERR("Failed to create fb\n"); return false; @@ -335,17 +335,6 @@ bool FrameBuffer::initialize(int width, int height, OnPostFn onPost, void* onPos fb->initGLState(); // - // Allocate space for the onPost framebuffer image - // - if (onPost) { - fb->m_fbImage = (unsigned char*)malloc(4 * width * height); - if (!fb->m_fbImage) { - delete fb; - return false; - } - } - - // // Cache the GL strings so we don't have to think about threading or // current-context when asked for them. // @@ -363,8 +352,7 @@ bool FrameBuffer::initialize(int width, int height, OnPostFn onPost, void* onPos return true; } -FrameBuffer::FrameBuffer(int p_width, int p_height, - OnPostFn onPost, void* onPostContext) : +FrameBuffer::FrameBuffer(int p_width, int p_height) : m_width(p_width), m_height(p_height), m_eglDisplay(EGL_NO_DISPLAY), @@ -381,8 +369,8 @@ FrameBuffer::FrameBuffer(int p_width, int p_height, m_eglContextInitialized(false), m_statsNumFrames(0), m_statsStartTime(0LL), - m_onPost(onPost), - m_onPostContext(onPostContext), + m_onPost(NULL), + m_onPostContext(NULL), m_fbImage(NULL), m_glVendor(NULL), m_glRenderer(NULL), @@ -396,6 +384,22 @@ FrameBuffer::~FrameBuffer() free(m_fbImage); } +void FrameBuffer::setPostCallback(OnPostFn onPost, void* onPostContext) +{ + android::Mutex::Autolock mutex(m_lock); + m_onPost = onPost; + m_onPostContext = onPostContext; + if (m_onPost && !m_fbImage) { + m_fbImage = (unsigned char*)malloc(4 * m_width * m_height); + if (!m_fbImage) { + ERR("out of memory, cancelling OnPost callback"); + m_onPost = NULL; + m_onPostContext = NULL; + return; + } + } +} + bool FrameBuffer::setupSubWindow(FBNativeWindowType p_window, int p_x, int p_y, int p_width, int p_height, float zRot) diff --git a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h index 89a708b..de0b71c 100644 --- a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h +++ b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h @@ -46,7 +46,7 @@ struct FrameBufferCaps class FrameBuffer { public: - static bool initialize(int width, int height, OnPostFn onPost, void* onPostContext); + static bool initialize(int width, int height); static bool setupSubWindow(FBNativeWindowType p_window, int x, int y, int width, int height, float zRot); @@ -59,6 +59,8 @@ public: int getWidth() const { return m_width; } int getHeight() const { return m_height; } + void setPostCallback(OnPostFn onPost, void* onPostContext); + void getGLStrings(const char** vendor, const char** renderer, const char** version) const { *vendor = m_glVendor; *renderer = m_glRenderer; @@ -96,7 +98,7 @@ public: } private: - FrameBuffer(int p_width, int p_height, OnPostFn onPost, void* onPostContext); + FrameBuffer(int p_width, int p_height); ~FrameBuffer(); HandleType genHandle(); bool bindSubwin_locked(); diff --git a/emulator/opengl/host/libs/libOpenglRender/render_api.cpp b/emulator/opengl/host/libs/libOpenglRender/render_api.cpp index 7d7a981..72cd9ba 100644 --- a/emulator/opengl/host/libs/libOpenglRender/render_api.cpp +++ b/emulator/opengl/host/libs/libOpenglRender/render_api.cpp @@ -76,8 +76,7 @@ int initLibrary(void) return true; } -int initOpenGLRenderer(int width, int height, int portNum, - OnPostFn onPost, void* onPostContext) +int initOpenGLRenderer(int width, int height, int portNum) { // @@ -94,7 +93,7 @@ int initOpenGLRenderer(int width, int height, int portNum, // initialize the renderer and listen to connections // on a thread in the current process. // - bool inited = FrameBuffer::initialize(width, height, onPost, onPostContext); + bool inited = FrameBuffer::initialize(width, height); if (!inited) { return false; } @@ -191,6 +190,27 @@ int initOpenGLRenderer(int width, int height, int portNum, return true; } +void setPostCallback(OnPostFn onPost, void* onPostContext) +{ +#ifdef RENDER_API_USE_THREAD // should be defined for mac + FrameBuffer* fb = FrameBuffer::getFB(); + if (fb) { + fb->setPostCallback(onPost, onPostContext); + } +#else + if (onPost) { + // onPost callback not supported with separate renderer process. + // + // If we ever revive separate process support, we could make the choice + // between thread and process at runtime instead of compile time, and + // choose the thread path if an onPost callback is requested. Or, the + // callback could be supported with a separate process using shmem or + // other IPC mechanism. + return false; + } +#endif +} + void getHardwareStrings(const char** vendor, const char** renderer, const char** version) { FrameBuffer* fb = FrameBuffer::getFB(); diff --git a/emulator/opengl/host/renderer/main.cpp b/emulator/opengl/host/renderer/main.cpp index ae7ace3..4549c56 100644 --- a/emulator/opengl/host/renderer/main.cpp +++ b/emulator/opengl/host/renderer/main.cpp @@ -120,7 +120,7 @@ int main(int argc, char *argv[]) // // initialize Framebuffer // - bool inited = FrameBuffer::initialize(winWidth, winHeight, NULL, NULL); + bool inited = FrameBuffer::initialize(winWidth, winHeight); if (!inited) { fprintf(stderr,"Failed to initialize Framebuffer\n"); return -1; |