aboutsummaryrefslogtreecommitdiffstats
path: root/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp')
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp897
1 files changed, 0 insertions, 897 deletions
diff --git a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
deleted file mode 100644
index e7a7960..0000000
--- a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-#include "FrameBuffer.h"
-#include "NativeSubWindow.h"
-#include "FBConfig.h"
-#include "EGLDispatch.h"
-#include "GLDispatch.h"
-#include "GL2Dispatch.h"
-#include "ThreadInfo.h"
-#include "TimeUtils.h"
-#include <stdio.h>
-
-FrameBuffer *FrameBuffer::s_theFrameBuffer = NULL;
-HandleType FrameBuffer::s_nextHandle = 0;
-
-#ifdef WITH_GLES2
-static char* getGLES2ExtensionString(EGLDisplay p_dpy)
-{
- EGLConfig config;
- EGLSurface surface;
-
- GLint configAttribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_NONE
- };
-
- int n;
- if (!s_egl.eglChooseConfig(p_dpy, configAttribs,
- &config, 1, &n)) {
- return NULL;
- }
-
- EGLint pbufAttribs[] = {
- EGL_WIDTH, 1,
- EGL_HEIGHT, 1,
- EGL_NONE
- };
-
- surface = s_egl.eglCreatePbufferSurface(p_dpy, config, pbufAttribs);
- if (surface == EGL_NO_SURFACE) {
- return NULL;
- }
-
- GLint gl2ContextAttribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
-
- EGLContext ctx = s_egl.eglCreateContext(p_dpy, config,
- EGL_NO_CONTEXT,
- gl2ContextAttribs);
- if (ctx == EGL_NO_CONTEXT) {
- s_egl.eglDestroySurface(p_dpy, surface);
- return NULL;
- }
-
- if (!s_egl.eglMakeCurrent(p_dpy, surface, surface, ctx)) {
- s_egl.eglDestroySurface(p_dpy, surface);
- s_egl.eglDestroyContext(p_dpy, ctx);
- return NULL;
- }
-
- // the string pointer may become invalid when the context is destroyed
- const char* s = (const char*)s_gl2.glGetString(GL_EXTENSIONS);
- char* extString = strdup(s ? s : "");
-
- s_egl.eglMakeCurrent(p_dpy, NULL, NULL, NULL);
- s_egl.eglDestroyContext(p_dpy, ctx);
- s_egl.eglDestroySurface(p_dpy, surface);
-
- return extString;
-}
-#endif
-
-void FrameBuffer::finalize(){
- if(s_theFrameBuffer){
- s_theFrameBuffer->removeSubWindow();
- s_theFrameBuffer->m_colorbuffers.clear();
- s_theFrameBuffer->m_windows.clear();
- s_theFrameBuffer->m_contexts.clear();
- s_egl.eglMakeCurrent(s_theFrameBuffer->m_eglDisplay, NULL, NULL, NULL);
- s_egl.eglDestroyContext(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglContext);
- s_egl.eglDestroyContext(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_pbufContext);
- s_egl.eglDestroySurface(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_pbufSurface);
- s_theFrameBuffer = NULL;
- }
-}
-
-bool FrameBuffer::initialize(int width, int height)
-{
- if (s_theFrameBuffer != NULL) {
- return true;
- }
-
- //
- // allocate space for the FrameBuffer object
- //
- FrameBuffer *fb = new FrameBuffer(width, height);
- if (!fb) {
- ERR("Failed to create fb\n");
- return false;
- }
-
-#ifdef WITH_GLES2
- //
- // Try to load GLES2 Plugin, not mandatory
- //
- if (getenv("ANDROID_NO_GLES2")) {
- fb->m_caps.hasGL2 = false;
- }
- else {
- fb->m_caps.hasGL2 = s_gl2_enabled;
- }
-#else
- fb->m_caps.hasGL2 = false;
-#endif
-
- //
- // Initialize backend EGL display
- //
- fb->m_eglDisplay = s_egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (fb->m_eglDisplay == EGL_NO_DISPLAY) {
- ERR("Failed to Initialize backend EGL display\n");
- delete fb;
- return false;
- }
-
- if (!s_egl.eglInitialize(fb->m_eglDisplay, &fb->m_caps.eglMajor, &fb->m_caps.eglMinor)) {
- ERR("Failed to eglInitialize\n");
- delete fb;
- return false;
- }
-
- DBG("egl: %d %d\n", fb->m_caps.eglMajor, fb->m_caps.eglMinor);
- s_egl.eglBindAPI(EGL_OPENGL_ES_API);
-
- //
- // if GLES2 plugin has loaded - try to make GLES2 context and
- // get GLES2 extension string
- //
- char* gl2Extensions = NULL;
-#ifdef WITH_GLES2
- if (fb->m_caps.hasGL2) {
- gl2Extensions = getGLES2ExtensionString(fb->m_eglDisplay);
- if (!gl2Extensions) {
- // Could not create GLES2 context - drop GL2 capability
- fb->m_caps.hasGL2 = false;
- }
- }
-#endif
-
- //
- // Create EGL context for framebuffer post rendering.
- //
-#if 0
- GLint configAttribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
- EGL_NONE
- };
-#else
- GLint configAttribs[] = {
- EGL_RED_SIZE, 1,
- EGL_GREEN_SIZE, 1,
- EGL_BLUE_SIZE, 1,
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
- EGL_NONE
- };
-#endif
-
- int n;
- if (!s_egl.eglChooseConfig(fb->m_eglDisplay, configAttribs,
- &fb->m_eglConfig, 1, &n)) {
- ERR("Failed on eglChooseConfig\n");
- free(gl2Extensions);
- delete fb;
- return false;
- }
-
- GLint glContextAttribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 1,
- EGL_NONE
- };
-
- fb->m_eglContext = s_egl.eglCreateContext(fb->m_eglDisplay, fb->m_eglConfig,
- EGL_NO_CONTEXT,
- glContextAttribs);
- if (fb->m_eglContext == EGL_NO_CONTEXT) {
- printf("Failed to create Context 0x%x\n", s_egl.eglGetError());
- free(gl2Extensions);
- delete fb;
- return false;
- }
-
- //
- // Create another context which shares with the eglContext to be used
- // when we bind the pbuffer. That prevent switching drawable binding
- // back and forth on framebuffer context.
- // The main purpose of it is to solve a "blanking" behaviour we see on
- // on Mac platform when switching binded drawable for a context however
- // it is more efficient on other platforms as well.
- //
- fb->m_pbufContext = s_egl.eglCreateContext(fb->m_eglDisplay, fb->m_eglConfig,
- fb->m_eglContext,
- glContextAttribs);
- if (fb->m_pbufContext == EGL_NO_CONTEXT) {
- printf("Failed to create Pbuffer Context 0x%x\n", s_egl.eglGetError());
- free(gl2Extensions);
- delete fb;
- 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());
- free(gl2Extensions);
- delete fb;
- return false;
- }
-
- // Make the context current
- if (!fb->bind_locked()) {
- ERR("Failed to make current\n");
- free(gl2Extensions);
- delete fb;
- return false;
- }
-
- //
- // Initilize framebuffer capabilities
- //
- const char *glExtensions = (const char *)s_gl.glGetString(GL_EXTENSIONS);
- bool has_gl_oes_image = false;
- if (glExtensions) {
- has_gl_oes_image = strstr(glExtensions, "GL_OES_EGL_image") != NULL;
- }
-
- if (fb->m_caps.hasGL2 && has_gl_oes_image) {
- has_gl_oes_image &= strstr(gl2Extensions, "GL_OES_EGL_image") != NULL;
- }
- free(gl2Extensions);
- gl2Extensions = NULL;
-
- const char *eglExtensions = s_egl.eglQueryString(fb->m_eglDisplay,
- EGL_EXTENSIONS);
-
- if (eglExtensions && has_gl_oes_image) {
- fb->m_caps.has_eglimage_texture_2d =
- strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image") != NULL;
- fb->m_caps.has_eglimage_renderbuffer =
- strstr(eglExtensions, "EGL_KHR_gl_renderbuffer_image") != NULL;
- }
- else {
- fb->m_caps.has_eglimage_texture_2d = false;
- fb->m_caps.has_eglimage_renderbuffer = false;
- }
-
- //
- // Fail initialization if not all of the following extensions
- // exist:
- // EGL_KHR_gl_texture_2d_image
- // GL_OES_EGL_IMAGE (by both GLES implementations [1 and 2])
- //
- if (!fb->m_caps.has_eglimage_texture_2d) {
- ERR("Failed: Missing egl_image related extension(s)\n");
- delete fb;
- return false;
- }
-
- //
- // Initialize set of configs
- //
- InitConfigStatus configStatus = FBConfig::initConfigList(fb);
- if (configStatus == INIT_CONFIG_FAILED) {
- ERR("Failed: Initialize set of configs\n");
- delete fb;
- return false;
- }
-
- //
- // Check that we have config for each GLES and GLES2
- //
- int nConfigs = FBConfig::getNumConfigs();
- int nGLConfigs = 0;
- int nGL2Configs = 0;
- for (int i=0; i<nConfigs; i++) {
- GLint rtype = FBConfig::get(i)->getRenderableType();
- if (0 != (rtype & EGL_OPENGL_ES_BIT)) {
- nGLConfigs++;
- }
- if (0 != (rtype & EGL_OPENGL_ES2_BIT)) {
- nGL2Configs++;
- }
- }
-
- //
- // Fail initialization if no GLES configs exist
- //
- if (nGLConfigs == 0) {
- delete fb;
- return false;
- }
-
- //
- // If no GLES2 configs exist - not GLES2 capability
- //
- if (nGL2Configs == 0) {
- fb->m_caps.hasGL2 = false;
- }
-
- //
- // Initialize some GL state in the pbuffer context
- //
- fb->initGLState();
-
- //
- // Cache the GL strings so we don't have to think about threading or
- // current-context when asked for them.
- //
- fb->m_glVendor = (const char*)s_gl.glGetString(GL_VENDOR);
- fb->m_glRenderer = (const char*)s_gl.glGetString(GL_RENDERER);
- fb->m_glVersion = (const char*)s_gl.glGetString(GL_VERSION);
-
- // release the FB context
- fb->unbind_locked();
-
- //
- // Keep the singleton framebuffer pointer
- //
- s_theFrameBuffer = fb;
- return true;
-}
-
-FrameBuffer::FrameBuffer(int p_width, int p_height) :
- m_width(p_width),
- m_height(p_height),
- m_eglDisplay(EGL_NO_DISPLAY),
- m_eglSurface(EGL_NO_SURFACE),
- m_eglContext(EGL_NO_CONTEXT),
- m_pbufContext(EGL_NO_CONTEXT),
- m_prevContext(EGL_NO_CONTEXT),
- m_prevReadSurf(EGL_NO_SURFACE),
- m_prevDrawSurf(EGL_NO_SURFACE),
- m_subWin((EGLNativeWindowType)0),
- m_subWinDisplay(NULL),
- m_lastPostedColorBuffer(0),
- m_zRot(0.0f),
- m_eglContextInitialized(false),
- m_statsNumFrames(0),
- m_statsStartTime(0LL),
- m_onPost(NULL),
- m_onPostContext(NULL),
- m_fbImage(NULL),
- m_glVendor(NULL),
- m_glRenderer(NULL),
- m_glVersion(NULL)
-{
- m_fpsStats = getenv("SHOW_FPS_STATS") != NULL;
-}
-
-FrameBuffer::~FrameBuffer()
-{
- free(m_fbImage);
-}
-
-void FrameBuffer::setPostCallback(OnPostFn onPost, void* onPostContext)
-{
- emugl::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)
-{
- 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 = (EGLNativeWindowType)0;
- }
- 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 = (EGLNativeWindowType)0;
- removed = true;
- }
- s_theFrameBuffer->m_lock.unlock();
- }
- return removed;
-}
-
-HandleType FrameBuffer::genHandle()
-{
- HandleType id;
- do {
- id = ++s_nextHandle;
- } while( id == 0 ||
- m_contexts.find(id) != m_contexts.end() ||
- m_windows.find(id) != m_windows.end() );
-
- return id;
-}
-
-HandleType FrameBuffer::createColorBuffer(int p_width, int p_height,
- GLenum p_internalFormat)
-{
- emugl::Mutex::AutoLock mutex(m_lock);
- HandleType ret = 0;
-
- ColorBufferPtr cb( ColorBuffer::create(p_width, p_height, p_internalFormat) );
- if (cb.Ptr() != NULL) {
- ret = genHandle();
- m_colorbuffers[ret].cb = cb;
- m_colorbuffers[ret].refcount = 1;
- }
- return ret;
-}
-
-HandleType FrameBuffer::createRenderContext(int p_config, HandleType p_share,
- bool p_isGL2)
-{
- emugl::Mutex::AutoLock mutex(m_lock);
- HandleType ret = 0;
-
- RenderContextPtr share(NULL);
- if (p_share != 0) {
- RenderContextMap::iterator s( m_contexts.find(p_share) );
- if (s == m_contexts.end()) {
- return 0;
- }
- share = (*s).second;
- }
-
- RenderContextPtr rctx( RenderContext::create(p_config, share, p_isGL2) );
- if (rctx.Ptr() != NULL) {
- ret = genHandle();
- m_contexts[ret] = rctx;
- }
- return ret;
-}
-
-HandleType FrameBuffer::createWindowSurface(int p_config, int p_width, int p_height)
-{
- emugl::Mutex::AutoLock mutex(m_lock);
-
- HandleType ret = 0;
- WindowSurfacePtr win( WindowSurface::create(p_config, p_width, p_height) );
- if (win.Ptr() != NULL) {
- ret = genHandle();
- m_windows[ret] = win;
- }
-
- return ret;
-}
-
-void FrameBuffer::DestroyRenderContext(HandleType p_context)
-{
- emugl::Mutex::AutoLock mutex(m_lock);
- m_contexts.erase(p_context);
-}
-
-void FrameBuffer::DestroyWindowSurface(HandleType p_surface)
-{
- emugl::Mutex::AutoLock mutex(m_lock);
- m_windows.erase(p_surface);
-}
-
-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
- ERR("FB: openColorBuffer cb handle %#x not found\n", p_colorbuffer);
- return -1;
- }
- (*c).second.refcount++;
- return 0;
-}
-
-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;
- }
- if (--(*c).second.refcount == 0) {
- m_colorbuffers.erase(c);
- }
-}
-
-bool FrameBuffer::flushWindowSurfaceColorBuffer(HandleType p_surface)
-{
- emugl::Mutex::AutoLock mutex(m_lock);
-
- 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;
- }
-
- return (*w).second->flushColorBuffer();
-}
-
-bool FrameBuffer::setWindowSurfaceColorBuffer(HandleType p_surface,
- HandleType p_colorbuffer)
-{
- emugl::Mutex::AutoLock mutex(m_lock);
-
- 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;
- }
-
- (*w).second->setColorBuffer( (*c).second.cb );
-
- return true;
-}
-
-bool FrameBuffer::updateColorBuffer(HandleType p_colorbuffer,
- int x, int y, int width, int height,
- GLenum format, GLenum type, void *pixels)
-{
- emugl::Mutex::AutoLock mutex(m_lock);
-
- ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
- if (c == m_colorbuffers.end()) {
- // bad colorbuffer handle
- return false;
- }
-
- (*c).second.cb->subUpdate(x, y, width, height, format, type, pixels);
-
- return true;
-}
-
-bool FrameBuffer::bindColorBufferToTexture(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 false;
- }
-
- return (*c).second.cb->bindToTexture();
-}
-
-bool FrameBuffer::bindColorBufferToRenderbuffer(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 false;
- }
-
- return (*c).second.cb->bindToRenderbuffer();
-}
-
-bool FrameBuffer::bindContext(HandleType p_context,
- HandleType p_drawSurface,
- HandleType p_readSurface)
-{
- emugl::Mutex::AutoLock mutex(m_lock);
-
- WindowSurfacePtr draw(NULL), read(NULL);
- RenderContextPtr ctx(NULL);
-
- //
- // if this is not an unbind operation - make sure all handles are good
- //
- if (p_context || p_drawSurface || p_readSurface) {
- RenderContextMap::iterator r( m_contexts.find(p_context) );
- if (r == m_contexts.end()) {
- // bad context handle
- return false;
- }
-
- ctx = (*r).second;
- WindowSurfaceMap::iterator w( m_windows.find(p_drawSurface) );
- if (w == m_windows.end()) {
- // bad surface handle
- return false;
- }
- draw = (*w).second;
-
- if (p_readSurface != p_drawSurface) {
- WindowSurfaceMap::iterator w( m_windows.find(p_readSurface) );
- if (w == m_windows.end()) {
- // bad surface handle
- return false;
- }
- read = (*w).second;
- }
- else {
- read = draw;
- }
- }
-
- if (!s_egl.eglMakeCurrent(m_eglDisplay,
- draw ? draw->getEGLSurface() : EGL_NO_SURFACE,
- read ? read->getEGLSurface() : EGL_NO_SURFACE,
- ctx ? ctx->getEGLContext() : EGL_NO_CONTEXT)) {
- ERR("eglMakeCurrent failed\n");
- return false;
- }
-
- //
- // Bind the surface(s) to the context
- //
- RenderThreadInfo *tinfo = RenderThreadInfo::get();
- WindowSurfacePtr bindDraw, bindRead;
- if (draw.Ptr() == NULL && read.Ptr() == NULL) {
- // Unbind the current read and draw surfaces from the context
- bindDraw = tinfo->currDrawSurf;
- bindRead = tinfo->currReadSurf;
- } else {
- bindDraw = draw;
- bindRead = read;
- }
-
- if (bindDraw.Ptr() != NULL && bindRead.Ptr() != NULL) {
- if (bindDraw.Ptr() != bindRead.Ptr()) {
- bindDraw->bind(ctx, SURFACE_BIND_DRAW);
- bindRead->bind(ctx, SURFACE_BIND_READ);
- }
- else {
- bindDraw->bind(ctx, SURFACE_BIND_READDRAW);
- }
- }
-
- //
- // update thread info with current bound context
- //
- tinfo->currContext = ctx;
- tinfo->currDrawSurf = draw;
- tinfo->currReadSurf = read;
- if (ctx) {
- if (ctx->isGL2()) tinfo->m_gl2Dec.setContextData(&ctx->decoderContextData());
- else tinfo->m_glDec.setContextData(&ctx->decoderContextData());
- }
- else {
- tinfo->m_glDec.setContextData(NULL);
- tinfo->m_gl2Dec.setContextData(NULL);
- }
- return true;
-}
-
-//
-// The framebuffer lock should be held when calling this function !
-//
-bool FrameBuffer::bind_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_pbufSurface,
- m_pbufSurface, m_pbufContext)) {
- 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,
- m_eglSurface, m_eglContext)) {
- ERR("eglMakeCurrent failed\n");
- return false;
- }
-
- //
- // initialize GL state in eglContext if not yet initilaized
- //
- if (!m_eglContextInitialized) {
- initGLState();
- m_eglContextInitialized = true;
- }
-
- m_prevContext = prevContext;
- m_prevReadSurf = prevReadSurf;
- m_prevDrawSurf = prevDrawSurf;
- return true;
-}
-
-bool FrameBuffer::unbind_locked()
-{
- if (!s_egl.eglMakeCurrent(m_eglDisplay, m_prevDrawSurf,
- m_prevReadSurf, m_prevContext)) {
- return false;
- }
-
- m_prevContext = EGL_NO_CONTEXT;
- m_prevReadSurf = EGL_NO_SURFACE;
- m_prevDrawSurf = EGL_NO_SURFACE;
- return true;
-}
-
-bool FrameBuffer::post(HandleType p_colorbuffer, bool needLock)
-{
- if (needLock) m_lock.lock();
- bool ret = false;
-
- ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) );
- if (c != m_colorbuffers.end()) {
-
- 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;
- }
-
- //
- // 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.cb->post();
- s_gl.glPopMatrix();
-
- if (ret) {
- //
- // output FPS statistics
- //
- if (m_fpsStats) {
- long long currTime = GetCurrentTimeMS();
- m_statsNumFrames++;
- if (currTime - m_statsStartTime >= 1000) {
- float dt = (float)(currTime - m_statsStartTime) / 1000.0f;
- printf("FPS: %5.3f\n", (float)m_statsNumFrames / dt);
- m_statsStartTime = currTime;
- m_statsNumFrames = 0;
- }
- }
-
- s_egl.eglSwapBuffers(m_eglDisplay, m_eglSurface);
- }
-
- // restore previous binding
- unbind_locked();
-
- //
- // Send framebuffer (without FPS overlay) to callback
- //
- if (m_onPost) {
- (*c).second.cb->readback(m_fbImage);
- m_onPost(m_onPostContext, m_width, m_height, -1,
- GL_RGBA, GL_UNSIGNED_BYTE, m_fbImage);
- }
-
- }
-
- if (needLock) m_lock.unlock();
- return ret;
-}
-
-bool FrameBuffer::repost()
-{
- if (m_lastPostedColorBuffer) {
- return post( m_lastPostedColorBuffer );
- }
- return false;
-}
-
-void FrameBuffer::initGLState()
-{
- s_gl.glMatrixMode(GL_PROJECTION);
- s_gl.glLoadIdentity();
- s_gl.glOrthof(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
- s_gl.glMatrixMode(GL_MODELVIEW);
- s_gl.glLoadIdentity();
-}