• 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 
15 #include <gtest/gtest.h>
16 
17 #include "GLTestUtils.h"
18 #include "OpenGLTestContext.h"
19 #include "TextureDraw.h"
20 
21 namespace emugl {
22 
23 namespace {
24 
TestTextureDrawBasic(const GLESv2Dispatch * gl,GLenum internalformat,GLenum format,bool should_work)25 void TestTextureDrawBasic(const GLESv2Dispatch* gl, GLenum internalformat,
26                           GLenum format, bool should_work) {
27     GLint viewport[4] = {};
28     gl->glGetIntegerv(GL_VIEWPORT, viewport);
29     EXPECT_EQ(0, viewport[0]);
30     EXPECT_EQ(0, viewport[1]);
31     const int width = viewport[2];
32     const int height = viewport[3];
33     const GLenum type = GL_UNSIGNED_BYTE;
34     const int bpp = 4;
35     const int bytes = width * height * bpp;
36 
37     GLuint textureToDraw;
38 
39     gl->glGenTextures(1, &textureToDraw);
40     gl->glActiveTexture(GL_TEXTURE0);
41     gl->glBindTexture(GL_TEXTURE_2D, textureToDraw);
42 
43     gl->glPixelStorei(GL_PACK_ALIGNMENT, 1);
44     gl->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
45     gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
46 
47     std::vector<unsigned char> pixels(bytes);
48 
49     for (int i = 0; i < height; i++) {
50         for (int j = 0; j < width; j++) {
51             pixels[i * width * bpp + j * bpp + 0] = (0xaa + i) % 0x100;
52             pixels[i * width * bpp + j * bpp + 1] = (0x00 + j) % 0x100;
53             pixels[i * width * bpp + j * bpp + 2] = (0x11 + i) % 0x100;
54             pixels[i * width * bpp + j * bpp + 3] = (0xff + j) % 0x100;
55         }
56     }
57     GLenum err = gl->glGetError();
58     EXPECT_EQ(GL_NO_ERROR, err);
59     gl->glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0,
60                      format, type, pixels.data());
61     err = gl->glGetError();
62     if (should_work) {
63         EXPECT_EQ(GL_NO_ERROR, err);
64     } else {
65         EXPECT_NE(GL_NO_ERROR, err);
66         return;
67     }
68     gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
69 
70     GLint fbStatus = gl->glCheckFramebufferStatus(GL_FRAMEBUFFER);
71     EXPECT_EQ((GLint)GL_FRAMEBUFFER_COMPLETE, fbStatus);
72 
73     TextureDraw textureDraw;
74 
75     textureDraw.draw(textureToDraw, 0, 0, 0);
76 
77     std::vector<unsigned char> pixelsOut(bytes, 0xff);
78 
79     gl->glReadPixels(0, 0, width, height, format, type, pixelsOut.data());
80 
81     // Check that the texture is drawn upside down (because that's what SurfaceFlinger wants)
82     for (int i = 0; i < height; i++) {
83         size_t rowBytes = width * bpp;
84         EXPECT_TRUE(RowMatches(i, width * bpp,
85                                pixels.data() + i * rowBytes,
86                                pixelsOut.data() + (height - i - 1) * rowBytes));
87     }
88 }
89 
TestTextureDrawLayer(const GLESv2Dispatch * gl)90 void TestTextureDrawLayer(const GLESv2Dispatch* gl) {
91     GLint viewport[4] = {};
92     gl->glGetIntegerv(GL_VIEWPORT, viewport);
93     EXPECT_EQ(0, viewport[0]);
94     EXPECT_EQ(0, viewport[1]);
95     const int width = viewport[2];
96     const int height = viewport[3];
97     const GLenum type = GL_UNSIGNED_BYTE;
98     const int bpp = 4;
99     const int bytes = width * height * bpp;
100 
101     GLuint textureToDraw;
102 
103     gl->glGenTextures(1, &textureToDraw);
104     gl->glActiveTexture(GL_TEXTURE0);
105     gl->glBindTexture(GL_TEXTURE_2D, textureToDraw);
106 
107     gl->glPixelStorei(GL_PACK_ALIGNMENT, 1);
108     gl->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
109     gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
110 
111     std::vector<unsigned char> pixels(bytes);
112 
113     for (int i = 0; i < height; i++) {
114         for (int j = 0; j < width; j++) {
115             pixels[i * width * bpp + j * bpp + 0] = 0xff;
116             pixels[i * width * bpp + j * bpp + 1] = 0x0;
117             pixels[i * width * bpp + j * bpp + 2] = 0x0;
118             pixels[i * width * bpp + j * bpp + 3] = 0xff;
119         }
120     }
121     GLenum err = gl->glGetError();
122     EXPECT_EQ(GL_NO_ERROR, err);
123     gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
124                      GL_RGBA, type, pixels.data());
125     err = gl->glGetError();
126     EXPECT_EQ(GL_NO_ERROR, err);
127     gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
128 
129     GLint fbStatus = gl->glCheckFramebufferStatus(GL_FRAMEBUFFER);
130     EXPECT_EQ((GLint)GL_FRAMEBUFFER_COMPLETE, fbStatus);
131 
132     TextureDraw textureDraw;
133 
134     // Test HWC2_COMPOSITION_SOLID_COLOR mode, red color
135     ComposeLayer l = {0,
136                       HWC2_COMPOSITION_SOLID_COLOR,
137                       {0, 0, width, height},
138                       {0.0, 0.0, (float)width, (float)height},
139                       HWC2_BLEND_MODE_NONE,
140                       1.0,
141                       {255, 0, 0, 255},
142                       (hwc_transform_t)0};
143     textureDraw.prepareForDrawLayer();
144     textureDraw.drawLayer(&l, width, height, width, height, textureToDraw);
145     std::vector<unsigned char> pixelsOut(bytes, 0xff);
146     gl->glReadPixels(0, 0, width, height, GL_RGBA, type, pixelsOut.data());
147     EXPECT_TRUE(ImageMatches(width, height, bpp, width,
148                              pixels.data(), pixelsOut.data()));
149 
150 
151     // Test HWC2_COMPOSITION_DEVICE mode, blue texture
152     for (int i = 0; i < height; i++) {
153         for (int j = 0; j < width; j++) {
154             pixels[i * width * bpp + j * bpp + 0] = 0x0;
155             pixels[i * width * bpp + j * bpp + 1] = 0x0;
156             pixels[i * width * bpp + j * bpp + 2] = 0xff;
157             pixels[i * width * bpp + j * bpp + 3] = 0xff;
158         }
159     }
160     err = gl->glGetError();
161     EXPECT_EQ(GL_NO_ERROR, err);
162     gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
163                      GL_RGBA, type, pixels.data());
164     l.composeMode = HWC2_COMPOSITION_DEVICE;
165     textureDraw.drawLayer(&l, width, height, width, height, textureToDraw);
166     gl->glReadPixels(0, 0, width, height, GL_RGBA, type, pixelsOut.data());
167     EXPECT_TRUE(ImageMatches(width, height, bpp, width,
168                              pixels.data(), pixelsOut.data()));
169 
170 
171     // Test composing 2 layers, layer1 draws blue to the upper half frame;
172     // layer2 draws the bottom half of the texture to the bottom half frame
173     ComposeLayer l1 = {0,
174                        HWC2_COMPOSITION_SOLID_COLOR,
175                        {0, 0, width, height/2},
176                        {0.0, 0.0, (float)width, (float)height/2},
177                        HWC2_BLEND_MODE_NONE,
178                        1.0,
179                        {0, 0, 255, 255},
180                        (hwc_transform_t)0};
181     ComposeLayer l2 = {0,
182                        HWC2_COMPOSITION_DEVICE,
183                        {0, height/2, width, height},
184                        {0.0, (float)height/2, (float)width, (float)height},
185                        HWC2_BLEND_MODE_NONE,
186                        1.0,
187                        {0, 0, 0, 0},
188                        (hwc_transform_t)0};
189     for (int i = 0; i < height; i++) {
190         for (int j = 0; j < width; j++) {
191             // texture bottom half green
192             if (i >= height/2) {
193                 pixels[i * width * bpp + j * bpp + 0] = 0x0;
194                 pixels[i * width * bpp + j * bpp + 2] = 0xff;
195             }
196         }
197     }
198     gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
199                      GL_RGBA, type, pixels.data());
200     textureDraw.drawLayer(&l1, width, height, width, height, textureToDraw);
201     textureDraw.drawLayer(&l2, width, height, width, height, textureToDraw);
202     gl->glReadPixels(0, 0, width, height, GL_RGBA, type, pixelsOut.data());
203     EXPECT_TRUE(ImageMatches(width, height, bpp, width,
204                              pixels.data(), pixelsOut.data()));
205 
206 }
207 
208 }  // namespace
209 
210 #define GL_BGRA_EXT 0x80E1
211 
TEST_F(GLTest,TextureDrawBasic)212 TEST_F(GLTest, TextureDrawBasic) {
213     TestTextureDrawBasic(gl, GL_RGBA, GL_RGBA, true);
214     // Assumes BGRA is supported
215     // Note: On NVIDIA EGL, the format mismatch with RGBA cauases a failure.
216     // TestTextureDrawBasic(gl, GL_BGRA_EXT, GL_BGRA_EXT, true);
217     // TestTextureDrawBasic(gl, GL_RGBA, GL_BGRA_EXT, false);
218     TestTextureDrawLayer(gl);
219 }
220 
221 }  // namespace emugl
222