Loading libs/renderengine/gl/ProgramCache.cpp +17 −9 Original line number Diff line number Diff line Loading @@ -742,15 +742,6 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) { if (needs.isOpaque()) { fs << "gl_FragColor.a = 1.0;"; } if (needs.hasAlpha()) { // modulate the current alpha value with alpha set if (needs.isPremultiplied()) { // ... and the color too if we're premultiplied fs << "gl_FragColor *= color.a;"; } else { fs << "gl_FragColor.a *= color.a;"; } } } if (needs.hasTransformMatrix() || Loading @@ -770,6 +761,23 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) { } } /* * Whether applying layer alpha before or after color transform doesn't matter, * as long as we can undo premultiplication. But we cannot un-premultiply * for color transform if the layer alpha = 0, e.g. 0 / (0 + 0.0019) = 0. */ if (!needs.drawShadows()) { if (needs.hasAlpha()) { // modulate the current alpha value with alpha set if (needs.isPremultiplied()) { // ... and the color too if we're premultiplied fs << "gl_FragColor *= color.a;"; } else { fs << "gl_FragColor.a *= color.a;"; } } } if (needs.hasRoundedCorners()) { if (needs.isPremultiplied()) { fs << "gl_FragColor *= vec4(applyCornerRadius(outCropCoords));"; Loading libs/renderengine/tests/RenderEngineTest.cpp +51 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,12 @@ struct RenderEngineTest : public ::testing::Test { template <typename SourceVariant> void fillBufferColorTransformCM(); template <typename SourceVariant> void fillBufferWithColorTransformZeroLayerAlpha(); template <typename SourceVariant> void fillBufferColorTransformZeroLayerAlpha(); template <typename SourceVariant> void fillRedBufferWithRoundedCorners(); Loading Loading @@ -709,6 +715,39 @@ void RenderEngineTest::fillBufferColorTransformCM() { expectBufferColor(fullscreenRect(), 126, 0, 0, 255, 1); } template <typename SourceVariant> void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() { renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); settings.clip = Rect(1, 1); std::vector<const renderengine::LayerSettings*> layers; renderengine::LayerSettings layer; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this); layer.alpha = 0; // construct a fake color matrix // simple inverse color settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1); layer.geometry.boundaries = Rect(1, 1).toFloatRect(); layers.push_back(&layer); invokeDraw(settings, layers, mBuffer); } template <typename SourceVariant> void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() { fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>(); expectBufferColor(fullscreenRect(), 0, 0, 0, 0); } template <typename SourceVariant> void RenderEngineTest::fillRedBufferWithRoundedCorners() { renderengine::DisplaySettings settings; Loading Loading @@ -1116,6 +1155,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformCM_colorSource) { fillBufferColorTransformCM<ColorSourceVariant>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) { fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) { fillBufferWithRoundedCorners<ColorSourceVariant>(); } Loading Loading @@ -1176,6 +1219,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformCM_opaqueBufferSourc fillBufferColorTransformCM<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) { fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) { fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } Loading Loading @@ -1236,6 +1283,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformCM_bufferSource) { fillBufferColorTransformCM<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) { fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) { fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } Loading Loading
libs/renderengine/gl/ProgramCache.cpp +17 −9 Original line number Diff line number Diff line Loading @@ -742,15 +742,6 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) { if (needs.isOpaque()) { fs << "gl_FragColor.a = 1.0;"; } if (needs.hasAlpha()) { // modulate the current alpha value with alpha set if (needs.isPremultiplied()) { // ... and the color too if we're premultiplied fs << "gl_FragColor *= color.a;"; } else { fs << "gl_FragColor.a *= color.a;"; } } } if (needs.hasTransformMatrix() || Loading @@ -770,6 +761,23 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) { } } /* * Whether applying layer alpha before or after color transform doesn't matter, * as long as we can undo premultiplication. But we cannot un-premultiply * for color transform if the layer alpha = 0, e.g. 0 / (0 + 0.0019) = 0. */ if (!needs.drawShadows()) { if (needs.hasAlpha()) { // modulate the current alpha value with alpha set if (needs.isPremultiplied()) { // ... and the color too if we're premultiplied fs << "gl_FragColor *= color.a;"; } else { fs << "gl_FragColor.a *= color.a;"; } } } if (needs.hasRoundedCorners()) { if (needs.isPremultiplied()) { fs << "gl_FragColor *= vec4(applyCornerRadius(outCropCoords));"; Loading
libs/renderengine/tests/RenderEngineTest.cpp +51 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,12 @@ struct RenderEngineTest : public ::testing::Test { template <typename SourceVariant> void fillBufferColorTransformCM(); template <typename SourceVariant> void fillBufferWithColorTransformZeroLayerAlpha(); template <typename SourceVariant> void fillBufferColorTransformZeroLayerAlpha(); template <typename SourceVariant> void fillRedBufferWithRoundedCorners(); Loading Loading @@ -709,6 +715,39 @@ void RenderEngineTest::fillBufferColorTransformCM() { expectBufferColor(fullscreenRect(), 126, 0, 0, 255, 1); } template <typename SourceVariant> void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() { renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); settings.clip = Rect(1, 1); std::vector<const renderengine::LayerSettings*> layers; renderengine::LayerSettings layer; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this); layer.alpha = 0; // construct a fake color matrix // simple inverse color settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1); layer.geometry.boundaries = Rect(1, 1).toFloatRect(); layers.push_back(&layer); invokeDraw(settings, layers, mBuffer); } template <typename SourceVariant> void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() { fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>(); expectBufferColor(fullscreenRect(), 0, 0, 0, 0); } template <typename SourceVariant> void RenderEngineTest::fillRedBufferWithRoundedCorners() { renderengine::DisplaySettings settings; Loading Loading @@ -1116,6 +1155,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformCM_colorSource) { fillBufferColorTransformCM<ColorSourceVariant>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) { fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) { fillBufferWithRoundedCorners<ColorSourceVariant>(); } Loading Loading @@ -1176,6 +1219,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformCM_opaqueBufferSourc fillBufferColorTransformCM<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) { fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) { fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } Loading Loading @@ -1236,6 +1283,10 @@ TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformCM_bufferSource) { fillBufferColorTransformCM<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) { fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) { fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } Loading