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