bool ColorBuffer::bindToRenderbuffer() { if (m_eglImage) { RenderThreadInfo *tInfo = getRenderThreadInfo(); if (tInfo->currContext.Ptr()) { #ifdef WITH_GLES2 if (tInfo->currContext->isGL2()) { s_gl2.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES, m_eglImage); } else { s_gl.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES, m_eglImage); } #else s_gl.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES, m_eglImage); #endif return true; } } return false; }
bool ColorBuffer::bindToTexture() { if (m_eglImage) { RenderThreadInfo *tInfo = getRenderThreadInfo(); if (tInfo->currContext.Ptr()) { #ifdef WITH_GLES2 if (tInfo->currContext->isGL2()) { s_gl2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); } else { s_gl.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); } #else s_gl.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); #endif return true; } } return false; }
bool FrameBuffer::bindContext(HandleType p_context, HandleType p_drawSurface, HandleType p_readSurface) { android::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)) { // MakeCurrent failed return false; } // // Bind the surface(s) to the context // RenderThreadInfo *tinfo = getRenderThreadInfo(); if (draw.Ptr() == NULL && read.Ptr() == NULL) { // if this is an unbind operation - make sure the current bound // surfaces get unbound from the context. draw = tinfo->currDrawSurf; read = tinfo->currReadSurf; } if (draw.Ptr() != NULL && read.Ptr() != NULL) { if (p_readSurface != p_drawSurface) { draw->bind( ctx, SURFACE_BIND_DRAW ); read->bind( ctx, SURFACE_BIND_READ ); } else { draw->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; }
bool ColorBuffer::blitFromCurrentReadBuffer() { RenderThreadInfo *tInfo = getRenderThreadInfo(); if (!tInfo->currContext.Ptr()) { // no Current context return false; } // // Create a temporary texture inside the current context // from the blit_texture EGLImage and copy the pixels // from the current read buffer to that texture // GLuint tmpTex; GLint currTexBind; if (tInfo->currContext->isGL2()) { s_gl2.glGetIntegerv(GL_TEXTURE_BINDING_2D, &currTexBind); s_gl2.glGenTextures(1,&tmpTex); s_gl2.glBindTexture(GL_TEXTURE_2D, tmpTex); s_gl2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_blitEGLImage); s_gl2.glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, 0, 0, m_width, m_height, 0); } else { s_gl.glGetIntegerv(GL_TEXTURE_BINDING_2D, &currTexBind); s_gl.glGenTextures(1,&tmpTex); s_gl.glBindTexture(GL_TEXTURE_2D, tmpTex); s_gl.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_blitEGLImage); s_gl.glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, 0, 0, m_width, m_height, 0); } // // Now bind the frame buffer context and blit from // m_blitTex into m_tex // FrameBuffer *fb = FrameBuffer::getFB(); if (fb->bind_locked()) { // // bind FBO object which has this colorbuffer as render target // if (bind_fbo()) { // // save current viewport and match it to the current // colorbuffer size // GLint vport[4]; s_gl.glGetIntegerv(GL_VIEWPORT, vport); s_gl.glViewport(0, 0, m_width, m_height); // render m_blitTex s_gl.glBindTexture(GL_TEXTURE_2D, m_blitTex); s_gl.glEnable(GL_TEXTURE_2D); s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); drawTexQuad(); // this will render the texture flipped // unbind the fbo s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); // restrore previous viewport s_gl.glViewport(vport[0], vport[1], vport[2], vport[3]); } // unbind from the FrameBuffer context fb->unbind_locked(); } // // delete the temporary texture and restore the texture binding // inside the current context // if (tInfo->currContext->isGL2()) { s_gl2.glDeleteTextures(1, &tmpTex); s_gl2.glBindTexture(GL_TEXTURE_2D, currTexBind); } else { s_gl.glDeleteTextures(1, &tmpTex); s_gl.glBindTexture(GL_TEXTURE_2D, currTexBind); } return true; }
int RenderThread::Main() { RenderThreadInfo * tInfo = getRenderThreadInfo(); // // initialize decoders // tInfo->m_glDec.initGL( gl_dispatch_get_proc_func, NULL ); tInfo->m_gl2Dec.initGL( gl2_dispatch_get_proc_func, NULL ); initRenderControlContext( &m_rcDec ); ReadBuffer readBuf(m_stream, STREAM_BUFFER_SIZE); int stats_totalBytes = 0; long long stats_t0 = GetCurrentTimeMS(); // // open dump file if RENDER_DUMP_DIR is defined // const char *dump_dir = getenv("RENDERER_DUMP_DIR"); FILE *dumpFP = NULL; if (dump_dir) { size_t bsize = strlen(dump_dir) + 32; char *fname = new char[bsize]; snprintf(fname,bsize,"%s/stream_%p", dump_dir, this); dumpFP = fopen(fname, "wb"); if (!dumpFP) { fprintf(stderr,"Warning: stream dump failed to open file %s\n",fname); } delete [] fname; } while (1) { int stat = readBuf.getData(); if (stat <= 0) { break; } // // log received bandwidth statistics // stats_totalBytes += readBuf.validData(); long long dt = GetCurrentTimeMS() - stats_t0; if (dt > 1000) { float dts = (float)dt / 1000.0f; //printf("Used Bandwidth %5.3f MB/s\n", ((float)stats_totalBytes / dts) / (1024.0f*1024.0f)); stats_totalBytes = 0; stats_t0 = GetCurrentTimeMS(); } // // dump stream to file if needed // if (dumpFP) { int skip = readBuf.validData() - stat; fwrite(readBuf.buf()+skip, 1, readBuf.validData()-skip, dumpFP); fflush(dumpFP); } bool progress; do { progress = false; // // try to process some of the command buffer using the GLESv1 decoder // size_t last = tInfo->m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream); if (last > 0) { progress = true; readBuf.consume(last); } // // try to process some of the command buffer using the GLESv2 decoder // last = tInfo->m_gl2Dec.decode(readBuf.buf(), readBuf.validData(), m_stream); if (last > 0) { progress = true; readBuf.consume(last); } // // try to process some of the command buffer using the // renderControl decoder // last = m_rcDec.decode(readBuf.buf(), readBuf.validData(), m_stream); if (last > 0) { readBuf.consume(last); progress = true; } } while( progress ); } if (dumpFP) { fclose(dumpFP); } // // release the thread from any EGL context // if bound to context. // EGLDisplay eglDpy = s_egl.eglGetCurrentDisplay(); if (eglDpy != EGL_NO_DISPLAY) { s_egl.eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } // // flag that this thread has finished execution m_finished = true; return 0; }