11
11
#include " test_utils/gl_raii.h"
12
12
#include " util/EGLWindow.h"
13
13
14
+ #include " common/android_util.h"
15
+
16
+ #if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26
17
+ # define ANGLE_AHARDWARE_BUFFER_SUPPORT
18
+ // NDK header file for access to Android Hardware Buffers
19
+ # include < android/hardware_buffer.h>
20
+ #endif
21
+
14
22
namespace angle
15
23
{
16
24
namespace
17
25
{
18
- constexpr char kOESExt [] = " GL_OES_EGL_image" ;
19
- constexpr char kExternalExt [] = " GL_OES_EGL_image_external" ;
20
- constexpr char kExternalESSL3Ext [] = " GL_OES_EGL_image_external_essl3" ;
21
- constexpr char kBaseExt [] = " EGL_KHR_image_base" ;
22
- constexpr char k2DTextureExt[] = " EGL_KHR_gl_texture_2D_image" ;
23
- constexpr char k3DTextureExt[] = " EGL_KHR_gl_texture_3D_image" ;
24
- constexpr char kPixmapExt [] = " EGL_KHR_image_pixmap" ;
25
- constexpr char kRenderbufferExt [] = " EGL_KHR_gl_renderbuffer_image" ;
26
- constexpr char kCubemapExt [] = " EGL_KHR_gl_texture_cubemap_image" ;
27
- constexpr char kImageGLColorspaceExt [] = " EGL_EXT_image_gl_colorspace" ;
28
- constexpr char kEGLImageArrayExt [] = " GL_EXT_EGL_image_array" ;
29
- constexpr EGLint kDefaultAttribs [] = {
26
+ constexpr char kOESExt [] = " GL_OES_EGL_image" ;
27
+ constexpr char kExternalExt [] = " GL_OES_EGL_image_external" ;
28
+ constexpr char kExternalESSL3Ext [] = " GL_OES_EGL_image_external_essl3" ;
29
+ constexpr char kBaseExt [] = " EGL_KHR_image_base" ;
30
+ constexpr char k2DTextureExt[] = " EGL_KHR_gl_texture_2D_image" ;
31
+ constexpr char k3DTextureExt[] = " EGL_KHR_gl_texture_3D_image" ;
32
+ constexpr char kPixmapExt [] = " EGL_KHR_image_pixmap" ;
33
+ constexpr char kRenderbufferExt [] = " EGL_KHR_gl_renderbuffer_image" ;
34
+ constexpr char kCubemapExt [] = " EGL_KHR_gl_texture_cubemap_image" ;
35
+ constexpr char kImageGLColorspaceExt [] = " EGL_EXT_image_gl_colorspace" ;
36
+ constexpr char kEGLImageArrayExt [] = " GL_EXT_EGL_image_array" ;
37
+ constexpr char kEGLAndroidImageNativeBufferExt [] = " EGL_ANDROID_image_native_buffer" ;
38
+ constexpr EGLint kDefaultAttribs [] = {
30
39
EGL_IMAGE_PRESERVED,
31
40
EGL_TRUE,
32
41
EGL_NONE,
@@ -382,6 +391,91 @@ class ImageTest : public ANGLETest
382
391
*outTargetTexture = target;
383
392
}
384
393
394
+ AHardwareBuffer *createAndroidHardwareBuffer (size_t width,
395
+ size_t height,
396
+ size_t depth,
397
+ int androidFormat,
398
+ const GLubyte *data,
399
+ size_t bytesPerPixel)
400
+ {
401
+ #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
402
+ // The height and width are number of pixels of size format
403
+ AHardwareBuffer_Desc aHardwareBufferDescription = {};
404
+ aHardwareBufferDescription.width = width;
405
+ aHardwareBufferDescription.height = height;
406
+ aHardwareBufferDescription.layers = depth;
407
+ aHardwareBufferDescription.format = androidFormat;
408
+ aHardwareBufferDescription.usage =
409
+ AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
410
+ aHardwareBufferDescription.stride = 0 ;
411
+ aHardwareBufferDescription.rfu0 = 0 ;
412
+ aHardwareBufferDescription.rfu1 = 0 ;
413
+
414
+ // Allocate memory from Android Hardware Buffer
415
+ AHardwareBuffer *aHardwareBuffer = nullptr ;
416
+ EXPECT_EQ (0 , AHardwareBuffer_allocate (&aHardwareBufferDescription, &aHardwareBuffer));
417
+
418
+ void *mappedMemory = nullptr ;
419
+ EXPECT_EQ (0 , AHardwareBuffer_lock (aHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY,
420
+ -1 , nullptr , &mappedMemory));
421
+
422
+ // Need to grab the stride the implementation might have enforced
423
+ AHardwareBuffer_describe (aHardwareBuffer, &aHardwareBufferDescription);
424
+ const uint32_t stride = aHardwareBufferDescription.stride ;
425
+
426
+ const uint32_t rowSize = bytesPerPixel * width;
427
+ for (uint32_t i = 0 ; i < height; i++)
428
+ {
429
+ uint32_t dstPtrOffset = stride * i * bytesPerPixel;
430
+ uint32_t srcPtrOffset = width * i * bytesPerPixel;
431
+
432
+ void *dst = reinterpret_cast <uint8_t *>(mappedMemory) + dstPtrOffset;
433
+ memcpy (dst, data + srcPtrOffset, rowSize);
434
+ }
435
+
436
+ EXPECT_EQ (0 , AHardwareBuffer_unlock (aHardwareBuffer, nullptr ));
437
+ AHardwareBuffer_acquire (aHardwareBuffer);
438
+ return aHardwareBuffer;
439
+ #else
440
+ return nullptr ;
441
+ #endif // ANGLE_PLATFORM_ANDROID
442
+ }
443
+
444
+ void destroyAndroidHardwareBuffer (AHardwareBuffer *aHardwarebuffer)
445
+ {
446
+ #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
447
+ AHardwareBuffer_release (aHardwarebuffer);
448
+ #endif
449
+ }
450
+
451
+ void createEGLImageAndroidHardwareBufferSource (size_t width,
452
+ size_t height,
453
+ size_t depth,
454
+ GLenum sizedInternalFormat,
455
+ const EGLint *attribs,
456
+ const GLubyte *data,
457
+ size_t bytesPerPixel,
458
+ AHardwareBuffer **outSourceAHB,
459
+ EGLImageKHR *outSourceImage)
460
+ {
461
+ // Set Android Memory
462
+ AHardwareBuffer *aHardwareBuffer = createAndroidHardwareBuffer (
463
+ width, height, depth,
464
+ angle::android::GLInternalFormatToNativePixelFormat (sizedInternalFormat), data,
465
+ bytesPerPixel);
466
+ EXPECT_NE (aHardwareBuffer, nullptr );
467
+
468
+ // Create an image from the source AHB
469
+ EGLWindow *window = getEGLWindow ();
470
+
471
+ EGLImageKHR image = eglCreateImageKHR (
472
+ window->getDisplay (), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
473
+ angle::android::AHardwareBufferToClientBuffer (aHardwareBuffer), attribs);
474
+ ASSERT_EGL_SUCCESS ();
475
+
476
+ *outSourceAHB = aHardwareBuffer;
477
+ *outSourceImage = image;
478
+ }
385
479
void createEGLImageTargetRenderbuffer (EGLImageKHR image, GLuint *outTargetRenderbuffer)
386
480
{
387
481
// Create a target texture from the image
@@ -396,6 +490,10 @@ class ImageTest : public ANGLETest
396
490
}
397
491
398
492
void ValidationGLEGLImage_helper (const EGLint *attribs);
493
+ void SourceAHBTarget2D_helper (const EGLint *attribs);
494
+ void SourceAHBTarget2DArray_helper (const EGLint *attribs);
495
+ void SourceAHBTargetExternal_helper (const EGLint *attribs);
496
+ void SourceAHBTargetExternalESSL3_helper (const EGLint *attribs);
399
497
void Source2DTarget2D_helper (const EGLint *attribs);
400
498
void Source2DTarget2DArray_helper (const EGLint *attribs);
401
499
void Source2DTargetRenderbuffer_helper (const EGLint *attribs);
@@ -484,6 +582,21 @@ class ImageTest : public ANGLETest
484
582
return IsEGLDisplayExtensionEnabled (getEGLWindow ()->getDisplay (), kImageGLColorspaceExt );
485
583
}
486
584
585
+ bool hasAndroidImageNativeBufferExt () const
586
+ {
587
+ return IsEGLDisplayExtensionEnabled (getEGLWindow ()->getDisplay (),
588
+ kEGLAndroidImageNativeBufferExt );
589
+ }
590
+
591
+ bool hasAndroidHardwareBufferSupport () const
592
+ {
593
+ #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
594
+ return true ;
595
+ #else
596
+ return false ;
597
+ #endif
598
+ }
599
+
487
600
bool hasEglImageArrayExt () const { return IsGLExtensionEnabled (kEGLImageArrayExt ); }
488
601
489
602
bool hasOESExt () const { return IsGLExtensionEnabled (kOESExt ); }
@@ -1242,6 +1355,7 @@ TEST_P(ImageTest, Source2DTarget2DArray_Colorspace)
1242
1355
ANGLE_SKIP_TEST_IF (!hasImageGLColorspaceExt ());
1243
1356
Source2DTarget2DArray_helper (kColorspaceAttribs );
1244
1357
}
1358
+
1245
1359
void ImageTest::Source2DTarget2DArray_helper (const EGLint *attribs)
1246
1360
{
1247
1361
ANGLE_SKIP_TEST_IF (IsAndroid () && IsOpenGLES ());
@@ -1269,6 +1383,185 @@ void ImageTest::Source2DTarget2DArray_helper(const EGLint *attribs)
1269
1383
glDeleteTextures (1 , &target);
1270
1384
}
1271
1385
1386
+ // Testing source AHB EGL image, target 2D texture
1387
+ TEST_P (ImageTest, SourceAHBTarget2D)
1388
+ {
1389
+ ANGLE_SKIP_TEST_IF (!IsAndroid ());
1390
+ SourceAHBTarget2D_helper (kDefaultAttribs );
1391
+ }
1392
+
1393
+ // Testing source AHB EGL image with colorspace, target 2D texture
1394
+ TEST_P (ImageTest, SourceAHBTarget2D_Colorspace)
1395
+ {
1396
+ ANGLE_SKIP_TEST_IF (!IsAndroid ());
1397
+ ANGLE_SKIP_TEST_IF (getClientMajorVersion () < 3 && !IsGLExtensionEnabled (" GL_EXT_sRGB" ));
1398
+ ANGLE_SKIP_TEST_IF (!hasImageGLColorspaceExt ());
1399
+ SourceAHBTarget2D_helper (kColorspaceAttribs );
1400
+ }
1401
+
1402
+ void ImageTest::SourceAHBTarget2D_helper (const EGLint *attribs)
1403
+ {
1404
+ EGLWindow *window = getEGLWindow ();
1405
+
1406
+ ANGLE_SKIP_TEST_IF (!hasOESExt () || !hasBaseExt () || !has2DTextureExt ());
1407
+ ANGLE_SKIP_TEST_IF (!hasAndroidImageNativeBufferExt () || !hasAndroidHardwareBufferSupport ());
1408
+
1409
+ GLubyte data[4 ] = {7 , 51 , 197 , 231 };
1410
+
1411
+ // Create the Image
1412
+ AHardwareBuffer *source;
1413
+ EGLImageKHR image;
1414
+ createEGLImageAndroidHardwareBufferSource (1 , 1 , 1 , GL_RGBA8, attribs, data, 4 , &source, &image);
1415
+
1416
+ // Create a texture target to bind the egl image
1417
+ GLuint target;
1418
+ createEGLImageTargetTexture2D (image, &target);
1419
+
1420
+ // Use texture target bound to egl image as source and render to framebuffer
1421
+ // Verify that data in framebuffer matches that in the egl image
1422
+ verifyResults2D (target, data);
1423
+
1424
+ // Clean up
1425
+ eglDestroyImageKHR (window->getDisplay (), image);
1426
+ destroyAndroidHardwareBuffer (source);
1427
+ glDeleteTextures (1 , &target);
1428
+ }
1429
+
1430
+ // Testing source AHB EGL image, target 2D array texture
1431
+ TEST_P (ImageTest, SourceAHBTarget2DArray)
1432
+ {
1433
+ ANGLE_SKIP_TEST_IF (!IsAndroid ());
1434
+ SourceAHBTarget2DArray_helper (kDefaultAttribs );
1435
+ }
1436
+
1437
+ // Testing source AHB EGL image with colorspace, target 2D array texture
1438
+ TEST_P (ImageTest, SourceAHBTarget2DArray_Colorspace)
1439
+ {
1440
+ ANGLE_SKIP_TEST_IF (!IsAndroid ());
1441
+ ANGLE_SKIP_TEST_IF (getClientMajorVersion () < 3 && !IsGLExtensionEnabled (" GL_EXT_sRGB" ));
1442
+ ANGLE_SKIP_TEST_IF (!hasImageGLColorspaceExt ());
1443
+ SourceAHBTarget2DArray_helper (kColorspaceAttribs );
1444
+ }
1445
+
1446
+ void ImageTest::SourceAHBTarget2DArray_helper (const EGLint *attribs)
1447
+ {
1448
+ EGLWindow *window = getEGLWindow ();
1449
+
1450
+ ANGLE_SKIP_TEST_IF (!hasOESExt () || !hasBaseExt () || !has2DTextureExt () ||
1451
+ !hasEglImageArrayExt ());
1452
+ ANGLE_SKIP_TEST_IF (!hasAndroidImageNativeBufferExt () || !hasAndroidHardwareBufferSupport ());
1453
+
1454
+ GLubyte data[4 ] = {7 , 51 , 197 , 231 };
1455
+
1456
+ // Create the Image
1457
+ AHardwareBuffer *source;
1458
+ EGLImageKHR image;
1459
+ createEGLImageAndroidHardwareBufferSource (1 , 1 , 1 , GL_RGBA8, attribs, data, 4 , &source, &image);
1460
+
1461
+ // Create a texture target to bind the egl image
1462
+ GLuint target;
1463
+ createEGLImageTargetTexture2DArray (image, &target);
1464
+
1465
+ // Use texture target bound to egl image as source and render to framebuffer
1466
+ // Verify that data in framebuffer matches that in the egl image
1467
+ verifyResults2DArray (target, data);
1468
+
1469
+ // Clean up
1470
+ eglDestroyImageKHR (window->getDisplay (), image);
1471
+ destroyAndroidHardwareBuffer (source);
1472
+ glDeleteTextures (1 , &target);
1473
+ }
1474
+
1475
+ // Testing source AHB EGL image, target external texture
1476
+ TEST_P (ImageTest, SourceAHBTargetExternal)
1477
+ {
1478
+ ANGLE_SKIP_TEST_IF (!IsAndroid ());
1479
+ SourceAHBTargetExternal_helper (kDefaultAttribs );
1480
+ }
1481
+
1482
+ // Testing source AHB EGL image with colorspace, target external texture
1483
+ TEST_P (ImageTest, SourceAHBTargetExternal_Colorspace)
1484
+ {
1485
+ ANGLE_SKIP_TEST_IF (!IsAndroid ());
1486
+ ANGLE_SKIP_TEST_IF (getClientMajorVersion () < 3 && !IsGLExtensionEnabled (" GL_EXT_sRGB" ));
1487
+ ANGLE_SKIP_TEST_IF (!hasImageGLColorspaceExt ());
1488
+ SourceAHBTargetExternal_helper (kColorspaceAttribs );
1489
+ }
1490
+
1491
+ void ImageTest::SourceAHBTargetExternal_helper (const EGLint *attribs)
1492
+ {
1493
+ EGLWindow *window = getEGLWindow ();
1494
+ ANGLE_SKIP_TEST_IF (!hasOESExt () || !hasBaseExt () || !has2DTextureExt () || !hasExternalExt ());
1495
+ ANGLE_SKIP_TEST_IF (!hasAndroidImageNativeBufferExt () || !hasAndroidHardwareBufferSupport ());
1496
+
1497
+ // Ozone only supports external target for images created with EGL_EXT_image_dma_buf_import
1498
+ ANGLE_SKIP_TEST_IF (IsOzone ());
1499
+
1500
+ GLubyte data[4 ] = {7 , 51 , 197 , 231 };
1501
+
1502
+ // Create the Image
1503
+ AHardwareBuffer *source;
1504
+ EGLImageKHR image;
1505
+ createEGLImageAndroidHardwareBufferSource (1 , 1 , 1 , GL_RGBA8, attribs, data, 4 , &source, &image);
1506
+
1507
+ // Create a texture target to bind the egl image
1508
+ GLuint target;
1509
+ createEGLImageTargetTextureExternal (image, &target);
1510
+
1511
+ // Use texture target bound to egl image as source and render to framebuffer
1512
+ // Verify that data in framebuffer matches that in the egl image
1513
+ verifyResultsExternal (target, data);
1514
+
1515
+ // Clean up
1516
+ eglDestroyImageKHR (window->getDisplay (), image);
1517
+ destroyAndroidHardwareBuffer (source);
1518
+ glDeleteTextures (1 , &target);
1519
+ }
1520
+
1521
+ // Testing source AHB EGL image, target external ESSL3 texture
1522
+ TEST_P (ImageTestES3, SourceAHBTargetExternalESSL3)
1523
+ {
1524
+ ANGLE_SKIP_TEST_IF (!IsAndroid ());
1525
+ SourceAHBTargetExternalESSL3_helper (kDefaultAttribs );
1526
+ }
1527
+
1528
+ // Testing source AHB EGL image with colorspace, target external ESSL3 texture
1529
+ TEST_P (ImageTestES3, SourceAHBTargetExternalESSL3_Colorspace)
1530
+ {
1531
+ ANGLE_SKIP_TEST_IF (!IsAndroid ());
1532
+ ANGLE_SKIP_TEST_IF (getClientMajorVersion () < 3 && !IsGLExtensionEnabled (" GL_EXT_sRGB" ));
1533
+ ANGLE_SKIP_TEST_IF (!hasImageGLColorspaceExt ());
1534
+ SourceAHBTargetExternalESSL3_helper (kColorspaceAttribs );
1535
+ }
1536
+
1537
+ void ImageTest::SourceAHBTargetExternalESSL3_helper (const EGLint *attribs)
1538
+ {
1539
+ EGLWindow *window = getEGLWindow ();
1540
+ ANGLE_SKIP_TEST_IF (!hasOESExt () || !hasBaseExt () || !has2DTextureExt () ||
1541
+ !hasExternalESSL3Ext ());
1542
+ ANGLE_SKIP_TEST_IF (!hasAndroidImageNativeBufferExt () || !hasAndroidHardwareBufferSupport ());
1543
+
1544
+ GLubyte data[4 ] = {7 , 51 , 197 , 231 };
1545
+
1546
+ // Create the Image
1547
+ AHardwareBuffer *source;
1548
+ EGLImageKHR image;
1549
+ createEGLImageAndroidHardwareBufferSource (1 , 1 , 1 , GL_RGBA8, attribs, data, 4 , &source, &image);
1550
+
1551
+ // Create a texture target to bind the egl image
1552
+ GLuint target;
1553
+ createEGLImageTargetTextureExternal (image, &target);
1554
+
1555
+ // Use texture target bound to egl image as source and render to framebuffer
1556
+ // Verify that data in framebuffer matches that in the egl image
1557
+ verifyResultsExternalESSL3 (target, data);
1558
+
1559
+ // Clean up
1560
+ eglDestroyImageKHR (window->getDisplay (), image);
1561
+ destroyAndroidHardwareBuffer (source);
1562
+ glDeleteTextures (1 , &target);
1563
+ }
1564
+
1272
1565
TEST_P (ImageTest, Source2DTargetRenderbuffer)
1273
1566
{
1274
1567
Source2DTargetRenderbuffer_helper (kDefaultAttribs );
0 commit comments