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