EmuGL: Deliver every frame to a callback

To enable multi-touch on a tethered device, allow a callback to be
registered with the OpenGL renderer. On every frame, the framebuffer
is read into system memory and provided to the callback, so it can be
mirrored to the device.

This change is co-dependent on Idae3b026d52ed8dd666cbcdc3f3af80175c90ad3
in external/qemu.

Change-Id: I03c49bc55ed9e66ffb59462333181f77e7e46035
This commit is contained in:
Jesse Hall
2012-03-21 11:43:43 -07:00
parent 34460c1e62
commit 08d643e5eb
5 changed files with 84 additions and 11 deletions

View File

@@ -101,7 +101,7 @@ void FrameBuffer::finalize(){
}
}
bool FrameBuffer::initialize(int width, int height)
bool FrameBuffer::initialize(int width, int height, OnPostFn onPost, void* onPostContext)
{
if (s_theFrameBuffer != NULL) {
return true;
@@ -110,7 +110,7 @@ bool FrameBuffer::initialize(int width, int height)
//
// allocate space for the FrameBuffer object
//
FrameBuffer *fb = new FrameBuffer(width, height);
FrameBuffer *fb = new FrameBuffer(width, height, onPost, onPostContext);
if (!fb) {
ERR("Failed to create fb\n");
return false;
@@ -334,6 +334,17 @@ bool FrameBuffer::initialize(int width, int height)
//
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;
}
}
// release the FB context
fb->unbind_locked();
@@ -344,7 +355,8 @@ bool FrameBuffer::initialize(int width, int height)
return true;
}
FrameBuffer::FrameBuffer(int p_width, int p_height) :
FrameBuffer::FrameBuffer(int p_width, int p_height,
OnPostFn onPost, void* onPostContext) :
m_width(p_width),
m_height(p_height),
m_eglDisplay(EGL_NO_DISPLAY),
@@ -360,13 +372,17 @@ FrameBuffer::FrameBuffer(int p_width, int p_height) :
m_zRot(0.0f),
m_eglContextInitialized(false),
m_statsNumFrames(0),
m_statsStartTime(0LL)
m_statsStartTime(0LL),
m_onPost(onPost),
m_onPostContext(onPostContext),
m_fbImage(NULL)
{
m_fpsStats = getenv("SHOW_FPS_STATS") != NULL;
}
FrameBuffer::~FrameBuffer()
{
free(m_fbImage);
}
bool FrameBuffer::setupSubWindow(FBNativeWindowType p_window,
@@ -799,6 +815,15 @@ bool FrameBuffer::post(HandleType p_colorbuffer, bool needLock)
s_gl.glPopMatrix();
if (ret) {
//
// Send framebuffer (without FPS overlay) to callback
//
if (m_onPost) {
s_gl.glReadPixels(0, 0, m_width, m_height,
GL_RGBA, GL_UNSIGNED_BYTE, m_fbImage);
m_onPost(m_onPostContext, m_width, m_height, -1,
GL_RGBA, GL_UNSIGNED_BYTE, m_fbImage);
}
//
// output FPS statistics