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