• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include <gtest/gtest.h>
15 
16 #include "Standalone.h"
17 #include "GLTestUtils.h"
18 
19 #include <memory>
20 
21 namespace emugl {
22 
23 struct ClearColorParam {
24     const GLESApi glVersion;
25     const bool fastBlit;
26 
ClearColorParamemugl::ClearColorParam27     ClearColorParam(GLESApi glVersion, bool fastBlit)
28         : glVersion(glVersion), fastBlit(fastBlit) {}
29 };
30 
PrintTo(const ClearColorParam & param,std::ostream * os)31 static void PrintTo(const ClearColorParam& param, std::ostream* os) {
32     *os << "ClearColorParam(";
33 
34     switch (param.glVersion) {
35         case GLESApi_CM:  *os << "GLESApi_CM";  break;
36         case GLESApi_2:   *os << "GLESApi_2";   break;
37         case GLESApi_3_0: *os << "GLESApi_3_0"; break;
38         case GLESApi_3_1: *os << "GLESApi_3_1"; break;
39         case GLESApi_3_2: *os << "GLESApi_3_2"; break;
40         default: *os << "GLESApi(" << int(param.glVersion) << ")"; break;
41     }
42 
43     *os << ", " << (param.fastBlit ? "fast blit" : "slow blit") << ")";
44 }
45 
46 class ClearColor final : public SampleApplication {
47 public:
ClearColor(ClearColorParam param)48     ClearColor(ClearColorParam param) : SampleApplication(256, 256, 60, param.glVersion) {
49         if (!param.fastBlit) {
50             // Disable fast blit and then recreate the color buffer to apply the
51             // change.
52             mFb->disableFastBlit();
53 
54             mFb->closeColorBuffer(mColorBuffer);
55             mColorBuffer = mFb->createColorBuffer(
56                     mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
57             mFb->setWindowSurfaceColorBuffer(mSurface, mColorBuffer);
58         }
59     }
60 
~ClearColor()61     ~ClearColor() {
62         auto gl = LazyLoadedGLESv2Dispatch::get();
63         if (mFbo) {
64             gl->glDeleteFramebuffers(1, &mFbo);
65             gl->glDeleteTextures(1, &mTexture);
66         }
67     }
68 
setClearColor(float r,float g,float b,float a)69     void setClearColor(float r, float g, float b, float a) {
70         mRed = r;
71         mGreen = g;
72         mBlue = b;
73         mAlpha = a;
74     }
75 
setUseFboCombined(bool useFbo)76     void setUseFboCombined(bool useFbo) {
77         mUseFboCombined = useFbo;
78     }
79 
setUseFbo(bool useFboDraw,bool useFboRead)80     void setUseFbo(bool useFboDraw, bool useFboRead) {
81         mUseFboDraw = useFboDraw;
82         mUseFboRead = useFboRead;
83     }
84 
initialize()85     void initialize() override {
86         auto gl = LazyLoadedGLESv2Dispatch::get();
87         gl->glActiveTexture(GL_TEXTURE0);
88 
89         if (!mFbo) {
90             gl->glGenFramebuffers(1, &mFbo);
91             gl->glGenTextures(1, &mTexture);
92 
93             gl->glBindTexture(GL_TEXTURE_2D, mTexture);
94             gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
95                              mWidth, mHeight, 0,
96                              GL_RGBA, GL_UNSIGNED_BYTE, 0);
97             gl->glBindTexture(GL_TEXTURE_2D, 0);
98 
99             gl->glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
100             gl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
101                                        GL_TEXTURE_2D, mTexture, 0);
102             gl->glBindFramebuffer(GL_FRAMEBUFFER, 0);
103         }
104     }
105 
draw()106     void draw() override {
107         auto gl = LazyLoadedGLESv2Dispatch::get();
108 
109         gl->glBindFramebuffer(GL_FRAMEBUFFER, mUseFboCombined ? mFbo : 0);
110 
111         if (mUseFboDraw) {
112             gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFbo);
113         }
114         if (mUseFboRead) {
115             gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, mFbo);
116         }
117 
118         gl->glClearColor(mRed, mGreen, mBlue, mAlpha);
119         gl->glClear(GL_COLOR_BUFFER_BIT);
120     }
121 
setNonDefaultCombinedFbo()122     void setNonDefaultCombinedFbo() {
123         setUseFboCombined(true);
124     }
125 
setNonDefaultDrawFbo()126     void setNonDefaultDrawFbo() {
127         setUseFbo(true, mUseFboRead);
128     }
129 
setNonDefaultReadFbo()130     void setNonDefaultReadFbo() {
131         setUseFbo(mUseFboDraw, true);
132     }
133 
drawWithColor(const float drawColor[4])134     void drawWithColor(const float drawColor[4]) {
135         setClearColor(drawColor[0], drawColor[1], drawColor[2], drawColor[3]);
136         drawOnce();
137     }
138 
verifySwappedColor(const float wantedColor[4])139     void verifySwappedColor(const float wantedColor[4]) {
140         TestTexture targetBuffer =
141             createTestTextureRGBA8888SingleColor(
142                 mWidth, mHeight, wantedColor[0], wantedColor[1], wantedColor[2], wantedColor[3]);
143 
144         TestTexture forRead =
145             createTestTextureRGBA8888SingleColor(
146                 mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
147 
148         mFb->readColorBuffer(
149             mColorBuffer, 0, 0, mWidth, mHeight,
150             GL_RGBA, GL_UNSIGNED_BYTE, forRead.data());
151 
152         EXPECT_TRUE(
153             ImageMatches(mWidth, mHeight, 4, mWidth, targetBuffer.data(), forRead.data()));
154     }
155 
156 private:
157     bool mUseFboCombined = false;
158     bool mUseFboDraw = false;
159     bool mUseFboRead = false;
160 
161     GLuint mFbo = 0;
162     GLuint mTexture = 0;
163 
164     float mRed = 1.0f;
165     float mGreen = 1.0f;
166     float mBlue = 1.0f;
167     float mAlpha = 1.0f;
168 };
169 
170 static constexpr float kDrawColorRed[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
171 static constexpr float kDrawColorGreen[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
172 
173 class CombinedFramebufferBlit : public ::testing::Test, public ::testing::WithParamInterface<ClearColorParam> {
174 protected:
SetUp()175     virtual void SetUp() override {
176         mApp.reset(new ClearColor(GetParam()));
177     }
178 
TearDown()179     virtual void TearDown() override {
180         mApp.reset();
181         EXPECT_EQ(EGL_SUCCESS, LazyLoadedEGLDispatch::get()->eglGetError())
182                 << "DefaultFramebufferBlitTest TearDown found an EGL error";
183     }
184 
185     std::unique_ptr<ClearColor> mApp;
186 };
187 
TEST_P(CombinedFramebufferBlit,DefaultDrawDefaultRead)188 TEST_P(CombinedFramebufferBlit, DefaultDrawDefaultRead) {
189     // Draw to default framebuffer; color should show up
190     mApp->drawWithColor(kDrawColorRed);
191     mApp->verifySwappedColor(kDrawColorRed);
192 }
193 
TEST_P(CombinedFramebufferBlit,NonDefault)194 TEST_P(CombinedFramebufferBlit, NonDefault) {
195     mApp->drawWithColor(kDrawColorRed);
196     mApp->verifySwappedColor(kDrawColorRed);
197 
198     // Color should not be affected by the draw to a non-default framebuffer.
199     mApp->setNonDefaultCombinedFbo();
200 
201     mApp->drawWithColor(kDrawColorGreen);
202     mApp->verifySwappedColor(kDrawColorRed);
203 }
204 
205 // Test blitting both with only the fast blit path.
206 INSTANTIATE_TEST_SUITE_P(CombinedFramebufferBlitTest,
207                         CombinedFramebufferBlit,
208                         testing::Values(
209                             ClearColorParam(GLESApi_CM, true),
210                             ClearColorParam(GLESApi_2, true),
211                             ClearColorParam(GLESApi_3_0, true)));
212 
213 class NonDefaultFramebufferBlit : public CombinedFramebufferBlit { };
214 
TEST_P(NonDefaultFramebufferBlit,NonDefaultDrawNonDefaultRead)215 TEST_P(NonDefaultFramebufferBlit, NonDefaultDrawNonDefaultRead) {
216     mApp->drawWithColor(kDrawColorRed);
217     mApp->verifySwappedColor(kDrawColorRed);
218 
219     // Color should not be affected by the draw to non-default
220     // draw/read framebuffers.
221     // (we preserve the previous contents of the surface in
222     // SampleApplication::drawOnce)
223     mApp->setNonDefaultDrawFbo();
224     mApp->setNonDefaultReadFbo();
225 
226     mApp->drawWithColor(kDrawColorGreen);
227     mApp->verifySwappedColor(kDrawColorRed);
228 }
229 
TEST_P(NonDefaultFramebufferBlit,DefaultDrawNonDefaultRead)230 TEST_P(NonDefaultFramebufferBlit, DefaultDrawNonDefaultRead) {
231     mApp->drawWithColor(kDrawColorRed);
232     mApp->verifySwappedColor(kDrawColorRed);
233 
234     // Bug: 110996998
235     // Draw to default framebuffer, and have a non-default
236     // read framebuffer bound. Color should show up
237     mApp->setNonDefaultReadFbo();
238 
239     mApp->drawWithColor(kDrawColorGreen);
240     mApp->verifySwappedColor(kDrawColorGreen);
241 }
242 
TEST_P(NonDefaultFramebufferBlit,NonDefaultDrawDefaultRead)243 TEST_P(NonDefaultFramebufferBlit, NonDefaultDrawDefaultRead) {
244     mApp->drawWithColor(kDrawColorRed);
245     mApp->verifySwappedColor(kDrawColorRed);
246 
247     // Draw to non-default framebuffer, and have the default
248     // read framebuffer bound. Color should not show up.
249     // (we preserve the previous contents of the surface in
250     // SampleApplication::drawOnce)
251     mApp->setNonDefaultDrawFbo();
252 
253     mApp->drawWithColor(kDrawColorGreen);
254     mApp->verifySwappedColor(kDrawColorRed);
255 }
256 
257 // Test blitting both with and without the fast blit path.
258 INSTANTIATE_TEST_SUITE_P(DefaultFramebufferBlitTest,
259                         NonDefaultFramebufferBlit,
260                         testing::Values(
261                             ClearColorParam(GLESApi_3_0, true)));
262 
263 
264 }  // namespace emugl
265