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