diff options
Diffstat (limited to 'services/surfaceflinger/RenderEngine')
6 files changed, 79 insertions, 35 deletions
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp index 1a9f59b..aded96f 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp @@ -210,28 +210,46 @@ void GLES11RenderEngine::disableBlending() { } void GLES11RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, - uint32_t* texName, uint32_t* fbName, uint32_t* status) { + uint32_t* texName, uint32_t* fbName, uint32_t* status, + bool useReadPixels, int reqWidth, int reqHeight) { GLuint tname, name; - // turn our EGLImage into a texture - glGenTextures(1, &tname); - glBindTexture(GL_TEXTURE_2D, tname); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image); - - // create a Framebuffer Object to render into - glGenFramebuffersOES(1, &name); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); - glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, - GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); + if (!useReadPixels) { + // turn our EGLImage into a texture + glGenTextures(1, &tname); + glBindTexture(GL_TEXTURE_2D, tname); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image); + + // create a Framebuffer Object to render into + glGenFramebuffersOES(1, &name); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); + glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, + GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); + } else { + // since we're going to use glReadPixels() anyways, + // use an intermediate renderbuffer instead + glGenRenderbuffersOES(1, &tname); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); + glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, reqWidth, reqHeight); + // create a FBO to render into + glGenFramebuffersOES(1, &name); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, + GL_RENDERBUFFER_OES, tname); + } *status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); *texName = tname; *fbName = name; } -void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) { +void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName, + bool useReadPixels) { glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); glDeleteFramebuffersOES(1, &fbName); - glDeleteTextures(1, &texName); + if (!useReadPixels) + glDeleteTextures(1, &texName); + else + glDeleteRenderbuffersOES(1, &texName); } void GLES11RenderEngine::setupFillWithColor(float r, float g, float b, float a) { diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h index 08de646..77824ce 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h @@ -40,8 +40,9 @@ class GLES11RenderEngine : public RenderEngine { GLint mMaxTextureSize; virtual void bindImageAsFramebuffer(EGLImageKHR image, - uint32_t* texName, uint32_t* fbName, uint32_t* status); - virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName); + uint32_t* texName, uint32_t* fbName, uint32_t* status, bool useReadPixels, + int reqWidth, int reqHeight); + virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName, bool useReadPixels); public: GLES11RenderEngine(); diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 1fabaf5..a35aa78 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -185,27 +185,44 @@ void GLES20RenderEngine::disableBlending() { void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, - uint32_t* texName, uint32_t* fbName, uint32_t* status) { + uint32_t* texName, uint32_t* fbName, uint32_t* status, + bool useReadPixels, int reqWidth, int reqHeight) { GLuint tname, name; - // turn our EGLImage into a texture - glGenTextures(1, &tname); - glBindTexture(GL_TEXTURE_2D, tname); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image); - - // create a Framebuffer Object to render into - glGenFramebuffers(1, &name); - glBindFramebuffer(GL_FRAMEBUFFER, name); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0); + if (!useReadPixels) { + // turn our EGLImage into a texture + glGenTextures(1, &tname); + glBindTexture(GL_TEXTURE_2D, tname); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image); + + // create a Framebuffer Object to render into + glGenFramebuffers(1, &name); + glBindFramebuffer(GL_FRAMEBUFFER, name); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0); + } else { + // since we're going to use glReadPixels() anyways, + // use an intermediate renderbuffer instead + glGenRenderbuffers(1, &tname); + glBindRenderbuffer(GL_RENDERBUFFER, tname); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, reqWidth, reqHeight); + // create a FBO to render into + glGenFramebuffers(1, &name); + glBindFramebuffer(GL_FRAMEBUFFER, name); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, tname); + } *status = glCheckFramebufferStatus(GL_FRAMEBUFFER); *texName = tname; *fbName = name; } -void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) { +void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName, + bool useReadPixels) { glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &fbName); - glDeleteTextures(1, &texName); + if (!useReadPixels) + glDeleteTextures(1, &texName); + else + glDeleteRenderbuffers(1, &texName); } void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) { diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h index 819356a..6074a3d 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -55,8 +55,9 @@ class GLES20RenderEngine : public RenderEngine { Vector<Group> mGroupStack; virtual void bindImageAsFramebuffer(EGLImageKHR image, - uint32_t* texName, uint32_t* fbName, uint32_t* status); - virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName); + uint32_t* texName, uint32_t* fbName, uint32_t* status, + bool useReadPixels, int reqWidth, int reqHeight); + virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName, bool useReadPixels); public: GLES20RenderEngine(); diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp index 7cd42e4..faae6fc 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp @@ -262,9 +262,11 @@ void RenderEngine::dump(String8& result) { // --------------------------------------------------------------------------- RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer( - RenderEngine& engine, EGLImageKHR image) : mEngine(engine) + RenderEngine& engine, EGLImageKHR image, bool useReadPixels, + int reqWidth, int reqHeight) : mEngine(engine), mUseReadPixels(useReadPixels) { - mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus); + mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus, + useReadPixels, reqWidth, reqHeight); ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d", mStatus); @@ -272,7 +274,7 @@ RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer( RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() { // back to main framebuffer - mEngine.unbindFramebuffer(mTexName, mFbName); + mEngine.unbindFramebuffer(mTexName, mFbName, mUseReadPixels); } status_t RenderEngine::BindImageAsFramebuffer::getStatus() const { diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index 31a961e..c9a043a 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -51,8 +51,11 @@ class RenderEngine { EGLContext mEGLContext; void setEGLHandles(EGLConfig config, EGLContext ctxt); - virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, uint32_t* status) = 0; - virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0; + virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, + uint32_t* fbName, uint32_t* status, bool useReadPixels, int reqWidth, + int reqHeight) = 0; + virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName, + bool useReadPixels) = 0; protected: RenderEngine(); @@ -83,8 +86,10 @@ public: RenderEngine& mEngine; uint32_t mTexName, mFbName; uint32_t mStatus; + bool mUseReadPixels; public: - BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image); + BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image, + bool useReadPixels, int reqWidth, int reqHeight); ~BindImageAsFramebuffer(); int getStatus() const; }; |