diff options
author | Mathias Agopian <mathias@google.com> | 2013-08-15 14:56:51 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2013-08-15 14:56:51 -0700 |
commit | 458197de008be8fe561286b09f4edddb2f5c540a (patch) | |
tree | 5ea0e30f1fc4152ecfcb80b2b25dedc2acbdb3fa /services/surfaceflinger/RenderEngine | |
parent | 6db4ff621898573b41abf570271a04a13bd36a69 (diff) | |
download | frameworks_native-458197de008be8fe561286b09f4edddb2f5c540a.zip frameworks_native-458197de008be8fe561286b09f4edddb2f5c540a.tar.gz frameworks_native-458197de008be8fe561286b09f4edddb2f5c540a.tar.bz2 |
Fix ES2 composition on some devices
- turns out fragment shaders don't have default precision by default
- GLES 1.x extensions that became core in GLES 2.0 don't always work
as extensions in GLES 2.0 (!)
Bug: 8679321
Change-Id: I5a4a93e158247910399325a965af5d2e3bbece9b
Diffstat (limited to 'services/surfaceflinger/RenderEngine')
7 files changed, 96 insertions, 35 deletions
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp index 428cdb8..19f17df 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp @@ -15,12 +15,12 @@ */ #include <GLES/gl.h> +#include <GLES/glext.h> #include <utils/String8.h> #include <cutils/compiler.h> #include "GLES11RenderEngine.h" -#include "GLExtensions.h" #include "Mesh.h" // --------------------------------------------------------------------------- @@ -183,6 +183,31 @@ void GLES11RenderEngine::disableBlending() { glDisable(GL_BLEND); } +void GLES11RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, + uint32_t* texName, uint32_t* fbName, uint32_t* status) { + 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); + + *status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); + *texName = tname; + *fbName = name; +} + +void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) { + glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); + glDeleteFramebuffersOES(1, &fbName); + glDeleteTextures(1, &texName); +} + void GLES11RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float b, float a) { glColor4f(r, g, b, a); glDisable(GL_TEXTURE_EXTERNAL_OES); @@ -219,14 +244,13 @@ void GLES11RenderEngine::drawMesh(const Mesh& mesh) { } void GLES11RenderEngine::dump(String8& result) { - const GLExtensions& extensions(GLExtensions::getInstance()); - result.appendFormat("GLES: %s, %s, %s\n", - extensions.getVendor(), - extensions.getRenderer(), - extensions.getVersion()); - result.appendFormat("%s\n", extensions.getExtension()); + RenderEngine::dump(result); } // --------------------------------------------------------------------------- }; // namespace android // --------------------------------------------------------------------------- + +#if defined(__gl2_h_) +#error "don't include gl2/gl2.h in this file" +#endif diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h index 8bb7ed1..d20ff1c 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h @@ -37,6 +37,10 @@ class GLES11RenderEngine : public RenderEngine { GLint mMaxViewportDims[2]; 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); + public: GLES11RenderEngine(); diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 9be12bf..4add66b 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -17,6 +17,7 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> #include <utils/String8.h> #include <utils/Trace.h> @@ -24,7 +25,6 @@ #include <cutils/compiler.h> #include "GLES20RenderEngine.h" -#include "GLExtensions.h" #include "Program.h" #include "ProgramCache.h" #include "Description.h" @@ -157,6 +157,32 @@ void GLES20RenderEngine::disableBlending() { glDisable(GL_BLEND); } + +void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, + uint32_t* texName, uint32_t* fbName, uint32_t* status) { + 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); + + *status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + *texName = tname; + *fbName = name; +} + +void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &fbName); + glDeleteTextures(1, &texName); +} + void GLES20RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float b, float a) { mState.setColor(r, g, b, a); disableTexturing(); @@ -200,14 +226,13 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { } void GLES20RenderEngine::dump(String8& result) { - const GLExtensions& extensions(GLExtensions::getInstance()); - result.appendFormat("GLES: %s, %s, %s\n", - extensions.getVendor(), - extensions.getRenderer(), - extensions.getVersion()); - result.appendFormat("%s\n", extensions.getExtension()); + RenderEngine::dump(result); } // --------------------------------------------------------------------------- }; // namespace android // --------------------------------------------------------------------------- + +#if defined(__gl_h_) +#error "don't include gl/gl.h in this file" +#endif diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h index 873a643..2998874 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -41,6 +41,10 @@ class GLES20RenderEngine : public RenderEngine { Description mState; + virtual void bindImageAsFramebuffer(EGLImageKHR image, + uint32_t* texName, uint32_t* fbName, uint32_t* status); + virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName); + public: GLES20RenderEngine(); diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp index f378713..db64a16 100644 --- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp +++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp @@ -122,6 +122,10 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) { if (needs.getTextureTarget() == Key::TEXTURE_EXT) { fs << "#extension GL_OES_EGL_image_external : require"; } + + // default precision is required-ish in fragment shaders + fs << "precision mediump float;"; + if (needs.getTextureTarget() == Key::TEXTURE_EXT) { fs << "uniform samplerExternalOES sampler;" << "varying vec2 outTexCoords;"; diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp index dc9cf4c..063be2e 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp @@ -42,7 +42,7 @@ RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) { EGL_NONE, EGL_NONE }; - EGLContext ctxt = EGL_NO_CONTEXT; // eglCreateContext(display, config, NULL, contextAttributes); + EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); if (ctxt == EGL_NO_CONTEXT) { // maybe ES 2.x is not supported ALOGW("can't create an ES 2.x context, trying 1.x"); @@ -190,34 +190,29 @@ void RenderEngine::deleteTextures(size_t count, uint32_t const* names) { glDeleteTextures(count, names); } +void RenderEngine::dump(String8& result) { + const GLExtensions& extensions(GLExtensions::getInstance()); + result.appendFormat("GLES: %s, %s, %s\n", + extensions.getVendor(), + extensions.getRenderer(), + extensions.getVersion()); + result.appendFormat("%s\n", extensions.getExtension()); +} + // --------------------------------------------------------------------------- RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer( RenderEngine& engine, EGLImageKHR image) : mEngine(engine) { - 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); - mStatus = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); + mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus); + ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d", mStatus); - mTexName = tname; - mFbName = name; } RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() { // back to main framebuffer - glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); - glDeleteFramebuffersOES(1, &mFbName); - glDeleteTextures(1, &mTexName); - + mEngine.unbindFramebuffer(mTexName, mFbName); } status_t RenderEngine::BindImageAsFramebuffer::getStatus() const { diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index f4fa30b..3c2b2ea 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -45,6 +45,9 @@ class RenderEngine { EGLContext mEGLContext; void setEGLContext(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; + protected: RenderEngine(); virtual ~RenderEngine() = 0; @@ -52,6 +55,9 @@ protected: public: static RenderEngine* create(EGLDisplay display, EGLConfig config); + // dump the extension strings. always call the base class. + virtual void dump(String8& result); + // helpers void clearWithColor(float red, float green, float blue, float alpha); void fillRegionWithColor(const Region& region, uint32_t height, @@ -65,8 +71,8 @@ public: class BindImageAsFramebuffer { RenderEngine& mEngine; - unsigned int mTexName, mFbName; - unsigned int mStatus; + uint32_t mTexName, mFbName; + uint32_t mStatus; public: BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image); ~BindImageAsFramebuffer(); @@ -75,7 +81,6 @@ public: // set-up virtual void checkErrors() const; - virtual void dump(String8& result) = 0; virtual void setViewportAndProjection(size_t vpw, size_t vph, size_t w, size_t h, bool yswap) = 0; virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0; virtual void setupDimLayerBlending(int alpha) = 0; |