• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 
21 #include "LayerTransactionTest.h"
22 
23 namespace android {
24 
25 class EffectLayerTest : public LayerTransactionTest {
26 protected:
SetUp()27     virtual void SetUp() {
28         LayerTransactionTest::SetUp();
29         ASSERT_EQ(NO_ERROR, mClient->initCheck());
30 
31         const auto display = SurfaceComposerClient::getInternalDisplayToken();
32         ASSERT_FALSE(display == nullptr);
33 
34         mParentLayer = createColorLayer("Parent layer", Color::RED);
35         asTransaction([&](Transaction& t) {
36             t.setDisplayLayerStack(display, 0);
37             t.setLayer(mParentLayer, INT32_MAX - 2).show(mParentLayer);
38             t.setFlags(mParentLayer, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque);
39         });
40     }
41 
TearDown()42     virtual void TearDown() {
43         LayerTransactionTest::TearDown();
44         mParentLayer = 0;
45     }
46 
47     sp<SurfaceControl> mParentLayer;
48 };
49 
TEST_F(EffectLayerTest,DefaultEffectLayerHasSolidBlackFill)50 TEST_F(EffectLayerTest, DefaultEffectLayerHasSolidBlackFill) {
51     sp<SurfaceControl> effectLayer =
52             mClient->createSurface(String8("Effect Layer"), 0 /* width */, 0 /* height */,
53                                    PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceEffect,
54                                    mParentLayer->getHandle());
55 
56     EXPECT_NE(nullptr, effectLayer.get()) << "failed to create SurfaceControl";
57     asTransaction([&](Transaction& t) {
58         t.setCrop(effectLayer, Rect(0, 0, 400, 400));
59         t.show(effectLayer);
60     });
61 
62     {
63         SCOPED_TRACE("Default effect Layer has solid black fill");
64         auto shot = screenshot();
65         shot->expectColor(Rect(0, 0, 400, 400), Color::BLACK);
66     }
67 }
68 
TEST_F(EffectLayerTest,EffectLayerWithNoFill)69 TEST_F(EffectLayerTest, EffectLayerWithNoFill) {
70     sp<SurfaceControl> effectLayer =
71             mClient->createSurface(String8("Effect Layer"), 0 /* width */, 0 /* height */,
72                                    PIXEL_FORMAT_RGBA_8888,
73                                    ISurfaceComposerClient::eFXSurfaceEffect |
74                                            ISurfaceComposerClient::eNoColorFill,
75                                    mParentLayer->getHandle());
76 
77     EXPECT_NE(nullptr, effectLayer.get()) << "failed to create SurfaceControl";
78     asTransaction([&](Transaction& t) {
79         t.setCrop(effectLayer, Rect(0, 0, 400, 400));
80         t.show(effectLayer);
81     });
82 
83     {
84         SCOPED_TRACE("Effect layer with nofill option is transparent");
85         auto shot = screenshot();
86         shot->expectColor(Rect(0, 0, 400, 400), Color::RED);
87     }
88 }
89 
TEST_F(EffectLayerTest,EffectLayerCanSetColor)90 TEST_F(EffectLayerTest, EffectLayerCanSetColor) {
91     sp<SurfaceControl> effectLayer =
92             mClient->createSurface(String8("Effect Layer"), 0 /* width */, 0 /* height */,
93                                    PIXEL_FORMAT_RGBA_8888,
94                                    ISurfaceComposerClient::eFXSurfaceEffect |
95                                            ISurfaceComposerClient::eNoColorFill,
96                                    mParentLayer->getHandle());
97 
98     EXPECT_NE(nullptr, effectLayer.get()) << "failed to create SurfaceControl";
99     asTransaction([&](Transaction& t) {
100         t.setCrop(effectLayer, Rect(0, 0, 400, 400));
101         t.setColor(effectLayer,
102                    half3{Color::GREEN.r / 255.0f, Color::GREEN.g / 255.0f,
103                          Color::GREEN.b / 255.0f});
104         t.show(effectLayer);
105     });
106 
107     {
108         SCOPED_TRACE("Effect Layer can set color");
109         auto shot = screenshot();
110         shot->expectColor(Rect(0, 0, 400, 400), Color::GREEN);
111     }
112 }
113 
TEST_F(EffectLayerTest,BlurEffectLayerIsVisible)114 TEST_F(EffectLayerTest, BlurEffectLayerIsVisible) {
115     if (!deviceSupportsBlurs()) GTEST_SKIP();
116     if (!deviceUsesSkiaRenderEngine()) GTEST_SKIP();
117 
118     const auto canvasSize = 256;
119 
120     sp<SurfaceControl> leftLayer = createColorLayer("Left", Color::BLUE);
121     sp<SurfaceControl> rightLayer = createColorLayer("Right", Color::GREEN);
122     sp<SurfaceControl> blurLayer;
123     const auto leftRect = Rect(0, 0, canvasSize / 2, canvasSize);
124     const auto rightRect = Rect(canvasSize / 2, 0, canvasSize, canvasSize);
125     const auto blurRect = Rect(0, 0, canvasSize, canvasSize);
126 
127     asTransaction([&](Transaction& t) {
128         t.setLayer(leftLayer, mLayerZBase + 1);
129         t.reparent(leftLayer, mParentLayer);
130         t.setCrop(leftLayer, leftRect);
131         t.setLayer(rightLayer, mLayerZBase + 2);
132         t.reparent(rightLayer, mParentLayer);
133         t.setCrop(rightLayer, rightRect);
134         t.show(leftLayer);
135         t.show(rightLayer);
136     });
137 
138     {
139         auto shot = screenshot();
140         shot->expectColor(leftRect, Color::BLUE);
141         shot->expectColor(rightRect, Color::GREEN);
142     }
143 
144     ASSERT_NO_FATAL_FAILURE(blurLayer = createColorLayer("BackgroundBlur", Color::TRANSPARENT));
145 
146     const auto blurRadius = canvasSize / 2;
147     asTransaction([&](Transaction& t) {
148         t.setLayer(blurLayer, mLayerZBase + 3);
149         t.reparent(blurLayer, mParentLayer);
150         t.setBackgroundBlurRadius(blurLayer, blurRadius);
151         t.setCrop(blurLayer, blurRect);
152         t.setAlpha(blurLayer, 0.0f);
153         t.show(blurLayer);
154     });
155 
156     {
157         auto shot = screenshot();
158 
159         const auto stepSize = 1;
160         const auto blurAreaOffset = blurRadius * 0.7f;
161         const auto blurAreaStartX = canvasSize / 2 - blurRadius + blurAreaOffset;
162         const auto blurAreaEndX = canvasSize / 2 + blurRadius - blurAreaOffset;
163         Color previousColor;
164         Color currentColor;
165         for (int y = 0; y < canvasSize; y++) {
166             shot->checkPixel(0, y, /* r = */ 0, /* g = */ 0, /* b = */ 255);
167             previousColor = shot->getPixelColor(0, y);
168             for (int x = blurAreaStartX; x < blurAreaEndX; x += stepSize) {
169                 currentColor = shot->getPixelColor(x, y);
170                 ASSERT_GT(currentColor.g, previousColor.g);
171                 ASSERT_LT(currentColor.b, previousColor.b);
172                 ASSERT_EQ(0, currentColor.r);
173             }
174             shot->checkPixel(canvasSize - 1, y, 0, 255, 0);
175         }
176     }
177 }
178 
179 } // namespace android
180 
181 // TODO(b/129481165): remove the #pragma below and fix conversion issues
182 #pragma clang diagnostic pop // ignored "-Wconversion"
183