Merge "opengles emulator: support display rotation and resize"
This commit is contained in:
@@ -24,18 +24,51 @@ extern "C" {
|
|||||||
|
|
||||||
//
|
//
|
||||||
// initOpenGLRenderer - initialize the OpenGL renderer process.
|
// initOpenGLRenderer - initialize the OpenGL renderer process.
|
||||||
// window is the native window to be used as the framebuffer.
|
|
||||||
// x,y,width,height are the dimensions of the rendering subwindow.
|
|
||||||
// portNum is the tcp port number the renderer is listening to.
|
// portNum is the tcp port number the renderer is listening to.
|
||||||
|
// width and height are the framebuffer dimensions that will be
|
||||||
|
// reported to the guest display driver.
|
||||||
//
|
//
|
||||||
// returns true if renderer has been starter successfully;
|
// returns true if renderer has been started successfully;
|
||||||
//
|
//
|
||||||
// This function is *NOT* thread safe and should be called first
|
// This function is *NOT* thread safe and should be called first
|
||||||
// to initialize the renderer.
|
// to initialize the renderer.
|
||||||
//
|
//
|
||||||
bool initOpenGLRenderer(FBNativeWindowType window,
|
bool initOpenGLRenderer(int width, int height, int portNum);
|
||||||
int x, int y, int width, int height,
|
|
||||||
int portNum);
|
|
||||||
|
//
|
||||||
|
// createOpenGLSubwindow -
|
||||||
|
// Create a native subwindow which is a child of 'window'
|
||||||
|
// to be used for framebuffer display.
|
||||||
|
// Framebuffer will not get displayed if a subwindow is not
|
||||||
|
// created.
|
||||||
|
// x,y,width,height are the dimensions of the rendering subwindow.
|
||||||
|
// zRot is the rotation to apply on the framebuffer display image.
|
||||||
|
//
|
||||||
|
bool createOpenGLSubwindow(FBNativeWindowType window,
|
||||||
|
int x, int y, int width, int height, float zRot);
|
||||||
|
|
||||||
|
//
|
||||||
|
// destroyOpenGLSubwindow -
|
||||||
|
// destroys the created native subwindow. Once destroyed,
|
||||||
|
// Framebuffer content will not be visible until a new
|
||||||
|
// subwindow will be created.
|
||||||
|
//
|
||||||
|
bool destroyOpenGLSubwindow();
|
||||||
|
|
||||||
|
//
|
||||||
|
// setOpenGLDisplatRotation -
|
||||||
|
// set the framebuffer display image rotation in units
|
||||||
|
// of degrees around the z axis
|
||||||
|
//
|
||||||
|
void setOpenGLDisplayRotation(float zRot);
|
||||||
|
|
||||||
|
//
|
||||||
|
// repaintOpenGLDisplay -
|
||||||
|
// causes the OpenGL subwindow to get repainted with the
|
||||||
|
// latest framebuffer content.
|
||||||
|
//
|
||||||
|
void repaintOpenGLDisplay();
|
||||||
|
|
||||||
//
|
//
|
||||||
// stopOpenGLRenderer - stops the OpenGL renderer process.
|
// stopOpenGLRenderer - stops the OpenGL renderer process.
|
||||||
|
|||||||
@@ -27,14 +27,13 @@ FrameBuffer *FrameBuffer::s_theFrameBuffer = NULL;
|
|||||||
HandleType FrameBuffer::s_nextHandle = 0;
|
HandleType FrameBuffer::s_nextHandle = 0;
|
||||||
|
|
||||||
#ifdef WITH_GLES2
|
#ifdef WITH_GLES2
|
||||||
static const char *getGLES2ExtensionString(EGLDisplay p_dpy,
|
static const char *getGLES2ExtensionString(EGLDisplay p_dpy)
|
||||||
EGLNativeWindowType p_window)
|
|
||||||
{
|
{
|
||||||
EGLConfig config;
|
EGLConfig config;
|
||||||
EGLSurface surface;
|
EGLSurface surface;
|
||||||
|
|
||||||
GLint configAttribs[] = {
|
GLint configAttribs[] = {
|
||||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
@@ -45,9 +44,13 @@ static const char *getGLES2ExtensionString(EGLDisplay p_dpy,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
surface = s_egl.eglCreateWindowSurface(p_dpy, config,
|
EGLint pbufAttribs[] = {
|
||||||
p_window,
|
EGL_WIDTH, 1,
|
||||||
NULL);
|
EGL_HEIGHT, 1,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
surface = s_egl.eglCreatePbufferSurface(p_dpy, config, pbufAttribs);
|
||||||
if (surface == EGL_NO_SURFACE) {
|
if (surface == EGL_NO_SURFACE) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -86,24 +89,17 @@ static const char *getGLES2ExtensionString(EGLDisplay p_dpy,
|
|||||||
|
|
||||||
void FrameBuffer::finalize(){
|
void FrameBuffer::finalize(){
|
||||||
if(s_theFrameBuffer){
|
if(s_theFrameBuffer){
|
||||||
|
s_theFrameBuffer->removeSubWindow();
|
||||||
s_theFrameBuffer->m_colorbuffers.clear();
|
s_theFrameBuffer->m_colorbuffers.clear();
|
||||||
s_theFrameBuffer->m_windows.clear();
|
s_theFrameBuffer->m_windows.clear();
|
||||||
s_theFrameBuffer->m_contexts.clear();
|
s_theFrameBuffer->m_contexts.clear();
|
||||||
s_egl.eglMakeCurrent(s_theFrameBuffer->m_eglDisplay, NULL, NULL, NULL);
|
|
||||||
s_egl.eglDestroySurface(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglSurface);
|
|
||||||
s_egl.eglDestroyContext(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglContext);
|
s_egl.eglDestroyContext(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglContext);
|
||||||
if (s_theFrameBuffer->m_subWin) {
|
s_egl.eglDestroySurface(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_pbufSurface);
|
||||||
destroySubWindow(s_theFrameBuffer->m_subWinDisplay,
|
|
||||||
s_theFrameBuffer->m_subWin);
|
|
||||||
}
|
|
||||||
delete s_theFrameBuffer;
|
|
||||||
s_theFrameBuffer = NULL;
|
s_theFrameBuffer = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FrameBuffer::initialize(FBNativeWindowType p_window,
|
bool FrameBuffer::initialize(int width, int height)
|
||||||
int p_x, int p_y,
|
|
||||||
int p_width, int p_height)
|
|
||||||
{
|
{
|
||||||
if (s_theFrameBuffer != NULL) {
|
if (s_theFrameBuffer != NULL) {
|
||||||
return true;
|
return true;
|
||||||
@@ -130,7 +126,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window,
|
|||||||
//
|
//
|
||||||
// allocate space for the FrameBuffer object
|
// allocate space for the FrameBuffer object
|
||||||
//
|
//
|
||||||
FrameBuffer *fb = new FrameBuffer(p_x, p_y, p_width, p_height);
|
FrameBuffer *fb = new FrameBuffer(width, height);
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
ERR("Failed to create fb\n");
|
ERR("Failed to create fb\n");
|
||||||
return false;
|
return false;
|
||||||
@@ -169,10 +165,6 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window,
|
|||||||
DBG("egl: %d %d\n", fb->m_caps.eglMajor, fb->m_caps.eglMinor);
|
DBG("egl: %d %d\n", fb->m_caps.eglMajor, fb->m_caps.eglMinor);
|
||||||
s_egl.eglBindAPI(EGL_OPENGL_ES_API);
|
s_egl.eglBindAPI(EGL_OPENGL_ES_API);
|
||||||
|
|
||||||
fb->m_nativeWindow = p_window;
|
|
||||||
|
|
||||||
fb->m_subWin = createSubWindow(p_window,&fb->m_subWinDisplay,p_x,p_y,p_width,p_height);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// if GLES2 plugin has loaded - try to make GLES2 context and
|
// if GLES2 plugin has loaded - try to make GLES2 context and
|
||||||
// get GLES2 extension string
|
// get GLES2 extension string
|
||||||
@@ -180,7 +172,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window,
|
|||||||
const char *gl2Extensions = NULL;
|
const char *gl2Extensions = NULL;
|
||||||
#ifdef WITH_GLES2
|
#ifdef WITH_GLES2
|
||||||
if (fb->m_caps.hasGL2) {
|
if (fb->m_caps.hasGL2) {
|
||||||
gl2Extensions = getGLES2ExtensionString(fb->m_eglDisplay, fb->m_subWin);
|
gl2Extensions = getGLES2ExtensionString(fb->m_eglDisplay);
|
||||||
if (!gl2Extensions) {
|
if (!gl2Extensions) {
|
||||||
// Could not create GLES2 context - drop GL2 capability
|
// Could not create GLES2 context - drop GL2 capability
|
||||||
fb->m_caps.hasGL2 = false;
|
fb->m_caps.hasGL2 = false;
|
||||||
@@ -189,8 +181,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create EGL context and Surface attached to the native window, for
|
// Create EGL context for framebuffer post rendering.
|
||||||
// framebuffer post rendering.
|
|
||||||
//
|
//
|
||||||
#if 0
|
#if 0
|
||||||
GLint configAttribs[] = {
|
GLint configAttribs[] = {
|
||||||
@@ -203,35 +194,25 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window,
|
|||||||
EGL_RED_SIZE, 1,
|
EGL_RED_SIZE, 1,
|
||||||
EGL_GREEN_SIZE, 1,
|
EGL_GREEN_SIZE, 1,
|
||||||
EGL_BLUE_SIZE, 1,
|
EGL_BLUE_SIZE, 1,
|
||||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
EGLConfig eglConfig;
|
|
||||||
int n;
|
int n;
|
||||||
if (!s_egl.eglChooseConfig(fb->m_eglDisplay, configAttribs,
|
if (!s_egl.eglChooseConfig(fb->m_eglDisplay, configAttribs,
|
||||||
&eglConfig, 1, &n)) {
|
&fb->m_eglConfig, 1, &n)) {
|
||||||
ERR("Failed on eglChooseConfig\n");
|
ERR("Failed on eglChooseConfig\n");
|
||||||
delete fb;
|
delete fb;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLNativeDisplayType dpy;
|
|
||||||
fb->m_eglSurface = s_egl.eglCreateWindowSurface(fb->m_eglDisplay, eglConfig,
|
|
||||||
fb->m_subWin,
|
|
||||||
NULL);
|
|
||||||
if (fb->m_eglSurface == EGL_NO_SURFACE) {
|
|
||||||
ERR("Failed to create surface\n");
|
|
||||||
delete fb;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint glContextAttribs[] = {
|
GLint glContextAttribs[] = {
|
||||||
EGL_CONTEXT_CLIENT_VERSION, 1,
|
EGL_CONTEXT_CLIENT_VERSION, 1,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
fb->m_eglContext = s_egl.eglCreateContext(fb->m_eglDisplay, eglConfig,
|
fb->m_eglContext = s_egl.eglCreateContext(fb->m_eglDisplay, fb->m_eglConfig,
|
||||||
EGL_NO_CONTEXT,
|
EGL_NO_CONTEXT,
|
||||||
glContextAttribs);
|
glContextAttribs);
|
||||||
if (fb->m_eglContext == EGL_NO_CONTEXT) {
|
if (fb->m_eglContext == EGL_NO_CONTEXT) {
|
||||||
@@ -240,6 +221,26 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// create a 1x1 pbuffer surface which will be used for binding
|
||||||
|
// the FB context.
|
||||||
|
// The FB output will go to a subwindow, if one exist.
|
||||||
|
//
|
||||||
|
EGLint pbufAttribs[] = {
|
||||||
|
EGL_WIDTH, 1,
|
||||||
|
EGL_HEIGHT, 1,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
fb->m_pbufSurface = s_egl.eglCreatePbufferSurface(fb->m_eglDisplay,
|
||||||
|
fb->m_eglConfig,
|
||||||
|
pbufAttribs);
|
||||||
|
if (fb->m_pbufSurface == EGL_NO_SURFACE) {
|
||||||
|
printf("Failed to create pbuf surface for FB 0x%x\n", s_egl.eglGetError());
|
||||||
|
delete fb;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Make the context current
|
// Make the context current
|
||||||
if (!fb->bind_locked()) {
|
if (!fb->bind_locked()) {
|
||||||
ERR("Failed to make current\n");
|
ERR("Failed to make current\n");
|
||||||
@@ -341,9 +342,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer::FrameBuffer(int p_x, int p_y, int p_width, int p_height) :
|
FrameBuffer::FrameBuffer(int p_width, int p_height) :
|
||||||
m_x(p_x),
|
|
||||||
m_y(p_y),
|
|
||||||
m_width(p_width),
|
m_width(p_width),
|
||||||
m_height(p_height),
|
m_height(p_height),
|
||||||
m_eglDisplay(EGL_NO_DISPLAY),
|
m_eglDisplay(EGL_NO_DISPLAY),
|
||||||
@@ -354,6 +353,8 @@ FrameBuffer::FrameBuffer(int p_x, int p_y, int p_width, int p_height) :
|
|||||||
m_prevDrawSurf(EGL_NO_SURFACE),
|
m_prevDrawSurf(EGL_NO_SURFACE),
|
||||||
m_subWin(NULL),
|
m_subWin(NULL),
|
||||||
m_subWinDisplay(NULL),
|
m_subWinDisplay(NULL),
|
||||||
|
m_lastPostedColorBuffer(0),
|
||||||
|
m_zRot(0.0f),
|
||||||
m_statsNumFrames(0),
|
m_statsNumFrames(0),
|
||||||
m_statsStartTime(0LL)
|
m_statsStartTime(0LL)
|
||||||
{
|
{
|
||||||
@@ -364,6 +365,74 @@ FrameBuffer::~FrameBuffer()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FrameBuffer::setupSubWindow(FBNativeWindowType p_window,
|
||||||
|
int p_x, int p_y,
|
||||||
|
int p_width, int p_height, float zRot)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (s_theFrameBuffer) {
|
||||||
|
s_theFrameBuffer->m_lock.lock();
|
||||||
|
FrameBuffer *fb = s_theFrameBuffer;
|
||||||
|
if (!fb->m_subWin) {
|
||||||
|
|
||||||
|
// create native subwindow for FB display output
|
||||||
|
fb->m_subWin = createSubWindow(p_window,
|
||||||
|
&fb->m_subWinDisplay,
|
||||||
|
p_x,p_y,p_width,p_height);
|
||||||
|
if (fb->m_subWin) {
|
||||||
|
fb->m_nativeWindow = p_window;
|
||||||
|
|
||||||
|
// create EGLSurface from the generated subwindow
|
||||||
|
fb->m_eglSurface = s_egl.eglCreateWindowSurface(fb->m_eglDisplay,
|
||||||
|
fb->m_eglConfig,
|
||||||
|
fb->m_subWin,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (fb->m_eglSurface == EGL_NO_SURFACE) {
|
||||||
|
ERR("Failed to create surface\n");
|
||||||
|
destroySubWindow(fb->m_subWinDisplay, fb->m_subWin);
|
||||||
|
fb->m_subWin = NULL;
|
||||||
|
}
|
||||||
|
else if (fb->bindSubwin_locked()) {
|
||||||
|
// Subwin creation was successfull,
|
||||||
|
// update viewport and z rotation and draw
|
||||||
|
// the last posted color buffer.
|
||||||
|
s_gl.glViewport(0, 0, p_width, p_height);
|
||||||
|
fb->m_zRot = zRot;
|
||||||
|
fb->post( fb->m_lastPostedColorBuffer, false );
|
||||||
|
fb->unbind_locked();
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s_theFrameBuffer->m_lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FrameBuffer::removeSubWindow()
|
||||||
|
{
|
||||||
|
bool removed = false;
|
||||||
|
if (s_theFrameBuffer) {
|
||||||
|
s_theFrameBuffer->m_lock.lock();
|
||||||
|
if (s_theFrameBuffer->m_subWin) {
|
||||||
|
s_egl.eglMakeCurrent(s_theFrameBuffer->m_eglDisplay, NULL, NULL, NULL);
|
||||||
|
s_egl.eglDestroySurface(s_theFrameBuffer->m_eglDisplay,
|
||||||
|
s_theFrameBuffer->m_eglSurface);
|
||||||
|
destroySubWindow(s_theFrameBuffer->m_subWinDisplay,
|
||||||
|
s_theFrameBuffer->m_subWin);
|
||||||
|
|
||||||
|
s_theFrameBuffer->m_eglSurface = EGL_NO_SURFACE;
|
||||||
|
s_theFrameBuffer->m_subWin = NULL;
|
||||||
|
removed = true;
|
||||||
|
}
|
||||||
|
s_theFrameBuffer->m_lock.unlock();
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
HandleType FrameBuffer::genHandle()
|
HandleType FrameBuffer::genHandle()
|
||||||
{
|
{
|
||||||
HandleType id;
|
HandleType id;
|
||||||
@@ -620,6 +689,24 @@ bool FrameBuffer::bind_locked()
|
|||||||
EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
|
EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
|
||||||
EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
|
EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
|
||||||
|
|
||||||
|
if (!s_egl.eglMakeCurrent(m_eglDisplay, m_pbufSurface,
|
||||||
|
m_pbufSurface, m_eglContext)) {
|
||||||
|
ERR("eglMakeCurrent failed\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_prevContext = prevContext;
|
||||||
|
m_prevReadSurf = prevReadSurf;
|
||||||
|
m_prevDrawSurf = prevDrawSurf;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FrameBuffer::bindSubwin_locked()
|
||||||
|
{
|
||||||
|
EGLContext prevContext = s_egl.eglGetCurrentContext();
|
||||||
|
EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
|
||||||
|
EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
|
||||||
|
|
||||||
if (!s_egl.eglMakeCurrent(m_eglDisplay, m_eglSurface,
|
if (!s_egl.eglMakeCurrent(m_eglDisplay, m_eglSurface,
|
||||||
m_eglSurface, m_eglContext)) {
|
m_eglSurface, m_eglContext)) {
|
||||||
ERR("eglMakeCurrent failed\n");
|
ERR("eglMakeCurrent failed\n");
|
||||||
@@ -645,17 +732,41 @@ bool FrameBuffer::unbind_locked()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FrameBuffer::post(HandleType p_colorbuffer)
|
bool FrameBuffer::post(HandleType p_colorbuffer, bool needLock)
|
||||||
{
|
{
|
||||||
android::Mutex::Autolock mutex(m_lock);
|
if (needLock) m_lock.lock();
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
|
ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
|
||||||
if (c != m_colorbuffers.end()) {
|
if (c != m_colorbuffers.end()) {
|
||||||
if (!bind_locked()) {
|
|
||||||
|
m_lastPostedColorBuffer = p_colorbuffer;
|
||||||
|
if (!m_subWin) {
|
||||||
|
// no subwindow created for the FB output
|
||||||
|
// cannot post the colorbuffer
|
||||||
|
if (needLock) m_lock.unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// bind the subwindow eglSurface
|
||||||
|
if (!bindSubwin_locked()) {
|
||||||
|
ERR("FrameBuffer::post eglMakeCurrent failed\n");
|
||||||
|
if (needLock) m_lock.unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// render the color buffer to the window
|
||||||
|
//
|
||||||
|
s_gl.glPushMatrix();
|
||||||
|
s_gl.glRotatef(m_zRot, 0.0f, 0.0f, 1.0f);
|
||||||
|
if (m_zRot != 0.0f) {
|
||||||
|
s_gl.glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
ret = (*c).second->post();
|
ret = (*c).second->post();
|
||||||
|
s_gl.glPopMatrix();
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -674,8 +785,19 @@ bool FrameBuffer::post(HandleType p_colorbuffer)
|
|||||||
|
|
||||||
s_egl.eglSwapBuffers(m_eglDisplay, m_eglSurface);
|
s_egl.eglSwapBuffers(m_eglDisplay, m_eglSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// restore previous binding
|
||||||
unbind_locked();
|
unbind_locked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needLock) m_lock.unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FrameBuffer::repost()
|
||||||
|
{
|
||||||
|
if (m_lastPostedColorBuffer) {
|
||||||
|
return post( m_lastPostedColorBuffer );
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,9 +43,11 @@ struct FrameBufferCaps
|
|||||||
class FrameBuffer
|
class FrameBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool initialize(FBNativeWindowType p_window,
|
static bool initialize(int width, int height);
|
||||||
int x, int y,
|
static bool setupSubWindow(FBNativeWindowType p_window,
|
||||||
int width, int height);
|
int x, int y,
|
||||||
|
int width, int height, float zRot);
|
||||||
|
static bool removeSubWindow();
|
||||||
static void finalize();
|
static void finalize();
|
||||||
static FrameBuffer *getFB() { return s_theFrameBuffer; }
|
static FrameBuffer *getFB() { return s_theFrameBuffer; }
|
||||||
|
|
||||||
@@ -70,7 +72,8 @@ public:
|
|||||||
int x, int y, int width, int height,
|
int x, int y, int width, int height,
|
||||||
GLenum format, GLenum type, void *pixels);
|
GLenum format, GLenum type, void *pixels);
|
||||||
|
|
||||||
bool post(HandleType p_colorbuffer);
|
bool post(HandleType p_colorbuffer, bool needLock = true);
|
||||||
|
bool repost();
|
||||||
|
|
||||||
EGLDisplay getDisplay() const { return m_eglDisplay; }
|
EGLDisplay getDisplay() const { return m_eglDisplay; }
|
||||||
EGLContext getContext() const { return m_eglContext; }
|
EGLContext getContext() const { return m_eglContext; }
|
||||||
@@ -78,10 +81,16 @@ public:
|
|||||||
bool bind_locked();
|
bool bind_locked();
|
||||||
bool unbind_locked();
|
bool unbind_locked();
|
||||||
|
|
||||||
|
void setDisplayRotation(float zRot) {
|
||||||
|
m_zRot = zRot;
|
||||||
|
repost();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FrameBuffer(int p_x, int p_y, int p_width, int p_height);
|
FrameBuffer(int p_width, int p_height);
|
||||||
~FrameBuffer();
|
~FrameBuffer();
|
||||||
HandleType genHandle();
|
HandleType genHandle();
|
||||||
|
bool bindSubwin_locked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static FrameBuffer *s_theFrameBuffer;
|
static FrameBuffer *s_theFrameBuffer;
|
||||||
@@ -100,12 +109,16 @@ private:
|
|||||||
|
|
||||||
EGLSurface m_eglSurface;
|
EGLSurface m_eglSurface;
|
||||||
EGLContext m_eglContext;
|
EGLContext m_eglContext;
|
||||||
|
EGLSurface m_pbufSurface;
|
||||||
|
|
||||||
EGLContext m_prevContext;
|
EGLContext m_prevContext;
|
||||||
EGLSurface m_prevReadSurf;
|
EGLSurface m_prevReadSurf;
|
||||||
EGLSurface m_prevDrawSurf;
|
EGLSurface m_prevDrawSurf;
|
||||||
EGLNativeWindowType m_subWin;
|
EGLNativeWindowType m_subWin;
|
||||||
EGLNativeDisplayType m_subWinDisplay;
|
EGLNativeDisplayType m_subWinDisplay;
|
||||||
|
EGLConfig m_eglConfig;
|
||||||
|
HandleType m_lastPostedColorBuffer;
|
||||||
|
float m_zRot;
|
||||||
|
|
||||||
int m_statsNumFrames;
|
int m_statsNumFrames;
|
||||||
long long m_statsStartTime;
|
long long m_statsStartTime;
|
||||||
|
|||||||
@@ -27,13 +27,19 @@ static int s_renderPort = 0;
|
|||||||
static IOStream *createRenderThread(int p_stream_buffer_size,
|
static IOStream *createRenderThread(int p_stream_buffer_size,
|
||||||
unsigned int clientFlags);
|
unsigned int clientFlags);
|
||||||
|
|
||||||
#ifdef __APPLE__
|
//
|
||||||
|
// For now run the renderer as a thread inside the calling
|
||||||
|
// process instead as running it in a separate process for all
|
||||||
|
// platforms.
|
||||||
|
// at the future we want it to run as a seperate process except for
|
||||||
|
// Mac OS X since it is imposibble on this platform to make one process
|
||||||
|
// render to a window created by another process.
|
||||||
|
//
|
||||||
|
//#ifdef __APPLE__
|
||||||
#define RENDER_API_USE_THREAD
|
#define RENDER_API_USE_THREAD
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
bool initOpenGLRenderer(FBNativeWindowType window,
|
bool initOpenGLRenderer(int width, int height, int portNum)
|
||||||
int x, int y, int width, int height,
|
|
||||||
int portNum)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -50,7 +56,7 @@ bool initOpenGLRenderer(FBNativeWindowType window,
|
|||||||
// initialize the renderer and listen to connections
|
// initialize the renderer and listen to connections
|
||||||
// on a thread in the current process.
|
// on a thread in the current process.
|
||||||
//
|
//
|
||||||
bool inited = FrameBuffer::initialize(window, x, y, width, height);
|
bool inited = FrameBuffer::initialize(width, height);
|
||||||
if (!inited) {
|
if (!inited) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -169,6 +175,71 @@ bool stopOpenGLRenderer()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool createOpenGLSubwindow(FBNativeWindowType window,
|
||||||
|
int x, int y, int width, int height, float zRot)
|
||||||
|
{
|
||||||
|
if (s_renderThread) {
|
||||||
|
return FrameBuffer::setupSubWindow(window,x,y,width,height, zRot);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//
|
||||||
|
// XXX: should be implemented by sending the renderer process
|
||||||
|
// a request
|
||||||
|
ERR("%s not implemented for separate renderer process !!!\n",
|
||||||
|
__FUNCTION__);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool destroyOpenGLSubwindow()
|
||||||
|
{
|
||||||
|
if (s_renderThread) {
|
||||||
|
return FrameBuffer::removeSubWindow();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//
|
||||||
|
// XXX: should be implemented by sending the renderer process
|
||||||
|
// a request
|
||||||
|
ERR("%s not implemented for separate renderer process !!!\n",
|
||||||
|
__FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOpenGLDisplayRotation(float zRot)
|
||||||
|
{
|
||||||
|
if (s_renderThread) {
|
||||||
|
FrameBuffer *fb = FrameBuffer::getFB();
|
||||||
|
if (fb) {
|
||||||
|
fb->setDisplayRotation(zRot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//
|
||||||
|
// XXX: should be implemented by sending the renderer process
|
||||||
|
// a request
|
||||||
|
ERR("%s not implemented for separate renderer process !!!\n",
|
||||||
|
__FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void repaintOpenGLDisplay()
|
||||||
|
{
|
||||||
|
if (s_renderThread) {
|
||||||
|
FrameBuffer *fb = FrameBuffer::getFB();
|
||||||
|
if (fb) {
|
||||||
|
fb->repost();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//
|
||||||
|
// XXX: should be implemented by sending the renderer process
|
||||||
|
// a request
|
||||||
|
ERR("%s not implemented for separate renderer process !!!\n",
|
||||||
|
__FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IOStream *createRenderThread(int p_stream_buffer_size, unsigned int clientFlags)
|
IOStream *createRenderThread(int p_stream_buffer_size, unsigned int clientFlags)
|
||||||
{
|
{
|
||||||
TcpStream *stream = new TcpStream(p_stream_buffer_size);
|
TcpStream *stream = new TcpStream(p_stream_buffer_size);
|
||||||
|
|||||||
@@ -120,13 +120,19 @@ int main(int argc, char *argv[])
|
|||||||
//
|
//
|
||||||
// initialize Framebuffer
|
// initialize Framebuffer
|
||||||
//
|
//
|
||||||
bool inited = FrameBuffer::initialize(windowId,
|
bool inited = FrameBuffer::initialize(winWidth, winHeight);
|
||||||
winX, winY, winWidth, winHeight);
|
|
||||||
if (!inited) {
|
if (!inited) {
|
||||||
fprintf(stderr,"Failed to initialize Framebuffer\n");
|
fprintf(stderr,"Failed to initialize Framebuffer\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inited = FrameBuffer::setupSubWindow(windowId,
|
||||||
|
winX, winY, winWidth, winHeight, 0.0);
|
||||||
|
if (!inited) {
|
||||||
|
fprintf(stderr,"Failed to create subwindow Framebuffer\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create and run a render server listening to the given port number
|
// Create and run a render server listening to the given port number
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -80,13 +80,23 @@ int main(int argc, char *argv[])
|
|||||||
//
|
//
|
||||||
// initialize OpenGL renderer to render in our window
|
// initialize OpenGL renderer to render in our window
|
||||||
//
|
//
|
||||||
bool inited = initOpenGLRenderer(windowId, 0, 0,
|
bool inited = initOpenGLRenderer(winWidth, winHeight, portNum);
|
||||||
winWidth, winHeight, portNum);
|
|
||||||
if (!inited) {
|
if (!inited) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
printf("renderer process started\n");
|
printf("renderer process started\n");
|
||||||
|
|
||||||
|
float zRot = 0.0f;
|
||||||
|
inited = createOpenGLSubwindow(windowId, 0, 0,
|
||||||
|
winWidth, winHeight, zRot);
|
||||||
|
if (!inited) {
|
||||||
|
printf("failed to create OpenGL subwindow\n");
|
||||||
|
stopOpenGLRenderer();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int subwinWidth = winWidth;
|
||||||
|
int subwinHeight = winHeight;
|
||||||
|
|
||||||
injector = new EventInjector(consolePort);
|
injector = new EventInjector(consolePort);
|
||||||
|
|
||||||
// Just wait until the window is closed
|
// Just wait until the window is closed
|
||||||
@@ -103,7 +113,7 @@ int main(int argc, char *argv[])
|
|||||||
injector->sendMouseDown(ev.button.x, ev.button.y);
|
injector->sendMouseDown(ev.button.x, ev.button.y);
|
||||||
mouseDown = 1;
|
mouseDown = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONUP:
|
case SDL_MOUSEBUTTONUP:
|
||||||
if (mouseDown) {
|
if (mouseDown) {
|
||||||
injector->sendMouseUp(ev.button.x,ev.button.y);
|
injector->sendMouseUp(ev.button.x,ev.button.y);
|
||||||
@@ -123,7 +133,41 @@ int main(int argc, char *argv[])
|
|||||||
goto EXIT;
|
goto EXIT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
injector->sendKeyDown(convert_keysym(ev.key.keysym.sym));
|
injector->sendKeyDown(convert_keysym(ev.key.keysym.sym));
|
||||||
|
|
||||||
|
if (ev.key.keysym.sym == SDLK_KP_MINUS) {
|
||||||
|
subwinWidth /= 2;
|
||||||
|
subwinHeight /= 2;
|
||||||
|
|
||||||
|
bool stat = destroyOpenGLSubwindow();
|
||||||
|
printf("destroy subwin returned %d\n", stat);
|
||||||
|
stat = createOpenGLSubwindow(windowId,
|
||||||
|
(winWidth - subwinWidth) / 2,
|
||||||
|
(winHeight - subwinHeight) / 2,
|
||||||
|
subwinWidth, subwinHeight,
|
||||||
|
zRot);
|
||||||
|
printf("create subwin returned %d\n", stat);
|
||||||
|
}
|
||||||
|
else if (ev.key.keysym.sym == SDLK_KP_PLUS) {
|
||||||
|
subwinWidth *= 2;
|
||||||
|
subwinHeight *= 2;
|
||||||
|
|
||||||
|
bool stat = destroyOpenGLSubwindow();
|
||||||
|
printf("destroy subwin returned %d\n", stat);
|
||||||
|
stat = createOpenGLSubwindow(windowId,
|
||||||
|
(winWidth - subwinWidth) / 2,
|
||||||
|
(winHeight - subwinHeight) / 2,
|
||||||
|
subwinWidth, subwinHeight,
|
||||||
|
zRot);
|
||||||
|
printf("create subwin returned %d\n", stat);
|
||||||
|
}
|
||||||
|
else if (ev.key.keysym.sym == SDLK_KP_MULTIPLY) {
|
||||||
|
zRot += 10.0f;
|
||||||
|
setOpenGLDisplayRotation(zRot);
|
||||||
|
}
|
||||||
|
else if (ev.key.keysym.sym == SDLK_KP_ENTER) {
|
||||||
|
repaintOpenGLDisplay();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
injector->sendKeyUp(convert_keysym(ev.key.keysym.sym));
|
injector->sendKeyUp(convert_keysym(ev.key.keysym.sym));
|
||||||
|
|||||||
Reference in New Issue
Block a user