Loading services/surfaceflinger/Layer.cpp +75 −18 Original line number Diff line number Diff line Loading @@ -559,32 +559,89 @@ void Layer::clearWithOpenGL( clearWithOpenGL(hw, clip, 0,0,0,0); } static void setupOpenGL10(bool premultipliedAlpha, bool opaque, int alpha) { // OpenGL ES 1.0 doesn't support texture combiners. // This path doesn't properly handle opaque layers that have non-opaque // alpha values. The alpha channel will be copied into the framebuffer or // screenshot, so if the framebuffer or screenshot is blended on top of // something else, whatever is below the window will incorrectly show // through. if (CC_UNLIKELY(alpha < 0xFF)) { GLfloat floatAlpha = alpha * (1.0f / 255.0f); if (premultipliedAlpha) { glColor4f(floatAlpha, floatAlpha, floatAlpha, floatAlpha); } else { glColor4f(1.0f, 1.0f, 1.0f, floatAlpha); } glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); } } static void setupOpenGL11(bool premultipliedAlpha, bool opaque, int alpha) { GLenum combineRGB; GLenum combineAlpha; GLenum src0Alpha; GLfloat envColor[4]; if (CC_UNLIKELY(alpha < 0xFF)) { // Cv = premultiplied ? Cs*alpha : Cs // Av = !opaque ? alpha*As : 1.0 combineRGB = premultipliedAlpha ? GL_MODULATE : GL_REPLACE; combineAlpha = !opaque ? GL_MODULATE : GL_REPLACE; src0Alpha = GL_CONSTANT; envColor[0] = alpha * (1.0f / 255.0f); } else { // Cv = Cs // Av = opaque ? 1.0 : As combineRGB = GL_REPLACE; combineAlpha = GL_REPLACE; src0Alpha = opaque ? GL_CONSTANT : GL_TEXTURE; envColor[0] = 1.0f; } glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, combineRGB); glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); if (combineRGB == GL_MODULATE) { glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); } glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, combineAlpha); glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, src0Alpha); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); if (combineAlpha == GL_MODULATE) { glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); } if (combineRGB == GL_MODULATE || src0Alpha == GL_CONSTANT) { envColor[1] = envColor[0]; envColor[2] = envColor[0]; envColor[3] = envColor[0]; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor); } } void Layer::drawWithOpenGL( const sp<const DisplayDevice>& hw, const Region& clip) const { const uint32_t fbHeight = hw->getHeight(); const State& s(drawingState()); GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; if (CC_UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); if (mFlinger->getGlesVersion() == GLES_VERSION_1_0) { setupOpenGL10(mPremultipliedAlpha, isOpaque(), s.alpha); } else { glColor4f(1, 1, 1, alpha); setupOpenGL11(mPremultipliedAlpha, isOpaque(), s.alpha); } if (s.alpha < 0xFF || !isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (!isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } LayerMesh mesh; computeGeometry(hw, &mesh); Loading services/surfaceflinger/SurfaceFlinger.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -414,6 +414,22 @@ EGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) return ctxt; } static GlesVersion parseGlesVersion(const char* str) { int major, minor; if (sscanf(str, "OpenGL ES-CM %d.%d", &major, &minor) != 2) { ALOGW("Unable to parse GL_VERSION string: \"%s\"", str); return GLES_VERSION_1_0; } if (major == 1 && minor == 0) return GLES_VERSION_1_0; if (major == 1 && minor >= 1) return GLES_VERSION_1_1; if (major == 2 && minor >= 0) return GLES_VERSION_2_0; if (major == 3 && minor >= 0) return GLES_VERSION_3_0; ALOGW("Unrecognized OpenGL ES version: %d.%d", major, minor); return GLES_VERSION_1_0; } void SurfaceFlinger::initializeGL(EGLDisplay display) { GLExtensions& extensions(GLExtensions::getInstance()); extensions.initWithGLStrings( Loading @@ -425,6 +441,8 @@ void SurfaceFlinger::initializeGL(EGLDisplay display) { eglQueryString(display, EGL_VERSION), eglQueryString(display, EGL_EXTENSIONS)); mGlesVersion = parseGlesVersion(extensions.getVersion()); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); Loading services/surfaceflinger/SurfaceFlinger.h +13 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,13 @@ enum { eTransactionMask = 0x07 }; enum GlesVersion { GLES_VERSION_1_0 = 0x10000, GLES_VERSION_1_1 = 0x10001, GLES_VERSION_2_0 = 0x20000, GLES_VERSION_3_0 = 0x30000, }; class SurfaceFlinger : public BinderService<SurfaceFlinger>, public BnSurfaceComposer, private IBinder::DeathRecipient, Loading Loading @@ -121,6 +128,11 @@ public: // TODO: this should be made accessible only to HWComposer const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int id); // return the version of the OpenGL ES composition context GlesVersion getGlesVersion() const { return mGlesVersion; } private: friend class Client; friend class DisplayEventConnection; Loading Loading @@ -421,6 +433,7 @@ private: EGLConfig mEGLConfig; EGLDisplay mEGLDisplay; EGLint mEGLNativeVisualId; GlesVersion mGlesVersion; sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_DISPLAY_TYPES]; // Can only accessed from the main thread, these members Loading Loading
services/surfaceflinger/Layer.cpp +75 −18 Original line number Diff line number Diff line Loading @@ -559,32 +559,89 @@ void Layer::clearWithOpenGL( clearWithOpenGL(hw, clip, 0,0,0,0); } static void setupOpenGL10(bool premultipliedAlpha, bool opaque, int alpha) { // OpenGL ES 1.0 doesn't support texture combiners. // This path doesn't properly handle opaque layers that have non-opaque // alpha values. The alpha channel will be copied into the framebuffer or // screenshot, so if the framebuffer or screenshot is blended on top of // something else, whatever is below the window will incorrectly show // through. if (CC_UNLIKELY(alpha < 0xFF)) { GLfloat floatAlpha = alpha * (1.0f / 255.0f); if (premultipliedAlpha) { glColor4f(floatAlpha, floatAlpha, floatAlpha, floatAlpha); } else { glColor4f(1.0f, 1.0f, 1.0f, floatAlpha); } glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); } } static void setupOpenGL11(bool premultipliedAlpha, bool opaque, int alpha) { GLenum combineRGB; GLenum combineAlpha; GLenum src0Alpha; GLfloat envColor[4]; if (CC_UNLIKELY(alpha < 0xFF)) { // Cv = premultiplied ? Cs*alpha : Cs // Av = !opaque ? alpha*As : 1.0 combineRGB = premultipliedAlpha ? GL_MODULATE : GL_REPLACE; combineAlpha = !opaque ? GL_MODULATE : GL_REPLACE; src0Alpha = GL_CONSTANT; envColor[0] = alpha * (1.0f / 255.0f); } else { // Cv = Cs // Av = opaque ? 1.0 : As combineRGB = GL_REPLACE; combineAlpha = GL_REPLACE; src0Alpha = opaque ? GL_CONSTANT : GL_TEXTURE; envColor[0] = 1.0f; } glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, combineRGB); glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); if (combineRGB == GL_MODULATE) { glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); } glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, combineAlpha); glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, src0Alpha); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); if (combineAlpha == GL_MODULATE) { glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); } if (combineRGB == GL_MODULATE || src0Alpha == GL_CONSTANT) { envColor[1] = envColor[0]; envColor[2] = envColor[0]; envColor[3] = envColor[0]; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor); } } void Layer::drawWithOpenGL( const sp<const DisplayDevice>& hw, const Region& clip) const { const uint32_t fbHeight = hw->getHeight(); const State& s(drawingState()); GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; if (CC_UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); if (mFlinger->getGlesVersion() == GLES_VERSION_1_0) { setupOpenGL10(mPremultipliedAlpha, isOpaque(), s.alpha); } else { glColor4f(1, 1, 1, alpha); setupOpenGL11(mPremultipliedAlpha, isOpaque(), s.alpha); } if (s.alpha < 0xFF || !isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (!isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } LayerMesh mesh; computeGeometry(hw, &mesh); Loading
services/surfaceflinger/SurfaceFlinger.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -414,6 +414,22 @@ EGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) return ctxt; } static GlesVersion parseGlesVersion(const char* str) { int major, minor; if (sscanf(str, "OpenGL ES-CM %d.%d", &major, &minor) != 2) { ALOGW("Unable to parse GL_VERSION string: \"%s\"", str); return GLES_VERSION_1_0; } if (major == 1 && minor == 0) return GLES_VERSION_1_0; if (major == 1 && minor >= 1) return GLES_VERSION_1_1; if (major == 2 && minor >= 0) return GLES_VERSION_2_0; if (major == 3 && minor >= 0) return GLES_VERSION_3_0; ALOGW("Unrecognized OpenGL ES version: %d.%d", major, minor); return GLES_VERSION_1_0; } void SurfaceFlinger::initializeGL(EGLDisplay display) { GLExtensions& extensions(GLExtensions::getInstance()); extensions.initWithGLStrings( Loading @@ -425,6 +441,8 @@ void SurfaceFlinger::initializeGL(EGLDisplay display) { eglQueryString(display, EGL_VERSION), eglQueryString(display, EGL_EXTENSIONS)); mGlesVersion = parseGlesVersion(extensions.getVersion()); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); Loading
services/surfaceflinger/SurfaceFlinger.h +13 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,13 @@ enum { eTransactionMask = 0x07 }; enum GlesVersion { GLES_VERSION_1_0 = 0x10000, GLES_VERSION_1_1 = 0x10001, GLES_VERSION_2_0 = 0x20000, GLES_VERSION_3_0 = 0x30000, }; class SurfaceFlinger : public BinderService<SurfaceFlinger>, public BnSurfaceComposer, private IBinder::DeathRecipient, Loading Loading @@ -121,6 +128,11 @@ public: // TODO: this should be made accessible only to HWComposer const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int id); // return the version of the OpenGL ES composition context GlesVersion getGlesVersion() const { return mGlesVersion; } private: friend class Client; friend class DisplayEventConnection; Loading Loading @@ -421,6 +433,7 @@ private: EGLConfig mEGLConfig; EGLDisplay mEGLDisplay; EGLint mEGLNativeVisualId; GlesVersion mGlesVersion; sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_DISPLAY_TYPES]; // Can only accessed from the main thread, these members Loading