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