1 /*
2  * Copyright (C) 2018 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 #include <EGL/egl.h>
18 #include <EGL/eglext.h>
19 #include <GLES2/gl2.h>
20 #include <GLES2/gl2ext.h>
21 #include <GLES3/gl32.h>
22 
23 #include <array>
24 #include <cmath>
25 #include <iterator>
26 #include <set>
27 #include <sstream>
28 #include <string>
29 #include <vector>
30 
31 #include <android/hardware_buffer.h>
32 #include <android/log.h>
33 #include <gtest/gtest.h>
34 
35 #define NO_ERROR 0
36 #define LOG_TAG "AHBGLTest"
37 #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
38 
39 namespace android {
40 namespace {
41 
42 // The 'stride' field is ignored by AHardwareBuffer_allocate, so we can use it
43 // to pass these flags.
44 enum TestFlags {
45     kGlFormat = 0x1,            // The 'format' field specifies a GL format.
46     kUseSrgb = 0x2,             // Whether to use the sRGB transfer function.
47     kExplicitYuvSampling = 0x4, // Whether to do explicit YUV conversion sampling,
48                                 // if false, GL will do conversions implicitly.
49 };
50 
51 // Conversion from YUV to RGB used by GPU. This assumes BT.601 (partial) format.
52 // The matrix M is multiplied in (Y,U,V) = M * (R, G, B, 1) to obtain the final YUV value s.
53 // TODO(b/123041714): Assumes ITU_601 color space is used. Can we count on this? Spec is unclear for
54 //                    glReadPixels YUV -> RGB conversion.
55 const double kYuvToRgb[] = {
56     0.25678823529411765,  0.50412941176470580,  0.09790588235294118, 16.00,
57    -0.14822352941176470, -0.29099215686274510,  0.43921568627450980, 128.0,
58     0.43921568627450980, -0.36778823529411764, -0.07142745098039215, 128.0
59 };
60 
61 #define FORMAT_CASE(x) case AHARDWAREBUFFER_FORMAT_##x: return #x; break
62 #define GL_FORMAT_CASE(x) case x: return #x; break;
AHBFormatAsString(int32_t format)63 const char* AHBFormatAsString(int32_t format) {
64     switch (format) {
65         FORMAT_CASE(R8G8B8A8_UNORM);
66         FORMAT_CASE(R8G8B8X8_UNORM);
67         FORMAT_CASE(R8G8B8_UNORM);
68         FORMAT_CASE(R5G6B5_UNORM);
69         FORMAT_CASE(R16G16B16A16_FLOAT);
70         FORMAT_CASE(R10G10B10A2_UNORM);
71         FORMAT_CASE(BLOB);
72         FORMAT_CASE(D16_UNORM);
73         FORMAT_CASE(D24_UNORM);
74         FORMAT_CASE(D24_UNORM_S8_UINT);
75         FORMAT_CASE(D32_FLOAT);
76         FORMAT_CASE(D32_FLOAT_S8_UINT);
77         FORMAT_CASE(S8_UINT);
78         FORMAT_CASE(Y8Cb8Cr8_420);
79         FORMAT_CASE(R8_UNORM);
80         FORMAT_CASE(R16_UINT);
81         FORMAT_CASE(R16G16_UINT);
82         GL_FORMAT_CASE(GL_RGB8);
83         GL_FORMAT_CASE(GL_RGBA8);
84         GL_FORMAT_CASE(GL_RGB565);
85         GL_FORMAT_CASE(GL_SRGB8_ALPHA8);
86         GL_FORMAT_CASE(GL_RGBA16F);
87         GL_FORMAT_CASE(GL_RGB10_A2);
88         GL_FORMAT_CASE(GL_DEPTH_COMPONENT16);
89         GL_FORMAT_CASE(GL_DEPTH24_STENCIL8);
90         GL_FORMAT_CASE(GL_STENCIL_INDEX8);
91         GL_FORMAT_CASE(GL_R8);
92         GL_FORMAT_CASE(GL_R16UI);
93         GL_FORMAT_CASE(GL_RG16UI);
94     }
95     return "";
96 }
97 
GetTestName(const::testing::TestParamInfo<AHardwareBuffer_Desc> & info)98 std::string GetTestName(const ::testing::TestParamInfo<AHardwareBuffer_Desc>& info) {
99     std::ostringstream name;
100     const char* format_string = AHBFormatAsString(info.param.format);
101     if (strlen(format_string) == 0) {
102         name << info.index;
103     } else {
104         name << format_string;
105         if (info.param.stride & kUseSrgb) {
106             name << "_sRGB";
107         }
108         if (info.param.stride & kExplicitYuvSampling) {
109             name << "_explicitYuvSampling";
110         }
111     }
112     return name.str();
113 }
114 
115 union IntFloat {
116     uint32_t i;
117     float f;
118 };
119 
120 // Copied from android.util.Half
121 // Used for reading directly from half-float buffers
FloatFromHalf(uint16_t bits)122 float FloatFromHalf(uint16_t bits) {
123     uint32_t s = bits & 0x8000;
124     uint32_t e = (bits & 0x7C00) >> 10;
125     uint32_t m = bits & 0x3FF;
126     uint32_t outE = 0;
127     uint32_t outM = 0;
128     if (e == 0) { // Denormal or 0
129         if (m != 0) {
130             // Convert denorm fp16 into normalized fp32
131             IntFloat uif;
132             uif.i = (126 << 23);
133             float denormal = uif.f;
134             uif.i += m;
135             float o = uif.f - denormal;
136             return s == 0 ? o : -o;
137         }
138     } else {
139         outM = m << 13;
140         if (e == 0x1f) { // Infinite or NaN
141             outE = 0xff;
142         } else {
143             outE = e - 15 + 127;
144         }
145     }
146     IntFloat result;
147     result.i = (s << 16) | (outE << 23) | outM;
148     return result.f;
149 }
150 
151 // Copied from android.util.Half
152 // Used for writing directly into half-float buffers.
HalfFromFloat(float value)153 uint16_t HalfFromFloat(float value) {
154     uint32_t bits = *reinterpret_cast<uint32_t*>(&value); // convert to int bits
155     int32_t s = (bits >> 31);
156     int32_t e = (bits >> 23) & 0xFF;
157     int32_t m = bits & 0x7FFFFF;
158 
159     int32_t outE = 0;
160     int32_t outM = 0;
161 
162     if (e == 0xff) { // Infinite or NaN
163         outE = 0x1f;
164         outM = m != 0 ? 0x200 : 0;
165     } else {
166         e = e - 127 + 15;
167         if (e >= 0x1f) { // Overflow
168             outE = 0x31;
169         } else if (e <= 0) { // Underflow
170             if (e < -10) {
171                 // The absolute fp32 value is less than MIN_VALUE, flush to +/-0
172             } else {
173                 // The fp32 value is a normalized float less than MIN_NORMAL,
174                 // we convert to a denorm fp16
175                 m = (m | 0x800000) >> (1 - e);
176                 if ((m & 0x1000) != 0) m += 0x2000;
177                 outM = m >> 13;
178             }
179         } else {
180             outE = e;
181             outM = m >> 13;
182             if ((m & 0x1000) != 0) {
183                 // Round to nearest "0.5" up
184                 int out = (outE << 10) | outM;
185                 out++;
186                 return static_cast<uint16_t>(out | (s << 15));
187             }
188         }
189     }
190     return static_cast<uint16_t>((s << 15) | (outE << 10) | outM);
191 }
192 
193 // Utility function to ensure converted values are clamped to [0...255].
ClampToUInt8(float value)194 uint8_t ClampToUInt8(float value) {
195     return static_cast<uint8_t>(value <= 0.0 ? 0 : (value >= 255.0 ? 255 : value));
196 }
197 
MipLevelCount(uint32_t width,uint32_t height)198 int MipLevelCount(uint32_t width, uint32_t height) {
199     return 1 + static_cast<int>(std::floor(std::log2(static_cast<float>(std::max(width, height)))));
200 }
201 
RoundUpToPowerOf2(uint32_t value)202 uint32_t RoundUpToPowerOf2(uint32_t value) {
203     return value == 0u ? value : 1u << (32 - __builtin_clz(value - 1));
204 }
205 
206 // Returns true only if the format has a dedicated alpha channel
FormatHasAlpha(uint32_t format)207 bool FormatHasAlpha(uint32_t format) {
208     switch (format) {
209         case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
210         case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
211         case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
212         // This may look scary, but fortunately AHardwareBuffer formats and GL pixel formats
213         // do not overlap.
214         case GL_RGBA8:
215         case GL_RGB10_A2:
216         case GL_RGBA16F:
217         case GL_SRGB8_ALPHA8:
218             return true;
219         default: return false;
220     }
221 }
222 
223 // Returns true only if the format has its components specified in some floating point format.
FormatIsFloat(uint32_t format)224 bool FormatIsFloat(uint32_t format) {
225     return format == AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT || format == GL_RGBA16F;
226 }
227 
228 // Returns true only if the format is a YUV format.
FormatIsYuv(uint32_t format)229 bool FormatIsYuv(uint32_t format) {
230     // Update with more YUV cases here if more formats become available
231     return format == AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
232 }
233 
UploadData(const AHardwareBuffer_Desc & desc,GLenum format,GLenum type,const void * data)234 void UploadData(const AHardwareBuffer_Desc& desc, GLenum format, GLenum type, const void* data) {
235     if (desc.layers <= 1) {
236         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, desc.width, desc.height, format, type, data);
237         ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()) << "glTexSubImage2D failed";
238     } else {
239         for (uint32_t layer = 0; layer < desc.layers; ++layer) {
240             glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, desc.width, desc.height, 1,
241                             format, type, data);
242             ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()) << "glTexSubImage3D failed";
243         }
244     }
245 }
246 
247 // Uploads opaque red to the currently bound texture.
UploadRedPixels(const AHardwareBuffer_Desc & desc)248 void UploadRedPixels(const AHardwareBuffer_Desc& desc) {
249     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
250     const bool use_srgb = desc.stride & kUseSrgb;
251     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
252     switch (desc.format) {
253         case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
254         case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
255         case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
256         case GL_RGB565:
257         case GL_RGB8: {
258             // GL_RGB565 supports uploading GL_UNSIGNED_BYTE data.
259             const int size = desc.width * desc.height * 3;
260             std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]);
261             for (int i = 0; i < size; i += 3) {
262                 pixels[i] = use_srgb ? 188 : 255;
263                 pixels[i + 1] = 0;
264                 pixels[i + 2] = 0;
265             }
266             UploadData(desc, GL_RGB, GL_UNSIGNED_BYTE, pixels.get());
267             break;
268         }
269         case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
270         case GL_RGBA8:
271         case GL_SRGB8_ALPHA8: {
272             const int size = desc.width * desc.height * 4;
273             std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]);
274             for (int i = 0; i < size; i += 4) {
275                 pixels[i] = use_srgb ? 188 : 255;
276                 pixels[i + 1] = 0;
277                 pixels[i + 2] = 0;
278                 pixels[i + 3] = use_srgb ? 128 : 255;
279             }
280             UploadData(desc, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
281             break;
282         }
283         case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
284         case GL_RGBA16F: {
285             const int size = desc.width * desc.height * 4;
286             std::unique_ptr<float[]> pixels(new float[size]);
287             for (int i = 0; i < size; i += 4) {
288                 pixels[i] = 1.f;
289                 pixels[i + 1] = 0.f;
290                 pixels[i + 2] = 0.f;
291                 pixels[i + 3] = 1.f;
292             }
293             UploadData(desc, GL_RGBA, GL_FLOAT, pixels.get());
294             break;
295         }
296         case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
297         case GL_RGB10_A2: {
298             const int size = desc.width * desc.height;
299             std::unique_ptr<uint32_t[]> pixels(new uint32_t[size]);
300             for (int i = 0; i < size; ++i) {
301                 // Opaque red is top 2 bits and bottom 10 bits set.
302                 pixels[i] = 0xc00003ff;
303             }
304             UploadData(desc, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT, pixels.get());
305             break;
306         }
307         default: FAIL() << "Unrecognized AHardwareBuffer format"; break;
308     }
309 }
310 
311 // A pre-defined list of colors that will be used for testing
312 enum GoldenColor {
313     kZero,  // all zero, i.e., transparent black
314     kBlack,  // opaque black
315     kWhite,  // opaque white
316     kRed,  // opaque red
317     kGreen,  // opaque green
318     kBlue,  // opaque blue
319     kRed50,  // 50% premultiplied red, i.e., (0.5, 0, 0, 0.5)
320     kRed50Srgb,  // 50% premultiplied red under sRGB transfer function
321     kRed50Alpha100,  // Opaque 50% red
322 };
323 
324 // A golden color at a specified position (given in pixel coordinates)
325 struct GoldenPixel {
326     int x;
327     int y;
328     GoldenColor color;
329 };
330 
331 // Compares a golden pixel against an actual pixel given the 4 color values. The values must
332 // match exactly.
333 template <typename T>
CheckGoldenPixel(int x,int y,const std::array<T,4> & golden,const std::array<T,4> & actual)334 void CheckGoldenPixel(int x, int y, const std::array<T, 4>& golden,
335                       const std::array<T, 4>& actual) {
336     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
337     EXPECT_EQ(golden, actual) << "Pixel doesn't match at X=" << x << ", Y=" << y;
338 }
339 
340 // Compares an actual pixel against a range of pixel values specified by a minimum and maximum
341 // 4-component pixel value.
342 template <typename T>
CheckGoldenPixel(int x,int y,const std::array<T,4> & minimum,const std::array<T,4> & maximum,const std::array<T,4> & actual)343 void CheckGoldenPixel(int x, int y, const std::array<T, 4>& minimum,
344                       const std::array<T, 4>& maximum, const std::array<T, 4>& actual) {
345     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
346     bool in_range = true;
347     for (int i = 0; i < 4; ++i) {
348         if (actual[i] < minimum[i] || actual[i] > maximum[i]) {
349             in_range = false;
350             break;
351         }
352     }
353     // Prefix with '+' so that uint8_t values are printed out as integers
354     EXPECT_TRUE(in_range) << "Pixel out of acceptable range at X=" << x << ", Y=" << y
355         << "; actual value: {" << +actual[0] << ", " << +actual[1] << ", "
356                                << +actual[2] << ", " << +actual[3]
357         << "}, minimum: {" << +minimum[0] << ", " << +minimum[1] << ", "
358                            << +minimum[2] << ", " << +minimum[3]
359         << "}, maximum: {" << +maximum[0] << ", " << +maximum[1] << ", "
360                            << +maximum[2] << ", " << +maximum[3]
361         << "}";
362 }
363 
364 // Given a golden color, format, and maximum allowed error, returns a 4-component pixel (as well as
365 // a maximum where it makes sense). Returns true, if the golden_max_out parameter was set, and
366 // the return values indicate a range.
GetGoldenColor(const GoldenColor & golden,uint32_t format,int32_t max_err,std::array<uint8_t,4> * golden_pixel_out,std::array<uint8_t,4> * golden_max_out)367 bool GetGoldenColor(const GoldenColor& golden, uint32_t format, int32_t max_err,
368                     std::array<uint8_t, 4>* golden_pixel_out,
369                     std::array<uint8_t, 4>* golden_max_out) {
370     bool use_range = false;
371     // Adjust color values.
372     std::array<uint8_t, 4>& golden_pixel = *golden_pixel_out;
373     std::array<uint8_t, 4>& golden_max = *golden_max_out;
374     golden_pixel[0] = golden_pixel[1] = golden_pixel[2] = 0;
375     golden_max[0] = golden_max[1] = golden_max[2] = 0;
376     golden_pixel[3] = 255;
377     golden_max[3] = 255;
378     switch (golden) {
379         case kRed: golden_pixel[0] = 255; break;
380         case kRed50:
381         case kRed50Alpha100:
382             use_range = true;
383             golden_pixel[0] = 127;
384             golden_max[0] = 128;
385             break;
386         case kRed50Srgb:
387             use_range = true;
388             golden_pixel[0] = 187;
389             golden_max[0] = 188;
390             break;
391         case kGreen: golden_pixel[1] = 255; break;
392         case kBlue: golden_pixel[2] = 255; break;
393         case kZero: if (FormatHasAlpha(format)) golden_pixel[3] = 0; break;
394         case kWhite: golden_pixel[0] = 255; golden_pixel[1] = 255; golden_pixel[2] = 255; break;
395         case kBlack: break;
396         default:
397             ADD_FAILURE() << "Unrecognized golden pixel color";
398             return false;
399     }
400     // Adjust alpha.
401     if (golden == kRed50 || golden == kRed50Srgb) {
402         if (format == GL_RGB10_A2 || format == AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM) {
403             golden_pixel[3] = 85;
404             golden_max[3] = 170;
405         } else if (FormatHasAlpha(format)) {
406             golden_pixel[3] = 127;
407             golden_max[3] = 128;
408         }
409     }
410     // Adjust color range for RGB565.
411     if ((golden == kRed50 || golden == kRed50Alpha100) &&
412         (format == GL_RGB565 || format == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM)) {
413         golden_pixel[0] = 123;
414         golden_max[0] = 132;
415     }
416     // Convert to YUV if this is a YUV format
417     if (FormatIsYuv(format)) {
418         const uint8_t r = golden_pixel[0];
419         const uint8_t g = golden_pixel[1];
420         const uint8_t b = golden_pixel[2];
421         const float y = kYuvToRgb[0] * r + kYuvToRgb[1] * g + kYuvToRgb[2]   * b + kYuvToRgb[3];
422         const float u = kYuvToRgb[4] * r + kYuvToRgb[5] * g + kYuvToRgb[6]   * b + kYuvToRgb[7];
423         const float v = kYuvToRgb[8] * r + kYuvToRgb[9] * g + kYuvToRgb[10]  * b + kYuvToRgb[11];
424         golden_pixel[0] = ClampToUInt8(y);
425         golden_pixel[1] = ClampToUInt8(u);
426         golden_pixel[2] = ClampToUInt8(v);
427     }
428     // Apply error bounds
429     if (max_err != 0) {
430         for (int i = 0; i < 4; ++i) {
431             golden_pixel[i] = ClampToUInt8(golden_pixel[i] - max_err);
432             golden_max[i] = ClampToUInt8(golden_pixel[i] + max_err);
433         }
434         use_range = true;
435     }
436     return use_range;
437 }
438 
439 // Get a golden color for range-less values.
GetGoldenColor(const GoldenColor & golden,uint32_t format,std::array<uint8_t,4> * golden_pixel_out)440 void GetGoldenColor(const GoldenColor& golden, uint32_t format,
441                     std::array<uint8_t, 4>* golden_pixel_out) {
442     std::array<uint8_t, 4> ignore;
443     GetGoldenColor(golden, format, 0, golden_pixel_out, &ignore);
444 }
445 
446 // Get a golden color for floating point values.
GetGoldenColor(const GoldenColor & golden,std::array<float,4> * golden_pixel_out)447 void GetGoldenColor(const GoldenColor& golden, std::array<float, 4>* golden_pixel_out) {
448     std::array<float, 4>& golden_pixel = *golden_pixel_out;
449     golden_pixel[0] = golden_pixel[1] = golden_pixel[2] = 0.f;
450     golden_pixel[3] = 1.f;
451     switch (golden) {
452         case kRed: golden_pixel[0] = 1.f; break;
453         case kRed50: golden_pixel[0] = 0.5f; golden_pixel[3] = 0.5f; break;
454         case kGreen: golden_pixel[1] = 1.f; break;
455         case kBlue: golden_pixel[2] = 1.f; break;
456         case kZero: golden_pixel[3] = 0.f; break;
457         case kWhite: golden_pixel[0] = 1.f; golden_pixel[1] = 1.f; golden_pixel[2] = 1.f; break;
458         case kBlack: break;
459         default: FAIL() << "Unrecognized golden pixel color";
460     }
461 }
462 
463 // Checks a pixel against a golden pixel of the specified format with the given error bounds.
CheckGoldenPixel(const GoldenPixel & golden,const std::array<uint8_t,4> & pixel,uint32_t format,int32_t max_err)464 void CheckGoldenPixel(const GoldenPixel& golden, const std::array<uint8_t, 4>& pixel,
465                       uint32_t format, int32_t max_err) {
466     std::array<uint8_t, 4> golden_pixel;
467     std::array<uint8_t, 4> golden_max;
468     if (GetGoldenColor(golden.color, format, max_err, &golden_pixel, &golden_max)) {
469         CheckGoldenPixel(golden.x, golden.y, golden_pixel, golden_max, pixel);
470     } else {
471         CheckGoldenPixel(golden.x, golden.y, golden_pixel, pixel);
472     }
473 }
474 
475 // Checks a pixel against a golden pixel of the specified format with no room for error.
CheckGoldenPixel(const GoldenPixel & golden,const std::array<uint8_t,4> & pixel,uint32_t format)476 void CheckGoldenPixel(const GoldenPixel& golden, const std::array<uint8_t, 4>& pixel,
477                       uint32_t format) {
478     CheckGoldenPixel(golden, pixel, format, 0);
479 }
480 
481 // Checks a floating point pixel against a golden pixel.
CheckGoldenPixel(const GoldenPixel & golden,const std::array<float,4> & pixel)482 void CheckGoldenPixel(const GoldenPixel& golden, const std::array<float, 4>& pixel) {
483     std::array<float, 4> golden_pixel;
484     GetGoldenColor(golden.color, &golden_pixel);
485     CheckGoldenPixel(golden.x, golden.y, golden_pixel, pixel);
486 }
487 
488 // Using glReadPixels, reads out the individual pixel values of each golden pixel location, and
489 // compares each against the golden color.
CheckGoldenPixels(const std::vector<GoldenPixel> & goldens,uint32_t format,int16_t max_err=0)490 void CheckGoldenPixels(const std::vector<GoldenPixel>& goldens,
491                        uint32_t format,
492                        int16_t max_err = 0) {
493     // We currently do not test any float formats that don't have alpha.
494     EXPECT_TRUE(FormatIsFloat(format) ? FormatHasAlpha(format) : true);
495     if (FormatIsYuv(format)) {
496         format = GL_RGB8;   // YUV formats are read out as RGB for glReadPixels
497         max_err = 255;      // Conversion method is unknown, so we cannot assume
498                             // anything about the actual colors
499     }
500     glPixelStorei(GL_PACK_ALIGNMENT, 1);
501     // In OpenGL, Y axis grows up, so bottom = minimum Y coordinate.
502     int bottom = INT_MAX, left = INT_MAX, right = 0, top = 0;
503     for (const GoldenPixel& golden : goldens) {
504         left = std::min(left, golden.x);
505         right = std::max(right, golden.x);
506         bottom = std::min(bottom, golden.y);
507         top = std::max(top, golden.y);
508         if (FormatIsFloat(format)) {
509             std::array<float, 4> pixel = {0.5f, 0.5f, 0.5f, 0.5f};
510             glReadPixels(golden.x, golden.y, 1, 1, GL_RGBA, GL_FLOAT, pixel.data());
511             ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()) << "Could not read pixel at " << golden.x << "," << golden.y;
512             CheckGoldenPixel(golden, pixel);
513         } else {
514             std::array<uint8_t, 4> pixel = {127, 127, 127, 127};
515             glReadPixels(golden.x, golden.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel.data());
516             CheckGoldenPixel(golden, pixel, format, max_err);
517         }
518     }
519     // Repeat the test, but read back all the necessary pixels in a single glReadPixels call.
520     const int width = right - left + 1;
521     const int height = top - bottom + 1;
522     if (FormatIsFloat(format)) {
523         std::unique_ptr<float[]> pixels(new float[width * height * 4]);
524         glReadPixels(left, bottom, width, height, GL_RGBA, GL_FLOAT, pixels.get());
525         ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
526         for (const GoldenPixel& golden : goldens) {
527             float* pixel = pixels.get() + ((golden.y - bottom) * width + golden.x - left) * 4;
528             std::array<float, 4> pixel_array;
529             memcpy(pixel_array.data(), pixel, 4 * sizeof(float));
530             CheckGoldenPixel(golden, pixel_array);
531         }
532     } else {
533         std::unique_ptr<uint8_t[]> pixels(new uint8_t[width * height * 4]);
534         glReadPixels(left, bottom, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
535         ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
536         for (const GoldenPixel& golden : goldens) {
537             uint8_t* pixel = pixels.get() + ((golden.y - bottom) * width + golden.x - left) * 4;
538             std::array<uint8_t, 4> pixel_array;
539             memcpy(pixel_array.data(), pixel, 4);
540             CheckGoldenPixel(golden, pixel_array, format, max_err);
541         }
542     }
543 }
544 
545 // Using direct memory access by locking the buffer, accesses the individual pixel values of each
546 // golden pixel location, and compares each against the golden color. This variant works for RGBA
547 // layouts only.
CheckCpuGoldenPixelsRgba(const std::vector<GoldenPixel> & goldens,AHardwareBuffer * buffer,const AHardwareBuffer_Desc & desc)548 void CheckCpuGoldenPixelsRgba(const std::vector<GoldenPixel>& goldens,
549                               AHardwareBuffer* buffer,
550                               const AHardwareBuffer_Desc& desc) {
551     void* data = nullptr;
552     int result = AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1, nullptr,
553                                       &data);
554     ASSERT_EQ(NO_ERROR, result) << "AHardwareBuffer_lock failed with error " << result;
555     for (const GoldenPixel& golden : goldens) {
556         ptrdiff_t row_offset = golden.y * desc.stride;
557         switch (desc.format) {
558             case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
559             case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: {
560                 uint8_t* pixel = reinterpret_cast<uint8_t*>(data) + (row_offset + golden.x) * 4;
561                 std::array<uint8_t, 4> pixel_to_check;
562                 memcpy(pixel_to_check.data(), pixel, 4);
563                 if (desc.format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM) {
564                     pixel_to_check[3] = 255;
565                 }
566                 CheckGoldenPixel(golden, pixel_to_check, desc.format);
567                 break;
568             }
569             case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM: {
570                 uint8_t* pixel = reinterpret_cast<uint8_t*>(data) + (row_offset + golden.x) * 3;
571                 std::array<uint8_t, 4> pixel_to_check;
572                 memcpy(pixel_to_check.data(), pixel, 3);
573                 pixel_to_check[3] = 255;
574                 CheckGoldenPixel(golden, pixel_to_check, desc.format);
575                 break;
576             }
577             case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: {
578                 uint16_t* pixel = reinterpret_cast<uint16_t*>(
579                     reinterpret_cast<uint8_t*>(data) + (row_offset + golden.x) * 2);
580                 std::array<uint8_t, 4> pixel_to_check = {
581                     static_cast<uint8_t>(((*pixel & 0xF800) >> 11) * (255./31.)),
582                     static_cast<uint8_t>(((*pixel & 0x07E0) >> 5) * (255./63.)),
583                     static_cast<uint8_t>((*pixel & 0x001F) * (255./31.)),
584                     255,
585                 };
586                 CheckGoldenPixel(golden, pixel_to_check, desc.format);
587                 break;
588             }
589             case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT: {
590                 uint16_t* pixel = reinterpret_cast<uint16_t*>(
591                     reinterpret_cast<uint8_t*>(data) + (row_offset + golden.x) * 8);
592                 std::array<float, 4> pixel_to_check;
593                 for (int i = 0; i < 4; ++i) {
594                     pixel_to_check[i] = FloatFromHalf(pixel[i]);
595                 }
596                 CheckGoldenPixel(golden, pixel_to_check);
597                 break;
598             }
599             case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM: {
600                 uint32_t* pixel = reinterpret_cast<uint32_t*>(
601                     reinterpret_cast<uint8_t*>(data) + (row_offset + golden.x) * 4);
602                 std::array<uint8_t, 4> pixel_to_check = {
603                     static_cast<uint8_t>((*pixel & 0x000003FF) * (255./1023.)),
604                     static_cast<uint8_t>(((*pixel & 0x000FFC00) >> 10) * (255./1023.)),
605                     static_cast<uint8_t>(((*pixel & 0x3FF00000) >> 20) * (255./1023.)),
606                     static_cast<uint8_t>(((*pixel & 0xC0000000) >> 30) * (255./3.)),
607                 };
608                 CheckGoldenPixel(golden, pixel_to_check, desc.format);
609                 break;
610             }
611             default: FAIL() << "Unrecognized AHardwareBuffer format"; break;
612         }
613     }
614     AHardwareBuffer_unlock(buffer, nullptr);
615 }
616 
617 // Using direct memory access by locking the buffer, accesses the individual pixel values of each
618 // golden pixel location, and compares each against the golden color. This variant works for YUV
619 // layouts only.
CheckCpuGoldenPixelsYuv(const std::vector<GoldenPixel> & goldens,AHardwareBuffer * buffer,const AHardwareBuffer_Desc & desc)620 void CheckCpuGoldenPixelsYuv(const std::vector<GoldenPixel>& goldens,
621                              AHardwareBuffer* buffer,
622                              const AHardwareBuffer_Desc& desc) {
623     AHardwareBuffer_Planes planes_info;
624     int result = AHardwareBuffer_lockPlanes(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1,
625                                             nullptr, &planes_info);
626     ASSERT_EQ(NO_ERROR, result) << "AHardwareBuffer_lock failed with error " << result;
627     for (const GoldenPixel& golden : goldens) {
628         switch (desc.format) {
629             case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: {
630                 ASSERT_EQ(3U, planes_info.planeCount) << "Unexpected number of planes in YUV data: "
631                                                       << planes_info.planeCount;
632                 AHardwareBuffer_Plane* planes = planes_info.planes;
633                 ptrdiff_t y_offset = golden.y * planes[0].rowStride
634                                    + golden.x * planes[0].pixelStride;
635                 ptrdiff_t u_offset = (golden.y / 2) * planes[1].rowStride
636                                    + (golden.x / 2) * planes[1].pixelStride;
637                 ptrdiff_t v_offset = (golden.y / 2) * planes[2].rowStride
638                                    + (golden.x / 2) * planes[2].pixelStride;
639                 // Check colors in YUV space (which desc.format is)
640                 std::array<uint8_t, 4> pixel_to_check = {
641                     *(reinterpret_cast<uint8_t*>(planes[0].data) + y_offset),
642                     *(reinterpret_cast<uint8_t*>(planes[1].data) + u_offset),
643                     *(reinterpret_cast<uint8_t*>(planes[2].data) + v_offset),
644                     255
645                 };
646                 CheckGoldenPixel(golden, pixel_to_check, desc.format);
647             }
648             break;
649             default: FAIL() << "Unrecognized AHardwareBuffer format"; break;
650         }
651     }
652     AHardwareBuffer_unlock(buffer, nullptr);
653 }
654 
655 // Using direct memory access by locking the buffer, accesses the individual pixel values of each
656 // golden pixel location, and compares each against the golden color. This variant forwards to the
657 // appropriate RGBA or YUV variants.
CheckCpuGoldenPixels(const std::vector<GoldenPixel> & goldens,AHardwareBuffer * buffer)658 void CheckCpuGoldenPixels(const std::vector<GoldenPixel>& goldens,
659                           AHardwareBuffer* buffer) {
660     AHardwareBuffer_Desc desc;
661     AHardwareBuffer_describe(buffer, &desc);
662     if (FormatIsYuv(desc.format)) {
663         CheckCpuGoldenPixelsYuv(goldens, buffer, desc);
664     } else {
665         CheckCpuGoldenPixelsRgba(goldens, buffer, desc);
666     }
667 }
668 
669 // Draws the following checkerboard pattern using glScissor and glClear.
670 // The number after the color is the stencil value and the floating point number is the depth value.
671 // The pattern is asymmetric to detect coordinate system mixups.
672 //        +-----+-----+ (W, H)
673 //        | OR1 | OB2 |
674 //        | 0.5 | 0.0 |
675 //        +-----+-----+  Tb = transparent black
676 //        | Tb0 | OG3 |  OR = opaque red
677 //        | 1.0 | 1.0 |  OG = opaque green
678 // (0, 0) +-----+-----+  OB = opaque blue
679 //
DrawCheckerboard(int width,int height,uint32_t format)680 void DrawCheckerboard(int width, int height, uint32_t format) {
681     glEnable(GL_SCISSOR_TEST);
682     const GLbitfield all_bits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
683     std::array<uint8_t, 4> color;
684 
685     GetGoldenColor(kZero, format, &color);
686     glClearColor(color[0] / 255.f, color[1] / 255.f, color[2] / 255.f, color[3] / 255.f);
687     glClearDepthf(1.0f);
688     glClearStencil(0);
689     glScissor(0, 0, width, height);
690     glClear(all_bits);
691 
692     GetGoldenColor(kRed, format, &color);
693     glClearColor(color[0] / 255.f, color[1] / 255.f, color[2] / 255.f, color[3] / 255.f);
694     glClearDepthf(0.5f);
695     glClearStencil(1);
696     glScissor(0, height / 2, width / 2, height / 2);
697     glClear(all_bits);
698 
699     GetGoldenColor(kGreen, format, &color);
700     glClearColor(color[0] / 255.f, color[1] / 255.f, color[2] / 255.f, color[3] / 255.f);
701     glClearDepthf(1.0f);
702     glClearStencil(3);
703     glScissor(width / 2, 0, width / 2, height / 2);
704     glClear(all_bits);
705 
706     GetGoldenColor(kBlue, format, &color);
707     glClearColor(color[0] / 255.f, color[1] / 255.f, color[2] / 255.f, color[3] / 255.f);
708     glClearDepthf(0.f);
709     glClearStencil(2);
710     glScissor(width / 2, height / 2, width / 2, height / 2);
711     glClear(all_bits);
712 
713     glDisable(GL_SCISSOR_TEST);
714     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
715 }
716 
717 // Using direct memory access, writes each specified golden pixel to the correct memory address
718 // inside the given buffer. This variant is compatible with RGBA color buffers only.
WriteGoldenPixelsRgba(AHardwareBuffer * buffer,const AHardwareBuffer_Desc & desc,const std::vector<GoldenPixel> & goldens)719 void WriteGoldenPixelsRgba(AHardwareBuffer* buffer,
720                            const AHardwareBuffer_Desc& desc,
721                            const std::vector<GoldenPixel>& goldens) {
722     void* data = nullptr;
723     int result = AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1, nullptr,
724                                       &data);
725     ASSERT_EQ(NO_ERROR, result) << "AHardwareBuffer_lock failed with error " << result;
726     std::array<uint8_t, 4> golden_color;
727     std::array<float, 4> golden_float;
728     for (const GoldenPixel& golden : goldens) {
729         ptrdiff_t row_offset = golden.y * desc.stride;
730         switch (desc.format) {
731             case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
732             case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: {
733                 uint8_t* pixel = reinterpret_cast<uint8_t*>(data) + (row_offset + golden.x) * 4;
734                 GetGoldenColor(golden.color, desc.format, &golden_color);
735                 memcpy(pixel, golden_color.data(), 4);
736                 break;
737             }
738             case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM: {
739                 uint8_t* pixel = reinterpret_cast<uint8_t*>(data) + (row_offset + golden.x) * 3;
740                 GetGoldenColor(golden.color, desc.format, &golden_color);
741                 memcpy(pixel, golden_color.data(), 3);
742                 break;
743             }
744             case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: {
745                 uint16_t* pixel = reinterpret_cast<uint16_t*>(
746                     reinterpret_cast<uint8_t*>(data) + (row_offset + golden.x) * 2);
747                 GetGoldenColor(golden.color, desc.format, &golden_color);
748                 uint16_t golden_565 =
749                     static_cast<uint8_t>(golden_color[0] * (31./255.)) << 11
750                     | static_cast<uint8_t>(golden_color[1] * (63./255.)) << 5
751                     | static_cast<uint8_t>(golden_color[2] * (31./255.));
752                 *pixel = golden_565;
753                 break;
754             }
755             case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT: {
756                 uint16_t* pixel = reinterpret_cast<uint16_t*>(
757                     reinterpret_cast<uint8_t*>(data) + (row_offset + golden.x) * 8);
758                 GetGoldenColor(golden.color, &golden_float);
759                 for (int i = 0; i < 4; ++i) {
760                     pixel[i] = HalfFromFloat(golden_float[i]);
761                 }
762                 break;
763             }
764             case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM: {
765                 uint32_t* pixel = reinterpret_cast<uint32_t*>(
766                     reinterpret_cast<uint8_t*>(data) + (row_offset + golden.x) * 4);
767                 GetGoldenColor(golden.color, desc.format, &golden_color);
768                 uint32_t golden_10102 =
769                     static_cast<uint16_t>(golden_color[0] * (1023./255.))
770                     | static_cast<uint16_t>(golden_color[1] * (1023./255.)) << 10
771                     | static_cast<uint16_t>(golden_color[2] * (1023./255.)) << 20
772                     | static_cast<uint16_t>(golden_color[3] * (3./255.)) << 30;
773                 *pixel = golden_10102;
774                 break;
775             }
776             default: FAIL() << "Unrecognized AHardwareBuffer format"; break;
777         }
778     }
779     AHardwareBuffer_unlock(buffer, nullptr);
780 }
781 
782 // Using direct memory access, writes each specified golden pixel to the correct memory address
783 // inside the given buffer. This variant is compatible with YUV color buffers only.
WriteGoldenPixelsYuv(AHardwareBuffer * buffer,const AHardwareBuffer_Desc & desc,const std::vector<GoldenPixel> & goldens)784 void WriteGoldenPixelsYuv(AHardwareBuffer* buffer,
785                           const AHardwareBuffer_Desc& desc,
786                           const std::vector<GoldenPixel>& goldens) {
787     AHardwareBuffer_Planes planes_info;
788     int result = AHardwareBuffer_lockPlanes(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1,
789                                             nullptr, &planes_info);
790     ASSERT_EQ(NO_ERROR, result) << "AHardwareBuffer_lock failed with error " << result;
791     std::array<uint8_t, 4> golden_color;
792     for (const GoldenPixel& golden : goldens) {
793         switch (desc.format) {
794             case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: {
795                 ASSERT_EQ(3U, planes_info.planeCount) << "Unexpected number of planes in YUV data: "
796                                                       << planes_info.planeCount;
797                 AHardwareBuffer_Plane* planes = planes_info.planes;
798 
799                 ptrdiff_t y_offset = golden.y * planes[0].rowStride
800                                    + golden.x * planes[0].pixelStride;
801                 ptrdiff_t u_offset = (golden.y / 2) * planes[1].rowStride
802                                    + (golden.x / 2) * planes[1].pixelStride;
803                 ptrdiff_t v_offset = (golden.y / 2) * planes[2].rowStride
804                                    + (golden.x / 2) * planes[2].pixelStride;
805 
806                 GetGoldenColor(golden.color, desc.format, &golden_color);
807                 uint8_t* const y_ptr = reinterpret_cast<uint8_t*>(planes[0].data) + y_offset;
808                 uint8_t* const u_ptr = reinterpret_cast<uint8_t*>(planes[1].data) + u_offset;
809                 uint8_t* const v_ptr = reinterpret_cast<uint8_t*>(planes[2].data) + v_offset;
810                 *y_ptr = golden_color[0];
811                 *u_ptr = golden_color[1];
812                 *v_ptr = golden_color[2];
813             }
814             break;
815             default: FAIL() << "Unrecognized AHardwareBuffer format"; break;
816         }
817     }
818     AHardwareBuffer_unlock(buffer, nullptr);
819 }
820 
821 // Writes the following checkerboard pattern directly to a buffer.
822 // The pattern is asymmetric to detect coordinate system mixups.
823 //        +-----+-----+ (W, H)
824 //        | OR  | OB  |
825 //        |     |     |
826 //        +-----+-----+  Tb = transparent black
827 //        | Tb  | OG  |  OR = opaque red
828 //        |     |     |  OG = opaque green
829 // (0, 0) +-----+-----+  OB = opaque blue
830 //
WriteCheckerBoard(AHardwareBuffer * buffer)831 void WriteCheckerBoard(AHardwareBuffer* buffer) {
832     AHardwareBuffer_Desc desc;
833     AHardwareBuffer_describe(buffer, &desc);
834 
835     // Write golden values in same manner as checkerboard on GPU
836     std::vector<GoldenPixel> goldens(desc.width * desc.height);
837     const uint32_t h2 = desc.height / 2;
838     const uint32_t w2 = desc.width / 2;
839     for (uint32_t y = h2; y < desc.height; ++y) {
840         for (uint32_t x = 0; x < w2; ++x) {
841             const uint32_t offset = y * desc.width + x;
842             goldens[offset].x = x;
843             goldens[offset].y = y;
844             goldens[offset].color = kRed;
845         }
846     }
847     for (uint32_t y = h2; y < desc.height; ++y) {
848         for (uint32_t x = w2; x < desc.width; ++x) {
849             const uint32_t offset = y * desc.width + x;
850             goldens[offset].x = x;
851             goldens[offset].y = y;
852             goldens[offset].color = kBlue;
853         }
854     }
855     for (uint32_t y = 0; y < h2; ++y) {
856         for (uint32_t x = 0; x < w2; ++x) {
857             const uint32_t offset = y * desc.width + x;
858             goldens[offset].x = x;
859             goldens[offset].y = y;
860             goldens[offset].color = kZero;
861         }
862     }
863     for (uint32_t y = 0; y < h2; ++y) {
864         for (uint32_t x = w2; x < desc.width; ++x) {
865             const uint32_t offset = y * desc.width + x;
866             goldens[offset].x = x;
867             goldens[offset].y = y;
868             goldens[offset].color = kGreen;
869         }
870     }
871 
872     if (FormatIsYuv(desc.format)) {
873         WriteGoldenPixelsYuv(buffer, desc, goldens);
874     } else {
875         WriteGoldenPixelsRgba(buffer, desc, goldens);
876     }
877 }
878 
879 const char* kVertexShader = R"glsl(#version 100
880     attribute vec2 aPosition;
881     attribute float aDepth;
882     uniform mediump float uScale;
883     varying mediump vec2 vTexCoords;
884     void main() {
885         vTexCoords = (vec2(1.0) + aPosition) * 0.5;
886         gl_Position.xy = aPosition * uScale;
887         gl_Position.z = aDepth;
888         gl_Position.w = 1.0;
889     }
890 )glsl";
891 
892 const char* kTextureFragmentShader = R"glsl(#version 100
893     precision mediump float;
894     varying mediump vec2 vTexCoords;
895     uniform lowp sampler2D uTexture;
896     void main() {
897         gl_FragColor = texture2D(uTexture, vTexCoords);
898     }
899 )glsl";
900 
901 const char* kExternalTextureFragmentShader = R"glsl(#version 100
902     #extension GL_OES_EGL_image_external : require
903     precision mediump float;
904     varying mediump vec2 vTexCoords;
905     uniform samplerExternalOES uTexture;
906     void main() {
907         gl_FragColor = texture2D(uTexture, vTexCoords);
908     }
909 )glsl";
910 
911 const char* kYuvTextureFragmentShader = R"glsl(#version 300 es
912     #extension GL_EXT_YUV_target : require
913     precision mediump float;
914     uniform __samplerExternal2DY2YEXT uTexture;
915     in vec2 vTexCoords;
916     out vec4 outColor;
917     void main() {
918         vec3 srcYuv = texture(uTexture, vTexCoords).xyz;
919         outColor = vec4(yuv_2_rgb(srcYuv, itu_601), 1.0);
920     }
921 )glsl";
922 
923 const char* kCubeMapFragmentShader = R"glsl(#version 100
924     precision mediump float;
925     varying mediump vec2 vTexCoords;
926     uniform lowp samplerCube uTexture;
927     uniform mediump vec3 uFaceVector;
928     void main() {
929         vec2 scaledTexCoords = (2.0 * vTexCoords) - vec2(1.0);
930         vec3 coords = uFaceVector;
931         if (uFaceVector.x > 0.0) {
932             coords.z = -scaledTexCoords.x;
933             coords.y = -scaledTexCoords.y;
934         }
935         if (uFaceVector.x < 0.0) {
936             coords.z = scaledTexCoords.x;
937             coords.y = -scaledTexCoords.y;
938         }
939         if (uFaceVector.y > 0.0) {
940             coords.x = scaledTexCoords.x;
941             coords.z = scaledTexCoords.y;
942         }
943         if (uFaceVector.y < 0.0) {
944             coords.x = scaledTexCoords.x;
945             coords.z = -scaledTexCoords.y;
946         }
947         if (uFaceVector.z > 0.0) {
948             coords.x = scaledTexCoords.x;
949             coords.y = -scaledTexCoords.y;
950         }
951         if (uFaceVector.z < 0.0) {
952             coords.x = -scaledTexCoords.x;
953             coords.y = -scaledTexCoords.y;
954         }
955         gl_FragColor = textureCube(uTexture, coords);
956     }
957 )glsl";
958 
959 const char* kColorFragmentShader = R"glsl(#version 100
960     precision mediump float;
961     uniform lowp vec4 uColor;
962     void main() {
963         gl_FragColor = uColor;
964     }
965 )glsl";
966 
967 const char* kVertexShaderEs3x = R"glsl(
968     in vec2 aPosition;
969     in float aDepth;
970     uniform mediump float uScale;
971     out mediump vec2 vTexCoords;
972     void main() {
973         vTexCoords = (vec2(1.0) + aPosition) * 0.5;
974         gl_Position.xy = aPosition * uScale;
975         gl_Position.z = aDepth;
976         gl_Position.w = 1.0;
977     }
978 )glsl";
979 
980 const char* kSsboComputeShaderEs31 = R"glsl(#version 310 es
981     layout(local_size_x = 1) in;
982     layout(std430, binding=0) buffer Output {
983         uint data[];
984     } bOutput;
985     void main() {
986         bOutput.data[gl_GlobalInvocationID.x] =
987             gl_GlobalInvocationID.x * 3u;
988     }
989 )glsl";
990 
991 const char* kArrayFragmentShaderEs30 = R"glsl(#version 300 es
992     precision mediump float;
993     in mediump vec2 vTexCoords;
994     uniform lowp sampler2DArray uTexture;
995     uniform mediump float uLayer;
996     out mediump vec4 color;
997     void main() {
998         color = texture(uTexture, vec3(vTexCoords, uLayer));
999     }
1000 )glsl";
1001 
1002 const char* kCubeMapArrayFragmentShaderEs32 = R"glsl(#version 320 es
1003     precision mediump float;
1004     in mediump vec2 vTexCoords;
1005     uniform lowp samplerCubeArray uTexture;
1006     uniform mediump float uLayer;
1007     uniform mediump vec3 uFaceVector;
1008     out mediump vec4 color;
1009     void main() {
1010         vec2 scaledTexCoords = (2.0 * vTexCoords) - vec2(1.0);
1011         vec4 coords = vec4(uFaceVector, uLayer);
1012         if (uFaceVector.x > 0.0) {
1013             coords.z = -scaledTexCoords.x;
1014             coords.y = -scaledTexCoords.y;
1015         }
1016         if (uFaceVector.x < 0.0) {
1017             coords.z = scaledTexCoords.x;
1018             coords.y = -scaledTexCoords.y;
1019         }
1020         if (uFaceVector.y > 0.0) {
1021             coords.x = scaledTexCoords.x;
1022             coords.z = scaledTexCoords.y;
1023         }
1024         if (uFaceVector.y < 0.0) {
1025             coords.x = scaledTexCoords.x;
1026             coords.z = -scaledTexCoords.y;
1027         }
1028         if (uFaceVector.z > 0.0) {
1029             coords.x = scaledTexCoords.x;
1030             coords.y = -scaledTexCoords.y;
1031         }
1032         if (uFaceVector.z < 0.0) {
1033             coords.x = -scaledTexCoords.x;
1034             coords.y = -scaledTexCoords.y;
1035         }
1036         color = texture(uTexture, coords);
1037     }
1038 )glsl";
1039 
1040 const char* kStencilFragmentShaderEs30 = R"glsl(#version 300 es
1041     precision mediump float;
1042     in mediump vec2 vTexCoords;
1043     uniform lowp usampler2D uTexture;
1044     out mediump vec4 color;
1045     void main() {
1046         uvec4 stencil = texture(uTexture, vTexCoords);
1047         color.r = stencil.x == 1u ? 1.0 : 0.0;
1048         color.g = stencil.x == 3u ? 1.0 : 0.0;
1049         color.b = stencil.x == 2u ? 1.0 : 0.0;
1050         color.a = stencil.x == 0u ? 0.0 : 1.0;
1051     }
1052 )glsl";
1053 
1054 const char* kStencilArrayFragmentShaderEs30 = R"glsl(#version 300 es
1055     precision mediump float;
1056     in mediump vec2 vTexCoords;
1057     uniform lowp usampler2DArray uTexture;
1058     uniform mediump float uLayer;
1059     out mediump vec4 color;
1060     void main() {
1061         uvec4 stencil = texture(uTexture, vec3(vTexCoords, uLayer));
1062         color.r = stencil.x == 1u ? 1.0 : 0.0;
1063         color.g = stencil.x == 3u ? 1.0 : 0.0;
1064         color.b = stencil.x == 2u ? 1.0 : 0.0;
1065         color.a = stencil.x == 0u ? 0.0 : 1.0;
1066     }
1067 )glsl";
1068 
GetTextureVertexShader(uint32_t format,uint32_t flags)1069 std::string GetTextureVertexShader(uint32_t format, uint32_t flags) {
1070     return FormatIsYuv(format) && (flags & kExplicitYuvSampling)
1071         ? std::string("#version 300 es") + kVertexShaderEs3x
1072         : kVertexShader;
1073 }
1074 
GetTextureFragmentShader(uint32_t format,uint32_t flags)1075 std::string GetTextureFragmentShader(uint32_t format, uint32_t flags) {
1076     return FormatIsYuv(format)
1077         ? ((flags & kExplicitYuvSampling)
1078             ? kYuvTextureFragmentShader
1079             : kExternalTextureFragmentShader)
1080         : kTextureFragmentShader;
1081 }
1082 
GetMaxExpectedColorError(uint32_t format,uint32_t flags)1083 uint32_t GetMaxExpectedColorError(uint32_t format, uint32_t flags) {
1084     // If format is YUV, and we have no explicit sampling, then we do not
1085     // know how the color will be converted (spec is not specific), and the
1086     // maximum error allows for any value. We do not want to abort the test
1087     // as we still want to ensure rendering and read-outs succeed.
1088     // If we use explicit sampling, then we know the conversion method
1089     // (BT.601), but account for some imprecision (2).
1090     // Otherwise, we do not allow any deviation from the expected value.
1091     return FormatIsYuv(format)
1092         ? ((flags & kExplicitYuvSampling) ? 2 : 255)
1093         : 0;
1094 }
1095 
1096 // Interleaved X and Y coordinates for 2 triangles forming a quad with CCW
1097 // orientation.
1098 const float kQuadPositions[] = {
1099     -1.f, -1.f, 1.f, 1.f, -1.f, 1.f,
1100     -1.f, -1.f, 1.f, -1.f, 1.f, 1.f,
1101 };
1102 const GLsizei kQuadVertexCount = 6;
1103 
1104 // Interleaved X, Y and Z coordinates for 4 triangles forming a "pyramid" as
1105 // seen from above. The center vertex has Z=1, while the edge vertices have Z=-1.
1106 // It looks like this:
1107 //
1108 //        +---+ 1, 1
1109 //        |\ /|
1110 //        | x |
1111 //        |/ \|
1112 // -1, -1 +---+
1113 const float kPyramidPositions[] = {
1114     -1.f, -1.f, -1.f, 0.f, 0.f, 1.f, -1.f, 1.f, -1.f,
1115     -1.f, 1.f, -1.f, 0.f, 0.f, 1.f, 1.f, 1.f, -1.f,
1116     1.f, 1.f, -1.f, 0.f, 0.f, 1.f, 1.f, -1.f, -1.f,
1117     1.f, -1.f, -1.f, 0.f, 0.f, 1.f, -1.f, -1.f, -1.f,
1118 };
1119 const GLsizei kPyramidVertexCount = 12;
1120 
1121 }  // namespace
1122 
1123 class AHardwareBufferGLTest : public ::testing::TestWithParam<AHardwareBuffer_Desc> {
1124 public:
1125     enum AttachmentType {
1126         kNone,
1127         kBufferAsTexture,
1128         kBufferAsRenderbuffer,
1129         kRenderbuffer,
1130     };
1131 
1132     void SetUp() override;
1133     virtual bool SetUpBuffer(const AHardwareBuffer_Desc& desc);
1134     void SetUpProgram(const std::string& vertex_source, const std::string& fragment_source,
1135                       const float* mesh, float scale, int texture_unit = 0);
1136     void SetUpTexture(const AHardwareBuffer_Desc& desc, int unit);
1137     void SetUpBufferObject(uint32_t size, GLenum target, GLbitfield flags);
1138     void SetUpFramebuffer(int width, int height, int layer, AttachmentType color,
1139                           AttachmentType depth = kNone, AttachmentType stencil = kNone,
1140                           AttachmentType depth_stencil = kNone, int level = 0);
1141     void TearDown() override;
1142 
MakeCurrent(int which)1143     void MakeCurrent(int which) {
1144         if (GetParam().stride & kGlFormat) return;
1145         mWhich = which;
1146         eglMakeCurrent(mDisplay, mSurface, mSurface, mContext[mWhich]);
1147     }
MakeCurrentNone()1148     void MakeCurrentNone() {
1149         eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1150     }
HasEGLExtension(const std::string & s)1151     bool HasEGLExtension(const std::string& s) {
1152         return mEGLExtensions.find(s) != mEGLExtensions.end();
1153     }
HasGLExtension(const std::string & s)1154     bool HasGLExtension(const std::string& s) {
1155         return mGLExtensions.find(s) != mGLExtensions.end();
1156     }
IsFormatColorRenderable(uint32_t format,bool use_srgb)1157     bool IsFormatColorRenderable(uint32_t format, bool use_srgb) {
1158         if (use_srgb) {
1159             // According to the spec, GL_SRGB8 is not color-renderable.
1160             return format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM || format == GL_SRGB8_ALPHA8;
1161         } else {
1162             if (format == GL_RGBA16F || format == AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT) {
1163                 return mGLVersion >= 32 || HasGLExtension("GL_EXT_color_buffer_float");
1164             }
1165             return true;
1166         }
1167     }
1168 
1169 protected:
1170     std::set<std::string> mEGLExtensions;
1171     std::set<std::string> mGLExtensions;
1172     EGLDisplay mDisplay = EGL_NO_DISPLAY;
1173     EGLSurface mSurface = EGL_NO_SURFACE;
1174     EGLContext mContext[2] = { EGL_NO_CONTEXT, EGL_NO_CONTEXT };
1175     int mWhich = 0;  // Which of the two EGL contexts is current.
1176     int mContextCount = 2;  // Will be 2 in AHB test cases and 1 in pure GL test cases.
1177     int mGLVersion = 0;  // major_version * 10 + minor_version
1178 
1179     AHardwareBuffer* mBuffer = nullptr;
1180     EGLImageKHR mEGLImage = EGL_NO_IMAGE_KHR;
1181     GLenum mTexTarget = GL_NONE;
1182     GLuint mProgram = 0;
1183     GLint mColorLocation = -1;
1184     GLint mFaceVectorLocation = -1;
1185     GLuint mTextures[2] = { 0, 0 };
1186     GLuint mBufferObjects[2] = { 0, 0 };
1187     GLuint mFramebuffers[2] = { 0, 0 };
1188     GLint mMaxTextureUnits = 0;
1189 };
1190 
SetUp()1191 void AHardwareBufferGLTest::SetUp() {
1192     mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1193     eglInitialize(mDisplay, NULL, NULL);
1194 
1195     // Try creating an OpenGL ES 3.x context and fall back to 2.x if that fails.
1196     // Create two contexts for cross-context image sharing tests.
1197     EGLConfig first_config;
1198     EGLint config_attrib_list[] = {
1199         EGL_RED_SIZE, 8,
1200         EGL_GREEN_SIZE, 8,
1201         EGL_BLUE_SIZE, 8,
1202         EGL_ALPHA_SIZE, 8,
1203         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
1204         EGL_NONE
1205     };
1206     EGLint num_config = 0;
1207     eglChooseConfig(mDisplay, config_attrib_list, &first_config, 1, &num_config);
1208     if (num_config == 0) {
1209         // There are no configs with the ES 3.0 bit, fall back to ES 2.0.
1210         config_attrib_list[8] = EGL_NONE;
1211         config_attrib_list[9] = EGL_NONE;
1212         eglChooseConfig(mDisplay, config_attrib_list, &first_config, 1, &num_config);
1213     }
1214     ASSERT_GT(num_config, 0);
1215 
1216     EGLint context_attrib_list[] = {
1217         EGL_CONTEXT_CLIENT_VERSION, 3,
1218         EGL_NONE
1219     };
1220     // Try creating an ES 3.0 context, but don't bother if there were no ES 3.0 compatible configs.
1221     if (config_attrib_list[9] != EGL_NONE) {
1222         mContext[0] = eglCreateContext(mDisplay, first_config, EGL_NO_CONTEXT, context_attrib_list);
1223     }
1224     // If we don't have a context yet, fall back to ES 2.0.
1225     if (mContext[0] == EGL_NO_CONTEXT) {
1226         context_attrib_list[1] = 2;
1227         mContext[0] = eglCreateContext(mDisplay, first_config, EGL_NO_CONTEXT, context_attrib_list);
1228     }
1229     mContext[1] = eglCreateContext(mDisplay, first_config, EGL_NO_CONTEXT, context_attrib_list);
1230     ASSERT_NE(EGL_NO_CONTEXT, mContext[0]);
1231     ASSERT_NE(EGL_NO_CONTEXT, mContext[1]);
1232 
1233     // Parse EGL extension strings into a set for easier processing.
1234     std::istringstream eglext_stream(eglQueryString(mDisplay, EGL_EXTENSIONS));
1235     mEGLExtensions = std::set<std::string>{
1236         std::istream_iterator<std::string>{eglext_stream},
1237         std::istream_iterator<std::string>{}
1238     };
1239     // Create a 1x1 pbuffer surface if surfaceless contexts are not supported.
1240     if (!HasEGLExtension("EGL_KHR_surfaceless_context")) {
1241         EGLint const surface_attrib_list[] = {
1242             EGL_WIDTH, 1,
1243             EGL_HEIGHT, 1,
1244             EGL_NONE
1245         };
1246         mSurface = eglCreatePbufferSurface(mDisplay, first_config, surface_attrib_list);
1247     }
1248     EGLBoolean result = eglMakeCurrent(mDisplay, mSurface, mSurface, mContext[0]);
1249     ASSERT_EQ(EGLBoolean{EGL_TRUE}, result);
1250 
1251     // Parse GL extension strings into a set for easier processing.
1252     std::istringstream glext_stream(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
1253     mGLExtensions = std::set<std::string>{
1254         std::istream_iterator<std::string>{glext_stream},
1255         std::istream_iterator<std::string>{}
1256     };
1257     // Parse GL version. Find the first dot, then treat the digit before it as the major version
1258     // and the digit after it as the minor version.
1259     std::string version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
1260     std::size_t dot_pos = version.find('.');
1261     ASSERT_TRUE(dot_pos > 0 && dot_pos < version.size() - 1);
1262     mGLVersion = (version[dot_pos - 1] - '0') * 10 + (version[dot_pos + 1] - '0');
1263     ASSERT_GE(mGLVersion, 20);
1264     glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxTextureUnits);
1265 }
1266 
SetUpBuffer(const AHardwareBuffer_Desc & desc)1267 bool AHardwareBufferGLTest::SetUpBuffer(const AHardwareBuffer_Desc& desc) {
1268     const bool use_srgb = desc.stride & kUseSrgb;
1269     if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP) {
1270         if (desc.layers > 6) {
1271             if (mGLVersion < 32) {
1272                 ALOGI("Test skipped: cube map arrays require GL ES 3.2, found %d.%d",
1273                       mGLVersion / 10, mGLVersion % 10);
1274                 return false;
1275             }
1276             mTexTarget = GL_TEXTURE_CUBE_MAP_ARRAY;
1277         } else {
1278             mTexTarget = GL_TEXTURE_CUBE_MAP;
1279         }
1280     } else {
1281         if (desc.layers > 1) {
1282             if (mGLVersion < 30) {
1283                 ALOGI("Test skipped: texture arrays require GL ES 3.0, found %d.%d",
1284                       mGLVersion / 10, mGLVersion % 10);
1285                 return false;
1286             }
1287             mTexTarget = GL_TEXTURE_2D_ARRAY;
1288         } else {
1289             if (FormatIsYuv(desc.format)) {
1290                 mTexTarget = GL_TEXTURE_EXTERNAL_OES;
1291             } else {
1292                 mTexTarget = GL_TEXTURE_2D;
1293             }
1294         }
1295     }
1296     if ((desc.format == GL_RGB8 || desc.format == GL_RGBA8) &&
1297         (desc.usage & AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT) &&
1298         mGLVersion < 30 && !HasGLExtension("GL_OES_rgb8_rgba8")) {
1299         ALOGI("Test skipped: GL_RGB8/GL_RGBA8 renderbuffers require GL ES 3.0 or "
1300               "GL_OES_rgb8_rgba8, but neither were found.");
1301         return false;
1302     }
1303     if (desc.format == GL_SRGB8_ALPHA8 && mGLVersion < 30 &&
1304         !HasGLExtension("GL_EXT_sRGB")) {
1305         ALOGI("Test skipped: GL_SRGB8_ALPHA8 requires GL ES 3.0 or GL_EXT_sRGB, "
1306               "but neither were found.");
1307         return false;
1308     }
1309     if (desc.format == GL_RGB10_A2 && mGLVersion < 30) {
1310         ALOGI("Test skipped: GL_RGB10_A2 requires GL ES 3.0, found %d.%d",
1311               mGLVersion / 10, mGLVersion % 10);
1312         return false;
1313     }
1314     if (desc.format == GL_RGBA16F && mGLVersion < 30) {
1315         ALOGI("Test skipped: GL_RGBA16F requires GL ES 3.0, found %d.%d",
1316               mGLVersion / 10, mGLVersion % 10);
1317         return false;
1318     }
1319     if (desc.format == GL_DEPTH_COMPONENT16 &&
1320         (desc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) &&
1321         mGLVersion < 30 && !HasGLExtension("GL_OES_depth_texture")) {
1322         ALOGI("Test skipped: depth textures require GL ES 3.0 or "
1323               "GL_OES_depth_texture, but neither were found.");
1324         return false;
1325     }
1326     if (desc.format == GL_DEPTH24_STENCIL8 &&
1327         (desc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) &&
1328         mGLVersion < 30 && !HasGLExtension("GL_OES_packed_depth_stencil")) {
1329         ALOGI("Test skipped: depth-stencil textures require GL ES 3.0 or "
1330               "GL_OES_packed_depth_stencil, but neither were found.");
1331         return false;
1332     }
1333     if (mTexTarget == GL_TEXTURE_EXTERNAL_OES &&
1334         (desc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) &&
1335         !HasGLExtension("GL_OES_EGL_image_external")) {
1336         ALOGI("Test skipped: External textures are not supported but required "
1337               "by this test.");
1338         return false;
1339     }
1340     if (FormatIsYuv(desc.format) && !HasGLExtension("GL_EXT_YUV_target")) {
1341         ALOGI("Test skipped: The GL_EXT_YUV_target extension is required for "
1342               "operations in the YUV color space.");
1343         return false;
1344     }
1345     // For control cases using GL formats, the test should be run in a single
1346     // context, without using AHardwareBuffer. This simplifies verifying that
1347     // the test behaves as expected even if the AHardwareBuffer format under
1348     // test is not supported.
1349     if (desc.stride & kGlFormat) {
1350         mContextCount = 1;
1351         return true;
1352     }
1353 
1354     // The code below will only execute if we are allocating a real AHardwareBuffer.
1355     if (use_srgb && !HasEGLExtension("EGL_EXT_image_gl_colorspace")) {
1356         ALOGI("Test skipped: sRGB hardware buffers require EGL_EXT_image_gl_colorspace");
1357         return false;
1358     }
1359     if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP &&
1360         !HasGLExtension("GL_EXT_EGL_image_storage")) {
1361         ALOGI("Test skipped: cube map array hardware buffers require "
1362               "GL_EXT_EGL_image_storage");
1363         return false;
1364     }
1365     if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE &&
1366         !HasGLExtension("GL_EXT_EGL_image_storage")) {
1367         ALOGI("Test skipped: mipmapped hardware buffers require "
1368               "GL_EXT_EGL_image_storage");
1369         return false;
1370     }
1371 
1372     int result = AHardwareBuffer_allocate(&desc, &mBuffer);
1373 
1374     ALOGI("Attempting to allocate format=%s width=%d height=%d layers=%d result=%d",
1375         AHBFormatAsString(desc.format), desc.width, desc.height, desc.layers, result);
1376 
1377     // Skip if this format cannot be allocated.
1378     if (result != NO_ERROR) {
1379         EXPECT_FALSE(AHardwareBuffer_isSupported(&desc)) <<
1380             "AHardwareBuffer_isSupported returned true, but buffer allocation failed. "
1381             "Potential gralloc bug or resource exhaustion.";
1382         ALOGI("Test skipped: format %s could not be allocated",
1383               AHBFormatAsString(desc.format));
1384         return false;
1385     }
1386     EXPECT_TRUE(AHardwareBuffer_isSupported(&desc)) <<
1387         "AHardwareBuffer_isSupported returned false, but buffer allocation succeeded. "
1388         "This is most likely a bug in the gralloc implementation.";
1389 
1390     // The code below will only execute if allocating an AHardwareBuffer succeeded.
1391     // Fail early if the buffer is mipmapped or a cube map, but the GL extension required
1392     // to actually access it from GL is not present.
1393     if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP &&
1394         !HasGLExtension("GL_EXT_EGL_image_storage")) {
1395         ADD_FAILURE() << "Cube map AHardwareBuffer allocation succeeded, but the extension "
1396             "GL_EXT_EGL_image_storage is not present";
1397         return false;
1398     }
1399     if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE &&
1400             !HasGLExtension("GL_EXT_EGL_image_storage")) {
1401         ADD_FAILURE() << "Mipmapped AHardwareBuffer allocation succeeded, but the extension "
1402             "GL_EXT_EGL_image_storage is not present";
1403         return false;
1404     }
1405 
1406     // Do not create the EGLImage if this is a blob format.
1407     if (desc.format == AHARDWAREBUFFER_FORMAT_BLOB) return true;
1408 
1409     EXPECT_TRUE(HasEGLExtension("EGL_ANDROID_image_native_buffer"));
1410 
1411     EGLint attrib_list[3] = { EGL_NONE, EGL_NONE, EGL_NONE };
1412     if (use_srgb) {
1413         attrib_list[0] = EGL_GL_COLORSPACE_KHR;
1414         attrib_list[1] = EGL_GL_COLORSPACE_SRGB_KHR;
1415     }
1416     mEGLImage = eglCreateImageKHR(
1417         mDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
1418         eglGetNativeClientBufferANDROID(mBuffer), attrib_list);
1419     EXPECT_NE(EGL_NO_IMAGE_KHR, mEGLImage) <<
1420         "AHardwareBuffer allocation succeeded, but binding it to an EGLImage failed. "
1421         "This is usually caused by a version mismatch between the gralloc implementation and "
1422         "the OpenGL/EGL driver. Please contact your GPU vendor to resolve this problem.";
1423     return mEGLImage != EGL_NO_IMAGE_KHR;
1424 }
1425 
SetUpProgram(const std::string & vertex_source,const std::string & fragment_source,const float * mesh,float scale,int texture_unit)1426 void AHardwareBufferGLTest::SetUpProgram(const std::string& vertex_source,
1427                                          const std::string& fragment_source,
1428                                          const float* mesh, float scale, int texture_unit) {
1429     ASSERT_EQ(0U, mProgram);
1430     GLint status = GL_FALSE;
1431     mProgram = glCreateProgram();
1432     GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
1433     const char* vertex_source_cstr = vertex_source.c_str();
1434     glShaderSource(vertex_shader, 1, &vertex_source_cstr, nullptr);
1435     glCompileShader(vertex_shader);
1436     glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &status);
1437     ASSERT_EQ(GL_TRUE, status) << "Vertex shader compilation failed";
1438     GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
1439     const char* fragment_source_cstr = fragment_source.c_str();
1440     glShaderSource(fragment_shader, 1, &fragment_source_cstr, nullptr);
1441     glCompileShader(fragment_shader);
1442     glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &status);
1443     ASSERT_EQ(GL_TRUE, status) << "Fragment shader compilation failed";
1444     glAttachShader(mProgram, vertex_shader);
1445     glAttachShader(mProgram, fragment_shader);
1446     glLinkProgram(mProgram);
1447     glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
1448     ASSERT_EQ(GL_TRUE, status) << "Shader program linking failed";
1449     glDetachShader(mProgram, vertex_shader);
1450     glDetachShader(mProgram, fragment_shader);
1451     glDeleteShader(vertex_shader);
1452     glDeleteShader(fragment_shader);
1453     glUseProgram(mProgram);
1454     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()) << "GL error during shader program setup";
1455 
1456     GLint a_position_location = glGetAttribLocation(mProgram, "aPosition");
1457     GLint a_depth_location = glGetAttribLocation(mProgram, "aDepth");
1458     if (mesh == kQuadPositions) {
1459         glVertexAttribPointer(a_position_location, 2, GL_FLOAT, GL_TRUE, 0, kQuadPositions);
1460         glVertexAttrib1f(a_depth_location, 0.f);
1461         glEnableVertexAttribArray(a_position_location);
1462     } else if (mesh == kPyramidPositions) {
1463         glVertexAttribPointer(a_position_location, 2, GL_FLOAT, GL_TRUE, 3 * sizeof(float),
1464                               kPyramidPositions);
1465         glVertexAttribPointer(a_depth_location, 1, GL_FLOAT, GL_TRUE, 3 * sizeof(float),
1466                               kPyramidPositions + 2);
1467         glEnableVertexAttribArray(a_position_location);
1468         glEnableVertexAttribArray(a_depth_location);
1469     } else {
1470         FAIL() << "Unknown mesh";
1471     }
1472     glUniform1f(glGetUniformLocation(mProgram, "uScale"), scale);
1473     mColorLocation = glGetUniformLocation(mProgram, "uColor");
1474     if (mColorLocation >= 0) {
1475         glUniform4f(mColorLocation, 1.f, 0.f, 0.f, 1.f);
1476     }
1477     GLint u_texture_location = glGetUniformLocation(mProgram, "uTexture");
1478     if (u_texture_location >= 0) {
1479         glUniform1i(u_texture_location, texture_unit);
1480     }
1481     GLint u_layer_location = glGetUniformLocation(mProgram, "uLayer");
1482     if (u_layer_location >= 0) {
1483         glUniform1f(u_layer_location, static_cast<float>(GetParam().layers - 1));
1484     }
1485     mFaceVectorLocation = glGetUniformLocation(mProgram, "uFaceVector");
1486     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()) << "GL error during shader uniform setup";
1487 }
1488 
SetUpTexture(const AHardwareBuffer_Desc & desc,int unit)1489 void AHardwareBufferGLTest::SetUpTexture(const AHardwareBuffer_Desc& desc, int unit) {
1490     GLuint& texture = mTextures[mWhich];
1491     glGenTextures(1, &texture);
1492     glActiveTexture(GL_TEXTURE0 + unit);
1493     glBindTexture(mTexTarget, texture);
1494     // If the texture does not have mipmaps, set a filter that does not require them.
1495     if (!(desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)) {
1496         glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1497     }
1498     if (desc.stride & kGlFormat) {
1499         int levels = 1;
1500         if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE) {
1501             levels = MipLevelCount(desc.width, desc.height);
1502         }
1503         // kGlFormat is set in the stride field, so interpret desc.format as a GL format.
1504         if ((desc.usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP) ? desc.layers > 6 : desc.layers > 1) {
1505             glTexStorage3D(mTexTarget, levels, desc.format, desc.width, desc.height, desc.layers);
1506         } else if (mGLVersion >= 30) {
1507             glTexStorage2D(mTexTarget, levels, desc.format, desc.width, desc.height);
1508         } else {
1509             // Compatibility code for ES 2.0 goes here.
1510             GLenum internal_format = 0, format = 0, type = 0;
1511             switch (desc.format) {
1512                 case GL_RGB8:
1513                     internal_format = GL_RGB;
1514                     format = GL_RGB;
1515                     type = GL_UNSIGNED_BYTE;
1516                     break;
1517                 case GL_RGBA8:
1518                     internal_format = GL_RGBA;
1519                     format = GL_RGBA;
1520                     type = GL_UNSIGNED_BYTE;
1521                     break;
1522                 case GL_SRGB8_ALPHA8:
1523                     // Available through GL_EXT_sRGB.
1524                     internal_format = GL_SRGB_ALPHA_EXT;
1525                     format = GL_RGBA;
1526                     type = GL_UNSIGNED_BYTE;
1527                     break;
1528                 case GL_RGB565:
1529                     internal_format = GL_RGB;
1530                     format = GL_RGB;
1531                     type = GL_UNSIGNED_SHORT_5_6_5;
1532                     break;
1533                 case GL_DEPTH_COMPONENT16:
1534                     // Available through GL_OES_depth_texture.
1535                     // Note that these are treated as luminance textures, not as red textures.
1536                     internal_format = GL_DEPTH_COMPONENT;
1537                     format = GL_DEPTH_COMPONENT;
1538                     type = GL_UNSIGNED_SHORT;
1539                     break;
1540                 case GL_DEPTH24_STENCIL8:
1541                     // Available through GL_OES_packed_depth_stencil.
1542                     internal_format = GL_DEPTH_STENCIL_OES;
1543                     format = GL_DEPTH_STENCIL;
1544                     type = GL_UNSIGNED_INT_24_8;
1545                     break;
1546                 default:
1547                     FAIL() << "Unrecognized GL format"; break;
1548             }
1549             if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP) {
1550                 for (int face = 0; face < 6; ++face) {
1551                     uint32_t width = desc.width;
1552                     uint32_t height = desc.height;
1553                     for (int level = 0; level < levels; ++level) {
1554                         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, internal_format,
1555                                      width, height, 0, format, type, nullptr);
1556                         width /= 2;
1557                         height /= 2;
1558                     }
1559                 }
1560             } else {
1561                 uint32_t width = desc.width;
1562                 uint32_t height = desc.height;
1563                 for (int level = 0; level < levels; ++level) {
1564                     glTexImage2D(mTexTarget, level, internal_format, width, height, 0, format,
1565                                  type, nullptr);
1566                     width /= 2;
1567                     height /= 2;
1568                 }
1569             }
1570         }
1571     } else {
1572         if (HasGLExtension("GL_EXT_EGL_image_storage")) {
1573             glEGLImageTargetTexStorageEXT(mTexTarget, static_cast<GLeglImageOES>(mEGLImage),
1574                                           nullptr);
1575         } else {
1576             glEGLImageTargetTexture2DOES(mTexTarget, static_cast<GLeglImageOES>(mEGLImage));
1577         }
1578     }
1579     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()) << "GL error during texture setup";
1580 }
1581 
SetUpBufferObject(uint32_t size,GLenum target,GLbitfield flags)1582 void AHardwareBufferGLTest::SetUpBufferObject(uint32_t size, GLenum target, GLbitfield flags) {
1583     glGenBuffers(1, &mBufferObjects[mWhich]);
1584     glBindBuffer(target, mBufferObjects[mWhich]);
1585     glBufferStorageExternalEXT(target, 0, size,
1586                                eglGetNativeClientBufferANDROID(mBuffer), flags);
1587     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()) << "GL error during buffer object setup";
1588 }
1589 
SetUpFramebuffer(int width,int height,int layer,AttachmentType color,AttachmentType depth,AttachmentType stencil,AttachmentType depth_stencil,int level)1590 void AHardwareBufferGLTest::SetUpFramebuffer(int width, int height, int layer,
1591                                              AttachmentType color,
1592                                              AttachmentType depth,
1593                                              AttachmentType stencil,
1594                                              AttachmentType depth_stencil,
1595                                              int level) {
1596     AttachmentType attachment_types[] = { color, depth, stencil, depth_stencil };
1597     GLenum attachment_points[] = {
1598         GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT,
1599         GL_DEPTH_STENCIL_ATTACHMENT
1600     };
1601     GLenum default_formats[] = {
1602         GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8, GL_DEPTH24_STENCIL8
1603     };
1604     GLuint& fbo = mFramebuffers[mWhich];
1605     GLbitfield clear_bits[] = {
1606         GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT,
1607         GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT
1608     };
1609 
1610     glClearColor(0.f, 0.f, 0.f, 0.f);
1611     glClearDepthf(1.0f);
1612     glClearStencil(0);
1613     glGenFramebuffers(1, &fbo);
1614     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1615     for (int i = 0; i < 4; ++i) {
1616         switch (attachment_types[i]) {
1617             case kNone:
1618                 break;
1619             case kBufferAsTexture:
1620                 ASSERT_NE(0U, mTextures[mWhich]);
1621                 if (mTexTarget == GL_TEXTURE_2D || mTexTarget == GL_TEXTURE_EXTERNAL_OES) {
1622                     glFramebufferTexture2D(GL_FRAMEBUFFER, attachment_points[i], mTexTarget,
1623                                            mTextures[mWhich], level);
1624                 } else if (mTexTarget == GL_TEXTURE_CUBE_MAP) {
1625                     glFramebufferTexture2D(GL_FRAMEBUFFER, attachment_points[i],
1626                                            GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer,
1627                                            mTextures[mWhich], level);
1628                 } else {
1629                     glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment_points[i],
1630                                               mTextures[mWhich], level, layer);
1631                 }
1632                 break;
1633             case kBufferAsRenderbuffer: {
1634                 ASSERT_EQ(0, layer);
1635                 GLuint renderbuffer = 0;
1636                 glGenRenderbuffers(1, &renderbuffer);
1637                 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
1638                 ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
1639                 bool isGlFormat = GetParam().stride & kGlFormat;
1640                 if (isGlFormat) {
1641                     glRenderbufferStorage(GL_RENDERBUFFER, GetParam().format, width, height);
1642                 } else {
1643                     ASSERT_FALSE(FormatIsYuv(GetParam().format)) << "YUV renderbuffers unsupported";
1644                     glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
1645                                                            static_cast<GLeglImageOES>(mEGLImage));
1646                 }
1647                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i],
1648                                           GL_RENDERBUFFER, renderbuffer);
1649                 if (isGlFormat)
1650                     glClear(clear_bits[i]);
1651                 break;
1652             }
1653             case kRenderbuffer: {
1654                 ASSERT_EQ(0, layer);
1655                 GLuint renderbuffer = 0;
1656                 glGenRenderbuffers(1, &renderbuffer);
1657                 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
1658                 glRenderbufferStorage(GL_RENDERBUFFER, default_formats[i], width, height);
1659                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i],
1660                                           GL_RENDERBUFFER, renderbuffer);
1661                 glClear(clear_bits[i]);
1662                 break;
1663             }
1664             default: FAIL() << "Unrecognized binding type";
1665         }
1666     }
1667     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()) << "GL error during framebuffer setup";
1668     ASSERT_EQ(GLenum{GL_FRAMEBUFFER_COMPLETE},
1669               glCheckFramebufferStatus(GL_FRAMEBUFFER)) << "Framebuffer not complete";
1670     glViewport(0, 0, width, height);
1671 }
1672 
TearDown()1673 void AHardwareBufferGLTest::TearDown() {
1674     MakeCurrentNone();
1675     for (int i = 0; i < 2; ++i) {
1676         // All GL objects will be deleted along with the context.
1677         eglDestroyContext(mDisplay, mContext[i]);
1678     }
1679     if (mBuffer != nullptr) {
1680         eglDestroyImageKHR(mDisplay, mEGLImage);
1681         AHardwareBuffer_release(mBuffer);
1682     }
1683     if (mSurface != EGL_NO_SURFACE) {
1684         eglDestroySurface(mDisplay, mSurface);
1685     }
1686     eglTerminate(mDisplay);
1687 }
1688 
1689 
1690 class BlobTest : public AHardwareBufferGLTest {
1691 public:
SetUpBuffer(const AHardwareBuffer_Desc & desc)1692     bool SetUpBuffer(const AHardwareBuffer_Desc& desc) override {
1693         if (!HasGLExtension("GL_EXT_external_buffer")) {
1694             ALOGI("Test skipped: GL_EXT_external_buffer not present");
1695             return false;
1696         }
1697         return AHardwareBufferGLTest::SetUpBuffer(desc);
1698     }
1699 };
1700 
1701 // Verifies that a blob buffer can be used to supply vertex attributes to a shader.
TEST_P(BlobTest,GpuDataBufferVertexBuffer)1702 TEST_P(BlobTest, GpuDataBufferVertexBuffer) {
1703     AHardwareBuffer_Desc desc = GetParam();
1704     desc.width = sizeof kQuadPositions;
1705     desc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
1706     if (!SetUpBuffer(desc)) return;
1707 
1708     ASSERT_NO_FATAL_FAILURE(
1709         SetUpProgram(kVertexShader, kColorFragmentShader, kQuadPositions, 0.5f));
1710 
1711     for (int i = 0; i < mContextCount; ++i) {
1712         MakeCurrent(i);
1713         ASSERT_NO_FATAL_FAILURE(
1714             SetUpBufferObject(desc.width, GL_ARRAY_BUFFER,
1715                               GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_WRITE_BIT));
1716     }
1717     float* data = static_cast<float*>(
1718         glMapBufferRange(GL_ARRAY_BUFFER, 0, desc.width,
1719                          GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT));
1720     ASSERT_NE(data, nullptr) << "glMapBufferRange on a blob buffer failed";
1721     memcpy(data, kQuadPositions, desc.width);
1722     glUnmapBuffer(GL_ARRAY_BUFFER);
1723     glFinish();
1724 
1725     MakeCurrent(0);
1726     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(40, 40, 0, kRenderbuffer));
1727     GLint a_position_location = glGetAttribLocation(mProgram, "aPosition");
1728     glVertexAttribPointer(a_position_location, 2, GL_FLOAT, GL_TRUE, 0, 0);
1729     glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
1730     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
1731 
1732     // Check the rendered pixels. There should be a red square in the middle.
1733     std::vector<GoldenPixel> goldens{
1734         {5, 35, kZero}, {15, 35, kZero}, {25, 35, kZero}, {35, 35, kZero},
1735         {5, 25, kZero}, {15, 25, kRed},  {25, 25, kRed},  {35, 25, kZero},
1736         {5, 15, kZero}, {15, 15, kRed},  {25, 15, kRed},  {35, 15, kZero},
1737         {5,  5, kZero}, {15,  5, kZero}, {25, 5,  kZero}, {35, 5,  kZero},
1738     };
1739     CheckGoldenPixels(goldens, GL_RGBA8);
1740 }
1741 
1742 // Verifies that a blob buffer can be directly accessed from the CPU.
TEST_P(BlobTest,GpuDataBufferCpuWrite)1743 TEST_P(BlobTest, GpuDataBufferCpuWrite) {
1744     AHardwareBuffer_Desc desc = GetParam();
1745     desc.width = sizeof kQuadPositions;
1746     desc.usage = AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY | AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
1747     if (!SetUpBuffer(desc)) return;
1748 
1749     ASSERT_NO_FATAL_FAILURE(
1750         SetUpProgram(kVertexShader, kColorFragmentShader, kQuadPositions, 0.5f));
1751 
1752     for (int i = 0; i < mContextCount; ++i) {
1753         MakeCurrent(i);
1754         ASSERT_NO_FATAL_FAILURE(
1755             SetUpBufferObject(desc.width, GL_ARRAY_BUFFER,
1756                               GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_WRITE_BIT));
1757     }
1758 
1759     // Clear the buffer to zero
1760     std::vector<float> zero_data(desc.width / sizeof(float), 0.f);
1761     glBufferSubData(GL_ARRAY_BUFFER, 0, desc.width, zero_data.data());
1762     glFinish();
1763 
1764     // Upload actual data with CPU access
1765     float* data = nullptr;
1766     int result = AHardwareBuffer_lock(mBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY,
1767                                       -1, nullptr, reinterpret_cast<void**>(&data));
1768     ASSERT_EQ(NO_ERROR, result);
1769     memcpy(data, kQuadPositions, desc.width);
1770     AHardwareBuffer_unlock(mBuffer, nullptr);
1771 
1772     // Render the buffer in the other context
1773     MakeCurrent(0);
1774     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(40, 40, 0, kRenderbuffer));
1775     GLint a_position_location = glGetAttribLocation(mProgram, "aPosition");
1776     glVertexAttribPointer(a_position_location, 2, GL_FLOAT, GL_TRUE, 0, 0);
1777     glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
1778     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
1779 
1780     // Check the rendered pixels. There should be a red square in the middle.
1781     std::vector<GoldenPixel> goldens{
1782         {5, 35, kZero}, {15, 35, kZero}, {25, 35, kZero}, {35, 35, kZero},
1783         {5, 25, kZero}, {15, 25, kRed},  {25, 25, kRed},  {35, 25, kZero},
1784         {5, 15, kZero}, {15, 15, kRed},  {25, 15, kRed},  {35, 15, kZero},
1785         {5,  5, kZero}, {15,  5, kZero}, {25, 5,  kZero}, {35, 5,  kZero},
1786     };
1787     CheckGoldenPixels(goldens, GL_RGBA8);
1788 }
1789 
1790 // Verifies that data written into a blob buffer from the GPU can be read on the CPU.
TEST_P(BlobTest,GpuDataBufferCpuRead)1791 TEST_P(BlobTest, GpuDataBufferCpuRead) {
1792     if (mGLVersion < 31) {
1793         ALOGI("Test skipped: shader storage buffer objects require ES 3.1+, found %d.%d",
1794               mGLVersion / 10, mGLVersion % 10);
1795         return;
1796     }
1797     const int kBufferElements = 16;
1798     AHardwareBuffer_Desc desc = GetParam();
1799     desc.width = kBufferElements * sizeof(int);
1800     desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
1801     if (!SetUpBuffer(desc)) return;
1802 
1803     for (int i = 0; i < mContextCount; ++i) {
1804         MakeCurrent(i);
1805         ASSERT_NO_FATAL_FAILURE(
1806             SetUpBufferObject(desc.width, GL_SHADER_STORAGE_BUFFER,
1807                               GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_READ_BIT));
1808     }
1809 
1810     // Clear the buffer to zero
1811     std::vector<unsigned int> expected_data(kBufferElements, 0U);
1812     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, desc.width, expected_data.data());
1813     glFinish();
1814 
1815     // Write into the buffer with a compute shader
1816     GLint status = 0;
1817     mProgram = glCreateProgram();
1818     GLuint shader = glCreateShader(GL_COMPUTE_SHADER);
1819     glShaderSource(shader, 1, &kSsboComputeShaderEs31, nullptr);
1820     glCompileShader(shader);
1821     glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
1822     ASSERT_EQ(GL_TRUE, status) << "Compute shader compilation failed";
1823     glAttachShader(mProgram, shader);
1824     glLinkProgram(mProgram);
1825     glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
1826     ASSERT_EQ(GL_TRUE, status) << "Shader program linking failed";
1827     glDetachShader(mProgram, shader);
1828     glDeleteShader(shader);
1829     glUseProgram(mProgram);
1830     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()) << "GL error during compute shader setup";
1831     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mBufferObjects[mWhich]);
1832     glDispatchCompute(kBufferElements, 1, 1);
1833     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1834     glFinish();
1835     EXPECT_EQ(GLenum{GL_NO_ERROR}, glGetError()) << "GL error during compute shader execution";
1836 
1837     // Inspect the data written into the buffer using CPU access.
1838     MakeCurrent(0);
1839     unsigned int* data = nullptr;
1840     int result = AHardwareBuffer_lock(mBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY,
1841                                       -1, nullptr, reinterpret_cast<void**>(&data));
1842     ASSERT_EQ(NO_ERROR, result) << "AHardwareBuffer_lock failed with error " << result;
1843     std::ostringstream s;
1844     for (int i = 0; i < kBufferElements; ++i) {
1845         expected_data[i] = static_cast<unsigned int>(i * 3);
1846         s << data[i] << ", ";
1847     }
1848     EXPECT_EQ(0, memcmp(expected_data.data(), data, desc.width)) << s.str();
1849     AHardwareBuffer_unlock(mBuffer, nullptr);
1850 }
1851 
1852 // The first case tests an ordinary GL buffer, while the second one tests an AHB-backed buffer.
1853 INSTANTIATE_TEST_CASE_P(
1854     Blob, BlobTest,
1855     ::testing::Values(
1856         AHardwareBuffer_Desc{1, 1, 1, AHARDWAREBUFFER_FORMAT_BLOB, 0, 0, 0, 0}),
1857     &GetTestName);
1858 
1859 
1860 class ColorTest : public AHardwareBufferGLTest {
1861 public:
SetUpBuffer(const AHardwareBuffer_Desc & desc)1862     bool SetUpBuffer(const AHardwareBuffer_Desc& desc) override {
1863         if ((desc.usage & AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT) &&
1864             !IsFormatColorRenderable(desc.format, desc.stride & kUseSrgb)) {
1865             ALOGI("Test skipped: requires GPU_COLOR_OUTPUT, but format is not color-renderable");
1866             return false;
1867         }
1868         return AHardwareBufferGLTest::SetUpBuffer(desc);
1869     }
1870 };
1871 
1872 // Verify that when allocating an AHardwareBuffer succeeds with GPU_COLOR_OUTPUT,
1873 // it can be bound as a framebuffer attachment, glClear'ed and then read from
1874 // another context using glReadPixels.
TEST_P(ColorTest,GpuColorOutputIsRenderable)1875 TEST_P(ColorTest, GpuColorOutputIsRenderable) {
1876     AHardwareBuffer_Desc desc = GetParam();
1877     desc.width = 100;
1878     desc.height = 100;
1879     desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
1880     if (FormatIsYuv(desc.format)) {
1881         // YUV formats are only supported for textures, so add texture usage.
1882         desc.usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1883     }
1884     // This test does not make sense for layered buffers - don't bother testing them.
1885     if (desc.layers > 1) return;
1886     if (!SetUpBuffer(desc)) return;
1887 
1888     for (int i = 0; i < mContextCount; ++i) {
1889         MakeCurrent(i);
1890 
1891         // YUV renderbuffers are unsupported, so we attach as a texture in this case.
1892         AttachmentType attachmentType;
1893         if (FormatIsYuv(desc.format)) {
1894             ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, 1));
1895             attachmentType = kBufferAsTexture;
1896         } else {
1897             attachmentType = kBufferAsRenderbuffer;
1898         }
1899 
1900         ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(desc.width, desc.height, 0, attachmentType));
1901     }
1902 
1903     // Draw a simple checkerboard pattern in the second context, which will
1904     // be current after the loop above, then read it in the first.
1905     DrawCheckerboard(desc.width, desc.height, desc.format);
1906     glFinish();
1907 
1908     MakeCurrent(0);
1909     std::vector<GoldenPixel> goldens{
1910         {10, 90, kRed},  {40, 90, kRed},  {60, 90, kBlue},  {90, 90, kBlue},
1911         {10, 60, kRed},  {40, 60, kRed},  {60, 60, kBlue},  {90, 60, kBlue},
1912         {10, 40, kZero}, {40, 40, kZero}, {60, 40, kGreen}, {90, 40, kGreen},
1913         {10, 10, kZero}, {40, 10, kZero}, {60, 10, kGreen}, {90, 10, kGreen},
1914     };
1915     CheckGoldenPixels(goldens, desc.format);
1916 }
1917 
1918 // Verifies that the content of GPU_COLOR_OUTPUT buffers can be read on the CPU directly by
1919 // locking the HardwareBuffer.
TEST_P(ColorTest,GpuColorOutputCpuRead)1920 TEST_P(ColorTest, GpuColorOutputCpuRead) {
1921     AHardwareBuffer_Desc desc = GetParam();
1922     desc.width = 16;
1923     desc.height = 16;
1924     desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
1925     if (FormatIsYuv(desc.format)) {
1926         // YUV formats are only supported for textures, so add texture usage.
1927         desc.usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1928     }
1929     // This test does not make sense for GL formats. Layered buffers do not support CPU access.
1930     if ((desc.stride & kGlFormat) || desc.layers > 1) {
1931         ALOGI("Test skipped: Test is for single-layer HardwareBuffer formats only.");
1932         return;
1933     }
1934     if (!SetUpBuffer(desc)) return;
1935 
1936     MakeCurrent(1);
1937 
1938     // YUV renderbuffers are unsupported, so we attach as a texture in this case.
1939     AttachmentType attachmentType;
1940     if (FormatIsYuv(desc.format)) {
1941         ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, 1));
1942         attachmentType = kBufferAsTexture;
1943     } else {
1944         attachmentType = kBufferAsRenderbuffer;
1945     }
1946 
1947     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(desc.width, desc.height, 0, attachmentType));
1948 
1949     // Draw a simple checkerboard pattern in the second context, which will
1950     // be current after the loop above, then read it in the first.
1951     DrawCheckerboard(desc.width, desc.height, desc.format);
1952     glFinish();
1953 
1954     MakeCurrent(0);
1955     std::vector<GoldenPixel> goldens{
1956         {0, 15, kRed},  {7, 15, kRed},  {8, 15, kBlue},  {15, 15, kBlue},
1957         {0,  8, kRed},  {7,  8, kRed},  {8,  8, kBlue},  {15,  8, kBlue},
1958         {0,  7, kZero}, {7,  7, kZero}, {8,  7, kGreen}, {15,  7, kGreen},
1959         {0,  0, kZero}, {7,  0, kZero}, {8,  0, kGreen}, {15,  0, kGreen},
1960     };
1961 
1962     // As we glCleared the colors, the YUV colors will simply be the RGB values
1963     CheckCpuGoldenPixels(goldens, mBuffer);
1964 }
1965 
1966 // Verifies that the CPU can write directly to a HardwareBuffer, and the GPU can then read from
1967 // that buffer.
TEST_P(ColorTest,CpuWriteColorGpuRead)1968 TEST_P(ColorTest, CpuWriteColorGpuRead) {
1969     AHardwareBuffer_Desc desc = GetParam();
1970     desc.width = 16;
1971     desc.height = 16;
1972     desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY;
1973     // This test does not make sense for GL formats. Layered buffers do not support CPU access.
1974     if ((desc.stride & kGlFormat) || desc.layers > 1) {
1975         ALOGI("Test skipped: Test is for single-layer HardwareBuffer formats only.");
1976         return;
1977     }
1978 
1979     if (!SetUpBuffer(desc)) return;
1980 
1981     // Write into buffer when no context is active
1982     MakeCurrentNone();
1983     WriteCheckerBoard(mBuffer);
1984 
1985     // Now setup a texture in a context to sample from this buffer
1986     MakeCurrent(0);
1987     const int kTextureUnit = 6 % mMaxTextureUnits;
1988     ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, kTextureUnit));
1989     glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1990     glTexParameteri(mTexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1991 
1992     // Draw a quad that samples from the texture.
1993     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(16, 16, 0, kRenderbuffer));
1994     glClearColor(0.f, 0.f, 0.f, 0.f);
1995     glClear(GL_COLOR_BUFFER_BIT);
1996 
1997     std::string vertex_shader = GetTextureVertexShader(desc.format, desc.stride);
1998     std::string fragment_shader = GetTextureFragmentShader(desc.format, desc.stride);
1999     ASSERT_NO_FATAL_FAILURE(
2000         SetUpProgram(vertex_shader, fragment_shader, kQuadPositions,
2001             1.0f, kTextureUnit));
2002 
2003     glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
2004     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2005 
2006     // Check the rendered pixels.
2007     // Non-alpha formats will render black instead of zero
2008     GoldenColor dark = FormatHasAlpha(desc.format) ? kZero : kBlack;
2009     std::vector<GoldenPixel> goldens{
2010         {0, 15, kRed},  {7, 15, kRed},  {8, 15, kBlue},  {15, 15, kBlue},
2011         {0,  8, kRed},  {7,  8, kRed},  {8,  8, kBlue},  {15,  8, kBlue},
2012         {0,  7, dark},  {7,  7, dark},  {8,  7, kGreen}, {15,  7, kGreen},
2013         {0,  0, dark},  {7,  0, dark},  {8,  0, kGreen}, {15,  0, kGreen},
2014     };
2015     // If source was YUV, there may be some conversion imprecision, so we allow some error
2016     CheckGoldenPixels(goldens, GL_RGBA8, GetMaxExpectedColorError(desc.format, desc.stride));
2017 }
2018 
2019 // Verify that when allocating an AHardwareBuffer succeeds with GPU_SAMPLED_IMAGE,
2020 // it can be bound as a texture, set to a color with glTexSubImage2D and sampled
2021 // from in a fragment shader.
TEST_P(ColorTest,GpuSampledImageCanBeSampled)2022 TEST_P(ColorTest, GpuSampledImageCanBeSampled) {
2023     AHardwareBuffer_Desc desc = GetParam();
2024     desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
2025 
2026     // This test requires using glTexImage2d to assign image data. YUV formats do not
2027     // support this. Other tests using glClear and CPU access test the YUV variants.
2028     if (FormatIsYuv(desc.format)) {
2029         ALOGI("Test Skipped: YUV formats do not support glTexImage2d and variants.");
2030         return;
2031     }
2032 
2033     if (!SetUpBuffer(desc)) return;
2034 
2035     // Bind the EGLImage to textures in both contexts.
2036     const int kTextureUnit = 6 % mMaxTextureUnits;
2037     for (int i = 0; i < mContextCount; ++i) {
2038         MakeCurrent(i);
2039         ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, kTextureUnit));
2040         glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2041         glTexParameteri(mTexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2042     }
2043     // In the second context, upload opaque red to the texture.
2044     ASSERT_NO_FATAL_FAILURE(UploadRedPixels(desc));
2045     glFinish();
2046 
2047     // In the first context, draw a quad that samples from the texture.
2048     MakeCurrent(0);
2049     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(40, 40, 0, kRenderbuffer));
2050     glClearColor(0.f, 0.f, 0.f, 0.f);
2051     glClear(GL_COLOR_BUFFER_BIT);
2052 
2053     if (desc.layers > 1) {
2054         ASSERT_NO_FATAL_FAILURE(
2055             SetUpProgram(std::string("#version 300 es") + kVertexShaderEs3x,
2056                          kArrayFragmentShaderEs30, kQuadPositions, 0.5f, kTextureUnit));
2057     } else {
2058         std::string vertex_shader = GetTextureVertexShader(desc.format, desc.stride);
2059         std::string fragment_shader = GetTextureFragmentShader(desc.format, desc.stride);
2060         ASSERT_NO_FATAL_FAILURE(
2061             SetUpProgram(vertex_shader, fragment_shader, kQuadPositions,
2062                          0.5f, kTextureUnit));
2063     }
2064     glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
2065     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2066 
2067     // Check the rendered pixels. There should be a red square in the middle.
2068     GoldenColor color = kRed;
2069     if (desc.stride & kUseSrgb) {
2070         color = FormatHasAlpha(desc.format) ? kRed50 : kRed50Alpha100;
2071     }
2072     std::vector<GoldenPixel> goldens{
2073         {5, 35, kZero}, {15, 35, kZero}, {25, 35, kZero}, {35, 35, kZero},
2074         {5, 25, kZero}, {15, 25, color}, {25, 25, color}, {35, 25, kZero},
2075         {5, 15, kZero}, {15, 15, color}, {25, 15, color}, {35, 15, kZero},
2076         {5,  5, kZero}, {15,  5, kZero}, {25, 5,  kZero}, {35, 5,  kZero},
2077     };
2078     CheckGoldenPixels(goldens, GL_RGBA8);
2079 }
2080 
2081 // Verify that buffers which have both GPU_SAMPLED_IMAGE and GPU_COLOR_OUTPUT
2082 // can be both rendered and sampled as a texture.
TEST_P(ColorTest,GpuColorOutputAndSampledImage)2083 TEST_P(ColorTest, GpuColorOutputAndSampledImage) {
2084     AHardwareBuffer_Desc desc = GetParam();
2085     desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
2086     if (!SetUpBuffer(desc)) return;
2087 
2088     // Bind the EGLImage to textures in both contexts.
2089     const int kTextureUnit = 1 % mMaxTextureUnits;
2090     for (int i = 0; i < mContextCount; ++i) {
2091         MakeCurrent(i);
2092         ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, kTextureUnit));
2093         glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2094         glTexParameteri(mTexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2095     }
2096 
2097     // In the second context, draw a checkerboard pattern.
2098     ASSERT_NO_FATAL_FAILURE(
2099         SetUpFramebuffer(desc.width, desc.height, desc.layers - 1, kBufferAsTexture));
2100     DrawCheckerboard(desc.width, desc.height, desc.format);
2101     glFinish();
2102 
2103     // In the first context, draw a quad that samples from the texture.
2104     MakeCurrent(0);
2105     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(40, 40, 0, kRenderbuffer));
2106     glClearColor(0.f, 0.f, 0.f, 0.f);
2107     glClear(GL_COLOR_BUFFER_BIT);
2108 
2109     if (desc.layers > 1) {
2110         ASSERT_NO_FATAL_FAILURE(
2111             SetUpProgram(std::string("#version 300 es") + kVertexShaderEs3x,
2112                          kArrayFragmentShaderEs30, kQuadPositions, 0.5f, kTextureUnit));
2113     } else {
2114         std::string vertex_shader = GetTextureVertexShader(desc.format, desc.stride);
2115         std::string fragment_shader = GetTextureFragmentShader(desc.format, desc.stride);
2116         ASSERT_NO_FATAL_FAILURE(
2117             SetUpProgram(vertex_shader, fragment_shader, kQuadPositions,
2118                          0.5f, kTextureUnit));
2119     }
2120     glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
2121     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2122 
2123     // Check the rendered pixels. The lower left area of the checkerboard will
2124     // be either transparent or opaque black depending on whether the texture
2125     // format has an alpha channel.
2126     const GoldenColor kCBBlack = FormatHasAlpha(desc.format) ? kZero : kBlack;
2127     std::vector<GoldenPixel> goldens{
2128         {5, 35, kZero}, {15, 35, kZero},    {25, 35, kZero},  {35, 35, kZero},
2129         {5, 25, kZero}, {15, 25, kRed},     {25, 25, kBlue},  {35, 25, kZero},
2130         {5, 15, kZero}, {15, 15, kCBBlack}, {25, 15, kGreen}, {35, 15, kZero},
2131         {5, 5,  kZero}, {15, 5,  kZero},    {25, 5,  kZero},  {35, 5,  kZero},
2132     };
2133     CheckGoldenPixels(goldens, GL_RGBA8, GetMaxExpectedColorError(desc.format, desc.stride));
2134 }
2135 
TEST_P(ColorTest,MipmapComplete)2136 TEST_P(ColorTest, MipmapComplete) {
2137     if (mGLVersion < 30) {
2138         ALOGI("Test skipped: reading from nonzero level of a mipmap requires ES 3.0+, "
2139               "found %d.%d", mGLVersion / 10, mGLVersion % 10);
2140         return;
2141     }
2142     const int kNumTiles = 8;
2143     AHardwareBuffer_Desc desc = GetParam();
2144     // Ensure that the checkerboard tiles have equal size at every level of the mipmap.
2145     desc.width = std::max(8u, RoundUpToPowerOf2(desc.width));
2146     desc.height = std::max(8u, RoundUpToPowerOf2(desc.height));
2147     desc.usage =
2148         AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
2149         AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
2150         AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
2151     if (!SetUpBuffer(desc)) return;
2152 
2153     const int kTextureUnit = 7 % mMaxTextureUnits;
2154     for (int i = 0; i < mContextCount; ++i) {
2155         MakeCurrent(i);
2156         ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, kTextureUnit));
2157         glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2158     }
2159     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2160 
2161     // Draw checkerboard for mipmapping.
2162     const int kTileWidth = desc.width / kNumTiles;
2163     const int kTileHeight = desc.height / kNumTiles;
2164     ASSERT_NO_FATAL_FAILURE(
2165         SetUpFramebuffer(desc.width, desc.height, desc.layers - 1, kBufferAsTexture));
2166     glEnable(GL_SCISSOR_TEST);
2167     for (int i = 0; i < kNumTiles; ++i) {
2168         for (int j = 0; j < kNumTiles; ++j) {
2169             const float v = (i & 1) ^ (j & 1) ? 1.f : 0.f;
2170             glClearColor(v, 0.f, 0.f, v);
2171             glScissor(i * kTileWidth, j * kTileHeight, kTileWidth, kTileHeight);
2172             glClear(GL_COLOR_BUFFER_BIT);
2173         }
2174     }
2175     glDisable(GL_SCISSOR_TEST);
2176     glGenerateMipmap(mTexTarget);
2177     glFinish();
2178     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2179 
2180     MakeCurrent(0);
2181     ASSERT_NO_FATAL_FAILURE(
2182         SetUpFramebuffer(1, 1, desc.layers - 1, kBufferAsTexture, kNone, kNone, kNone,
2183                          MipLevelCount(desc.width, desc.height) - 1));
2184     std::vector<GoldenPixel> goldens{{0, 0, (desc.stride & kUseSrgb) ? kRed50Srgb : kRed50}};
2185     CheckGoldenPixels(goldens, desc.format);
2186 }
2187 
TEST_P(ColorTest,CubemapSampling)2188 TEST_P(ColorTest, CubemapSampling) {
2189     AHardwareBuffer_Desc desc = GetParam();
2190     desc.usage =
2191         AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
2192         AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
2193         AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
2194     desc.height = desc.width;
2195     desc.layers *= 6;
2196     if (!SetUpBuffer(desc)) return;
2197 
2198     const int kTextureUnit = 4 % mMaxTextureUnits;
2199     for (int i = 0; i < mContextCount; ++i) {
2200         MakeCurrent(i);
2201         ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, kTextureUnit));
2202     }
2203 
2204     for (int i = 0; i < 6; ++i) {
2205         ASSERT_NO_FATAL_FAILURE(
2206             SetUpFramebuffer(desc.width, desc.height, desc.layers - 6 + i, kBufferAsTexture));
2207         DrawCheckerboard(desc.width, desc.height, desc.format);
2208     }
2209     glFinish();
2210 
2211     MakeCurrent(0);
2212     if (desc.layers > 6) {
2213         ASSERT_NO_FATAL_FAILURE(
2214             SetUpProgram(std::string("#version 320 es") + kVertexShaderEs3x,
2215                          kCubeMapArrayFragmentShaderEs32, kQuadPositions, 0.5f, kTextureUnit));
2216     } else {
2217         ASSERT_NO_FATAL_FAILURE(
2218             SetUpProgram(kVertexShader, kCubeMapFragmentShader, kQuadPositions, 0.5f, kTextureUnit));
2219     }
2220     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(40, 40, 0, kRenderbuffer));
2221     for (int i = 0; i < 6; ++i) {
2222         float face_vector[3] = {0.f, 0.f, 0.f};
2223         face_vector[i / 2] = (i % 2) ? -1.f : 1.f;
2224         glUniform3fv(mFaceVectorLocation, 1, face_vector);
2225         glClearColor(0.f, 0.f, 0.f, 0.f);
2226         glClear(GL_COLOR_BUFFER_BIT);
2227         glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
2228 
2229         const GoldenColor kCBBlack = FormatHasAlpha(desc.format) ? kZero : kBlack;
2230         std::vector<GoldenPixel> goldens{
2231             {5, 35, kZero}, {15, 35, kZero},    {25, 35, kZero},  {35, 35, kZero},
2232             {5, 25, kZero}, {15, 25, kRed},     {25, 25, kBlue},  {35, 25, kZero},
2233             {5, 15, kZero}, {15, 15, kCBBlack}, {25, 15, kGreen}, {35, 15, kZero},
2234             {5, 5,  kZero}, {15, 5,  kZero},    {25, 5,  kZero},  {35, 5,  kZero},
2235         };
2236         CheckGoldenPixels(goldens, GL_RGBA8);
2237     }
2238 }
2239 
TEST_P(ColorTest,CubemapMipmaps)2240 TEST_P(ColorTest, CubemapMipmaps) {
2241     if (mGLVersion < 30) {
2242         ALOGI("Test skipped: reading from nonzero level of a mipmap requires ES 3.0+, "
2243               "found %d.%d", mGLVersion / 10, mGLVersion % 10);
2244         return;
2245     }
2246     const int kNumTiles = 8;
2247     AHardwareBuffer_Desc desc = GetParam();
2248     desc.usage =
2249         AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
2250         AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
2251         AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP |
2252         AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
2253     // Ensure that the checkerboard tiles have equal size at every level of the mipmap.
2254     desc.width = std::max(8u, RoundUpToPowerOf2(desc.width));
2255     desc.height = desc.width;
2256     desc.layers *= 6;
2257     if (!SetUpBuffer(desc)) return;
2258 
2259     const int kTextureUnit = 5 % mMaxTextureUnits;
2260     for (int i = 0; i < mContextCount; ++i) {
2261         MakeCurrent(i);
2262         ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, kTextureUnit));
2263     }
2264 
2265     const int kTileSize = desc.width / kNumTiles;
2266     glEnable(GL_SCISSOR_TEST);
2267     for (int face = 0; face < 6; ++face) {
2268         ASSERT_NO_FATAL_FAILURE(
2269             SetUpFramebuffer(desc.width, desc.height, desc.layers - 6 + face, kBufferAsTexture));
2270         for (int i = 0; i < kNumTiles; ++i) {
2271                 for (int j = 0; j < kNumTiles; ++j) {
2272                 const float v = (i & 1) ^ (j & 1) ? 1.f : 0.f;
2273                 glClearColor(v, 0.f, 0.f, v);
2274                 glScissor(i * kTileSize, j * kTileSize, kTileSize, kTileSize);
2275                 glClear(GL_COLOR_BUFFER_BIT);
2276             }
2277         }
2278     }
2279     glDisable(GL_SCISSOR_TEST);
2280     glGenerateMipmap(mTexTarget);
2281     glFinish();
2282 
2283     MakeCurrent(0);
2284     for (int face = 0; face < 6; ++face) {
2285         ASSERT_NO_FATAL_FAILURE(
2286             SetUpFramebuffer(1, 1, desc.layers - 6 + face, kBufferAsTexture, kNone, kNone, kNone,
2287                              MipLevelCount(desc.width, desc.height) - 1));
2288         std::vector<GoldenPixel> goldens{{0, 0, (desc.stride & kUseSrgb) ? kRed50Srgb : kRed50}};
2289         CheckGoldenPixels(goldens, desc.format);
2290     }
2291 }
2292 
2293 // The 'stride' field is used to pass a combination of TestFlags.
2294 INSTANTIATE_TEST_CASE_P(
2295     SingleLayer, ColorTest,
2296     ::testing::Values(
2297         AHardwareBuffer_Desc{75, 33, 1, GL_RGB8, 0, kGlFormat, 0, 0},
2298         AHardwareBuffer_Desc{64, 80, 1, GL_RGBA8, 0, kGlFormat, 0, 0},
2299         AHardwareBuffer_Desc{49, 23, 1, GL_SRGB8_ALPHA8, 0, kGlFormat | kUseSrgb, 0, 0},
2300         AHardwareBuffer_Desc{63, 78, 1, GL_RGB565, 0, kGlFormat, 0, 0},
2301         AHardwareBuffer_Desc{42, 41, 1, GL_RGBA16F, 0, kGlFormat, 0, 0},
2302         AHardwareBuffer_Desc{37, 63, 1, GL_RGB10_A2, 0, kGlFormat, 0, 0},
2303         AHardwareBuffer_Desc{33, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, 0, 0, 0},
2304         AHardwareBuffer_Desc{33, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, kUseSrgb, 0, 0},
2305         AHardwareBuffer_Desc{20, 10, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, 0, 0, 0},
2306         AHardwareBuffer_Desc{20, 10, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, kUseSrgb, 0, 0},
2307         AHardwareBuffer_Desc{16, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, 0, 0, 0},
2308         AHardwareBuffer_Desc{16, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, kUseSrgb, 0, 0},
2309         AHardwareBuffer_Desc{10, 20, 1, AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM, 0, 0, 0, 0},
2310         AHardwareBuffer_Desc{10, 20, 1, AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT, 0, 0, 0, 0},
2311         AHardwareBuffer_Desc{10, 20, 1, AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM, 0, 0, 0, 0},
2312         AHardwareBuffer_Desc{64, 80, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, 0, 0, 0, 0},
2313         AHardwareBuffer_Desc{64, 80, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, 0,
2314                                         kExplicitYuvSampling, 0, 0}),
2315     &GetTestName);
2316 
2317 INSTANTIATE_TEST_CASE_P(
2318     MultipleLayers, ColorTest,
2319     ::testing::Values(
2320         AHardwareBuffer_Desc{75, 33, 5, GL_RGB8, 0, kGlFormat, 0, 0},
2321         AHardwareBuffer_Desc{64, 80, 6, GL_RGBA8, 0, kGlFormat, 0, 0},
2322         AHardwareBuffer_Desc{33, 28, 4, GL_SRGB8_ALPHA8, 0, kGlFormat | kUseSrgb, 0, 0},
2323         AHardwareBuffer_Desc{42, 41, 3, GL_RGBA16F, 0, kGlFormat, 0, 0},
2324         AHardwareBuffer_Desc{63, 78, 3, GL_RGB565, 0, kGlFormat, 0, 0},
2325         AHardwareBuffer_Desc{37, 63, 4, GL_RGB10_A2, 0, kGlFormat, 0, 0},
2326         AHardwareBuffer_Desc{25, 77, 7, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, 0, 0, 0},
2327         AHardwareBuffer_Desc{25, 77, 7, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, kUseSrgb, 0, 0},
2328         AHardwareBuffer_Desc{30, 30, 3, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, 0, 0, 0},
2329         AHardwareBuffer_Desc{30, 30, 3, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, kUseSrgb, 0, 0},
2330         AHardwareBuffer_Desc{50, 50, 4, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, 0, 0, 0},
2331         AHardwareBuffer_Desc{50, 50, 4, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, kUseSrgb, 0, 0},
2332         AHardwareBuffer_Desc{20, 10, 2, AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM, 0, 0, 0, 0},
2333         AHardwareBuffer_Desc{20, 20, 4, AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT, 0, 0, 0, 0},
2334         AHardwareBuffer_Desc{30, 20, 16, AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM, 0, 0, 0, 0}),
2335     &GetTestName);
2336 
2337 
2338 class DepthTest : public AHardwareBufferGLTest {};
2339 
2340 // Verify that depth testing against a depth buffer rendered in another context
2341 // works correctly.
TEST_P(DepthTest,DepthAffectsDrawAcrossContexts)2342 TEST_P(DepthTest, DepthAffectsDrawAcrossContexts) {
2343     AHardwareBuffer_Desc desc = GetParam();
2344     desc.width = 40;
2345     desc.height = 40;
2346     desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
2347     // This test does not make sense for layered buffers - don't bother testing them.
2348     if (desc.layers > 1) return;
2349     if (!SetUpBuffer(desc)) return;
2350 
2351     // Bind the EGLImage to renderbuffers and framebuffers in both contexts.
2352     // The depth buffer is shared, but the color buffer is not.
2353     for (int i = 0; i < mContextCount; ++i) {
2354         MakeCurrent(i);
2355         ASSERT_NO_FATAL_FAILURE(
2356             SetUpFramebuffer(40, 40, 0, kRenderbuffer, kBufferAsRenderbuffer));
2357     }
2358 
2359     // In the second context, clear the depth buffer to a checkerboard pattern.
2360     DrawCheckerboard(40, 40, desc.format);
2361     glFinish();
2362 
2363     // In the first context, clear the color buffer only, then draw a red pyramid.
2364     MakeCurrent(0);
2365     ASSERT_NO_FATAL_FAILURE(
2366         SetUpProgram(kVertexShader, kColorFragmentShader, kPyramidPositions, 1.f));
2367     glClearColor(0.f, 0.f, 0.f, 0.f);
2368     glClear(GL_COLOR_BUFFER_BIT);
2369     glEnable(GL_DEPTH_TEST);
2370     glDepthFunc(GL_LESS);
2371     glDrawArrays(GL_TRIANGLES, 0, kPyramidVertexCount);
2372     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2373 
2374     // Check golden pixels.
2375     std::vector<GoldenPixel> goldens{
2376         {5, 35, kRed}, {15, 35, kRed},  {25, 35, kZero}, {35, 35, kZero},
2377         {5, 25, kRed}, {15, 25, kZero}, {25, 25, kZero}, {35, 25, kZero},
2378         {5, 15, kRed}, {15, 15, kRed},  {25, 15, kRed},  {35, 15, kRed},
2379         {5, 5,  kRed}, {15, 5,  kRed},  {25, 5,  kRed},  {35, 5,  kRed},
2380     };
2381     CheckGoldenPixels(goldens, GL_RGBA8);
2382 }
2383 
2384 // Verify that depth buffers with usage GPU_SAMPLED_IMAGE can be used as textures.
TEST_P(DepthTest,DepthCanBeSampled)2385 TEST_P(DepthTest, DepthCanBeSampled) {
2386     AHardwareBuffer_Desc desc = GetParam();
2387     desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
2388     if (!SetUpBuffer(desc)) return;
2389 
2390     // Bind the EGLImage to renderbuffers and framebuffers in both contexts.
2391     // The depth buffer is shared, but the color buffer is not.
2392     const int kTextureUnit = 3 % mMaxTextureUnits;
2393     for (int i = 0; i < 2; ++i) {
2394         MakeCurrent(i);
2395         ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, kTextureUnit));
2396         glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2397         glTexParameteri(mTexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2398     }
2399 
2400     // In the second context, attach the depth texture to the framebuffer and clear to 1.
2401     ASSERT_NO_FATAL_FAILURE(
2402         SetUpFramebuffer(desc.width, desc.height, desc.layers - 1, kNone, kBufferAsTexture));
2403     glClearDepthf(1.f);
2404     glClear(GL_DEPTH_BUFFER_BIT);
2405     glFinish();
2406 
2407     // In the first context, draw a quad using the depth texture.
2408     MakeCurrent(0);
2409     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(40, 40, 0, kRenderbuffer));
2410     glClearColor(0.f, 0.f, 0.f, 0.f);
2411     glClear(GL_COLOR_BUFFER_BIT);
2412     if (desc.layers > 1) {
2413         ASSERT_NO_FATAL_FAILURE(
2414             SetUpProgram(std::string("#version 300 es") + kVertexShaderEs3x, kArrayFragmentShaderEs30,
2415                          kQuadPositions, 0.5f, kTextureUnit));
2416     } else {
2417         std::string vertex_shader = GetTextureVertexShader(desc.format, desc.stride);
2418         std::string fragment_shader = GetTextureFragmentShader(desc.format, desc.stride);
2419         ASSERT_NO_FATAL_FAILURE(
2420             SetUpProgram(vertex_shader, fragment_shader, kQuadPositions, 0.5f, kTextureUnit));
2421     }
2422     glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
2423     glFinish();
2424     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2425 
2426     // Check the rendered pixels. There should be a square in the middle.
2427     const GoldenColor kDepth = mGLVersion < 30 ? kWhite : kRed;
2428     std::vector<GoldenPixel> goldens{
2429         {5, 35, kZero}, {15, 35, kZero},  {25, 35, kZero},  {35, 35, kZero},
2430         {5, 25, kZero}, {15, 25, kDepth}, {25, 25, kDepth}, {35, 25, kZero},
2431         {5, 15, kZero}, {15, 15, kDepth}, {25, 15, kDepth}, {35, 15, kZero},
2432         {5,  5, kZero}, {15,  5, kZero},  {25, 5,  kZero},  {35, 5,  kZero},
2433     };
2434     CheckGoldenPixels(goldens, GL_RGBA8);
2435 }
2436 
TEST_P(DepthTest,DepthCubemapSampling)2437 TEST_P(DepthTest, DepthCubemapSampling) {
2438     AHardwareBuffer_Desc desc = GetParam();
2439     desc.usage =
2440         AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
2441         AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
2442         AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
2443     desc.height = desc.width;
2444     desc.layers *= 6;
2445     if (!SetUpBuffer(desc)) return;
2446 
2447     const int kTextureUnit = 9 % mMaxTextureUnits;
2448     for (int i = 0; i < mContextCount; ++i) {
2449         MakeCurrent(i);
2450         ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, kTextureUnit));
2451         glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2452         glTexParameteri(mTexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2453     }
2454 
2455     glEnable(GL_SCISSOR_TEST);
2456     for (int i = 0; i < 6; ++i) {
2457         ASSERT_NO_FATAL_FAILURE(
2458             SetUpFramebuffer(desc.width, desc.height, desc.layers - 6 + i, kNone, kBufferAsTexture));
2459         glClearDepthf(0.f);
2460         glScissor(0, 0, desc.width, desc.height);
2461         glClear(GL_DEPTH_BUFFER_BIT);
2462         glClearDepthf(1.f);
2463         glScissor(0, 0, desc.width / 2, desc.height / 2);
2464         glClear(GL_DEPTH_BUFFER_BIT);
2465         glScissor(desc.width / 2, desc.height / 2, desc.width / 2, desc.height / 2);
2466         glClear(GL_DEPTH_BUFFER_BIT);
2467     }
2468     glDisable(GL_SCISSOR_TEST);
2469     glFinish();
2470     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2471 
2472     MakeCurrent(0);
2473     if (desc.layers > 6) {
2474         ASSERT_NO_FATAL_FAILURE(
2475             SetUpProgram(std::string("#version 320 es") + kVertexShaderEs3x,
2476                          kCubeMapArrayFragmentShaderEs32, kQuadPositions, 0.5f, kTextureUnit));
2477     } else {
2478         ASSERT_NO_FATAL_FAILURE(
2479             SetUpProgram(kVertexShader, kCubeMapFragmentShader, kQuadPositions, 0.5f, kTextureUnit));
2480     }
2481     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(40, 40, 0, kRenderbuffer));
2482     const GoldenColor kDepth = mGLVersion < 30 ? kWhite: kRed;
2483     for (int i = 0; i < 6; ++i) {
2484         float face_vector[3] = {0.f, 0.f, 0.f};
2485         face_vector[i / 2] = (i % 2) ? -1.f : 1.f;
2486         glUniform3fv(mFaceVectorLocation, 1, face_vector);
2487         glClearColor(0.f, 0.f, 0.f, 0.f);
2488         glClear(GL_COLOR_BUFFER_BIT);
2489         glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
2490         ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2491 
2492         std::vector<GoldenPixel> goldens{
2493             {5, 35, kZero}, {15, 35, kZero},  {25, 35, kZero},  {35, 35, kZero},
2494             {5, 25, kZero}, {15, 25, kBlack}, {25, 25, kDepth}, {35, 25, kZero},
2495             {5, 15, kZero}, {15, 15, kDepth}, {25, 15, kBlack}, {35, 15, kZero},
2496             {5, 5,  kZero}, {15, 5,  kZero},  {25, 5,  kZero},  {35, 5,  kZero},
2497         };
2498         CheckGoldenPixels(goldens, GL_RGBA8);
2499     }
2500 }
2501 
2502 // The 'stride' field is used to pass a combination of TestFlags.
2503 INSTANTIATE_TEST_CASE_P(
2504     SingleLayer, DepthTest,
2505     ::testing::Values(
2506         AHardwareBuffer_Desc{16, 24, 1, GL_DEPTH_COMPONENT16, 0, kGlFormat, 0, 0},
2507         AHardwareBuffer_Desc{16, 24, 1, AHARDWAREBUFFER_FORMAT_D16_UNORM, 0, 0, 0, 0},
2508         AHardwareBuffer_Desc{44, 21, 1, AHARDWAREBUFFER_FORMAT_D24_UNORM, 0, 0, 0, 0},
2509         AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
2510         AHardwareBuffer_Desc{20, 10, 1, AHARDWAREBUFFER_FORMAT_D32_FLOAT, 0, 0, 0, 0},
2511         AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}),
2512     &GetTestName);
2513 
2514 
2515 INSTANTIATE_TEST_CASE_P(
2516     MultipleLayers, DepthTest,
2517     ::testing::Values(
2518         AHardwareBuffer_Desc{16, 24, 6, GL_DEPTH_COMPONENT16, 0, kGlFormat, 0, 0},
2519         AHardwareBuffer_Desc{16, 24, 6, AHARDWAREBUFFER_FORMAT_D16_UNORM, 0, 0, 0, 0},
2520         AHardwareBuffer_Desc{44, 21, 4, AHARDWAREBUFFER_FORMAT_D24_UNORM, 0, 0, 0, 0},
2521         AHardwareBuffer_Desc{57, 33, 7, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
2522         AHardwareBuffer_Desc{20, 10, 5, AHARDWAREBUFFER_FORMAT_D32_FLOAT, 0, 0, 0, 0},
2523         AHardwareBuffer_Desc{57, 33, 3, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}),
2524     &GetTestName);
2525 
2526 
2527 class StencilTest : public AHardwareBufferGLTest {};
2528 
2529 // Verify that stencil testing against a stencil buffer rendered in another context
2530 // works correctly.
TEST_P(StencilTest,StencilAffectsDrawAcrossContexts)2531 TEST_P(StencilTest, StencilAffectsDrawAcrossContexts) {
2532     AHardwareBuffer_Desc desc = GetParam();
2533     desc.width = 40;
2534     desc.height = 40;
2535     desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
2536     // This test does not make sense for layered buffers - don't bother testing them.
2537     if (desc.layers > 1) return;
2538     if (!SetUpBuffer(desc)) return;
2539 
2540     // Bind the EGLImage to renderbuffers and framebuffers in both contexts.
2541     // The depth buffer is shared, but the color buffer is not.
2542     for (int i = 0; i < mContextCount; ++i) {
2543         MakeCurrent(i);
2544         ASSERT_NO_FATAL_FAILURE(
2545             SetUpFramebuffer(40, 40, 0, kRenderbuffer, kNone, kBufferAsRenderbuffer));
2546     }
2547 
2548     // In the second context, clear the stencil buffer to a checkerboard pattern.
2549     DrawCheckerboard(40, 40, desc.format);
2550     glFinish();
2551     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2552 
2553     // In the first context, clear the color buffer only, then draw a flat quad.
2554     MakeCurrent(0);
2555     ASSERT_NO_FATAL_FAILURE(
2556         SetUpProgram(kVertexShader, kColorFragmentShader, kQuadPositions, 1.f));
2557     glClearColor(0.f, 0.f, 0.f, 0.f);
2558     glClear(GL_COLOR_BUFFER_BIT);
2559     glEnable(GL_STENCIL_TEST);
2560     glStencilFunc(GL_ALWAYS, 0, 0xFF);
2561     glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
2562     glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
2563     glClear(GL_COLOR_BUFFER_BIT);
2564     glStencilFunc(GL_EQUAL, 2, 0xFF);
2565     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2566     glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
2567     glUniform4f(mColorLocation, 0.f, 1.f, 0.f, 1.f);
2568     glStencilFunc(GL_EQUAL, 4, 0xFF);
2569     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2570     glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
2571     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2572 
2573     // Check golden pixels.
2574     std::vector<GoldenPixel> goldens{
2575         {5, 35, kRed},  {15, 35, kRed},  {25, 35, kZero},  {35, 35, kZero},
2576         {5, 25, kRed},  {15, 25, kRed},  {25, 25, kZero},  {35, 25, kZero},
2577         {5, 15, kZero}, {15, 15, kZero}, {25, 15, kGreen}, {35, 15, kGreen},
2578         {5, 5,  kZero}, {15, 5,  kZero}, {25, 5,  kGreen}, {35, 5,  kGreen},
2579     };
2580     CheckGoldenPixels(goldens, GL_RGBA8);
2581 }
2582 
2583 // Verify that stencil testing against a stencil buffer rendered in another context
2584 // works correctly.
TEST_P(StencilTest,StencilTexture)2585 TEST_P(StencilTest, StencilTexture) {
2586     AHardwareBuffer_Desc desc = GetParam();
2587     desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
2588     const bool kPureStencil =
2589         desc.format == GL_STENCIL_INDEX8 || desc.format == AHARDWAREBUFFER_FORMAT_S8_UINT;
2590     // Pure stencil textures are only supported with an extension. Note: we don't exit for the
2591     // AHB format here, because we want to ensure that buffer allocation fails with the
2592     // GPU_SAMPLED_IMAGE usage flag if the implementation doesn't support pure stencil textures.
2593     if (desc.format == GL_STENCIL_INDEX8 && !HasGLExtension("GL_OES_texture_stencil8")) return;
2594     // Stencil sampling from depth-stencil textures was introduced in ES 3.1.
2595     if (!kPureStencil && mGLVersion < 31) return;
2596     if (!SetUpBuffer(desc)) return;
2597 
2598     const int kTextureUnit = 8 % mMaxTextureUnits;
2599     for (int i = 0; i < mContextCount; ++i) {
2600         MakeCurrent(i);
2601         ASSERT_NO_FATAL_FAILURE(SetUpTexture(desc, kTextureUnit));
2602         glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2603         glTexParameteri(mTexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2604         if (!kPureStencil) {
2605             glTexParameteri(mTexTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
2606         }
2607     }
2608 
2609     // In the second context, clear the stencil buffer to a checkerboard pattern.
2610     ASSERT_NO_FATAL_FAILURE(
2611         SetUpFramebuffer(desc.width, desc.height, desc.layers - 1,
2612                          kNone, kNone, kBufferAsTexture));
2613     DrawCheckerboard(desc.width, desc.height, desc.format);
2614     glFinish();
2615     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2616 
2617     // In the first context, reconstruct the checkerboard with a special shader.
2618     MakeCurrent(0);
2619     ASSERT_NO_FATAL_FAILURE(
2620         SetUpProgram(std::string("#version 300 es") + kVertexShaderEs3x,
2621                      desc.layers > 1 ? kStencilArrayFragmentShaderEs30 : kStencilFragmentShaderEs30,
2622                      kQuadPositions, 1.f, kTextureUnit));
2623     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(40, 40, 0, kRenderbuffer));
2624     glDrawArrays(GL_TRIANGLES, 0, kQuadVertexCount);
2625     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2626 
2627     // Check golden pixels.
2628     std::vector<GoldenPixel> goldens{
2629         {5, 35, kRed},  {15, 35, kRed},  {25, 35, kBlue},  {35, 35, kBlue},
2630         {5, 25, kRed},  {15, 25, kRed},  {25, 25, kBlue},  {35, 25, kBlue},
2631         {5, 15, kZero}, {15, 15, kZero}, {25, 15, kGreen}, {35, 15, kGreen},
2632         {5, 5,  kZero}, {15, 5,  kZero}, {25, 5,  kGreen}, {35, 5,  kGreen},
2633     };
2634     CheckGoldenPixels(goldens, GL_RGBA8);
2635 }
2636 
2637 // The 'stride' field is used to pass a combination of TestFlags.
2638 INSTANTIATE_TEST_CASE_P(
2639     SingleLayer, StencilTest,
2640     ::testing::Values(
2641         AHardwareBuffer_Desc{49, 57, 1, GL_STENCIL_INDEX8, 0, kGlFormat, 0, 0},
2642         AHardwareBuffer_Desc{36, 50, 1, GL_DEPTH24_STENCIL8, 0, kGlFormat, 0, 0},
2643         AHardwareBuffer_Desc{26, 29, 1, AHARDWAREBUFFER_FORMAT_S8_UINT, 0, 0, 0, 0},
2644         AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
2645         AHardwareBuffer_Desc{17, 23, 1, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}),
2646     &GetTestName);
2647 
2648 INSTANTIATE_TEST_CASE_P(
2649     MultipleLayers, StencilTest,
2650     ::testing::Values(
2651         AHardwareBuffer_Desc{49, 57, 3, GL_STENCIL_INDEX8, 0, kGlFormat, 0, 0},
2652         AHardwareBuffer_Desc{36, 50, 6, GL_DEPTH24_STENCIL8, 0, kGlFormat, 0, 0},
2653         AHardwareBuffer_Desc{26, 29, 5, AHARDWAREBUFFER_FORMAT_S8_UINT, 0, 0, 0, 0},
2654         AHardwareBuffer_Desc{57, 33, 4, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
2655         AHardwareBuffer_Desc{17, 23, 7, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}),
2656     &GetTestName);
2657 
2658 class R8Test : public AHardwareBufferGLTest {};
2659 
2660 // Verify that if we can allocate an R8 AHB we can render to it.
TEST_P(R8Test,Write)2661 TEST_P(R8Test, Write) {
2662     AHardwareBuffer_Desc desc = GetParam();
2663     desc.usage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
2664     if (!SetUpBuffer(desc)) {
2665         return;
2666     }
2667 
2668     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(desc.width, desc.height, 0, kBufferAsRenderbuffer));
2669     ASSERT_NO_FATAL_FAILURE(
2670         SetUpProgram(kVertexShader, kColorFragmentShader, kPyramidPositions, 0.5f));
2671 
2672     glDrawArrays(GL_TRIANGLES, 0, kPyramidVertexCount);
2673     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2674 }
2675 
2676 INSTANTIATE_TEST_CASE_P(
2677     SingleLayer, R8Test,
2678     ::testing::Values(
2679         AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_R8_UNORM, 0, 0, 0, 0}),
2680     &GetTestName);
2681 
2682 class R16UITest : public AHardwareBufferGLTest {};
2683 
2684 // Verify that if we can allocate an R16_UINT AHB we can render to it.
TEST_P(R16UITest,Write)2685 TEST_P(R16UITest, Write) {
2686     AHardwareBuffer_Desc desc = GetParam();
2687     desc.usage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
2688     if (!SetUpBuffer(desc)) {
2689         return;
2690     }
2691 
2692     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(desc.width, desc.height, 0, kBufferAsRenderbuffer));
2693     ASSERT_NO_FATAL_FAILURE(
2694         SetUpProgram(kVertexShader, kColorFragmentShader, kPyramidPositions, 0.5f));
2695 
2696     glDrawArrays(GL_TRIANGLES, 0, kPyramidVertexCount);
2697     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2698 }
2699 
2700 INSTANTIATE_TEST_CASE_P(
2701     SingleLayer, R16UITest,
2702     ::testing::Values(
2703         AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_R16_UINT, 0, 0, 0, 0}),
2704     &GetTestName);
2705 
2706 class RG16UITest : public AHardwareBufferGLTest {};
2707 
2708 // Verify that if we can allocate an R16G16_UINT AHB we can render to it.
TEST_P(RG16UITest,Write)2709 TEST_P(RG16UITest, Write) {
2710     AHardwareBuffer_Desc desc = GetParam();
2711     desc.usage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
2712     if (!SetUpBuffer(desc)) {
2713         return;
2714     }
2715 
2716     ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(desc.width, desc.height, 0, kBufferAsRenderbuffer));
2717     ASSERT_NO_FATAL_FAILURE(
2718         SetUpProgram(kVertexShader, kColorFragmentShader, kPyramidPositions, 0.5f));
2719 
2720     glDrawArrays(GL_TRIANGLES, 0, kPyramidVertexCount);
2721     ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
2722 }
2723 
2724 INSTANTIATE_TEST_CASE_P(
2725     SingleLayer, RG16UITest,
2726     ::testing::Values(
2727         AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_R16G16_UINT, 0, 0, 0, 0}),
2728     &GetTestName);
2729 
2730 }  // namespace android
2731