aboutsummaryrefslogtreecommitdiffstats
path: root/emulator
diff options
context:
space:
mode:
authorJesse Hall <jessehall@google.com>2012-05-10 21:55:36 -0700
committerandroid code review <noreply-gerritcodereview@google.com>2012-05-10 21:55:37 -0700
commit257abb47724bedf562f96d61014551b2c212d419 (patch)
tree340a3b4170514962883e8644d4e9533b3469c205 /emulator
parent4485b74e8c374f00493b6e368ad6fb924abc7e35 (diff)
parentab800d7b0188e840407a61fa931f678d2ef46de6 (diff)
downloadsdk-257abb47724bedf562f96d61014551b2c212d419.zip
sdk-257abb47724bedf562f96d61014551b2c212d419.tar.gz
sdk-257abb47724bedf562f96d61014551b2c212d419.tar.bz2
Merge "Allow frame callback to be enabled/disabled"
Diffstat (limited to 'emulator')
-rw-r--r--emulator/opengl/host/include/libOpenglRender/render_api.h69
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp38
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h6
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/render_api.cpp26
-rw-r--r--emulator/opengl/host/renderer/main.cpp2
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;