Hash :
5b419533
Author :
Date :
2020-11-03T13:33:44
GL: Implement EXT_YUV_target Add test coverage of YUV format sampling as RGB or directly as YUV and rendering as YUV using layout(yuv). Initializing YUV AHardwareBuffers requires Android API 29 so ANGLE must be compiled with: android32_ndk_api_level = 29 android64_ndk_api_level = 29 The following tests can still run with Android API 26 because they don't need to initialize the buffer: ImageTestES3.ClearYUVAHB ImageTestES3.YUVValidation Bug: angleproject:4852 Bug: b/172649538 Change-Id: I4fe9afb2a68fb827dc5a5732b213b5eb60d585ac Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2517562 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
//
// Copyright The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DmaBufImageSiblingEGL.cpp: Defines the DmaBufImageSiblingEGL to wrap EGL images
// created from dma_buf objects
#include "libANGLE/renderer/gl/egl/DmaBufImageSiblingEGL.h"
namespace
{
// Refer to the following link
// https://source.chromium.org/chromium/chromium/src/+/master:ui/gl/gl_image_native_pixmap.cc;l=24
#define FOURCC(a, b, c, d) \
((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \
(static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24))
#define DRM_FORMAT_R8 FOURCC('R', '8', ' ', ' ')
#define DRM_FORMAT_R16 FOURCC('R', '1', '6', ' ')
#define DRM_FORMAT_GR88 FOURCC('G', 'R', '8', '8')
#define DRM_FORMAT_RGB565 FOURCC('R', 'G', '1', '6')
#define DRM_FORMAT_ARGB8888 FOURCC('A', 'R', '2', '4')
#define DRM_FORMAT_ABGR8888 FOURCC('A', 'B', '2', '4')
#define DRM_FORMAT_XRGB8888 FOURCC('X', 'R', '2', '4')
#define DRM_FORMAT_XBGR8888 FOURCC('X', 'B', '2', '4')
#define DRM_FORMAT_ABGR2101010 FOURCC('A', 'B', '3', '0')
#define DRM_FORMAT_ARGB2101010 FOURCC('A', 'R', '3', '0')
#define DRM_FORMAT_YVU420 FOURCC('Y', 'V', '1', '2')
#define DRM_FORMAT_NV12 FOURCC('N', 'V', '1', '2')
#define DRM_FORMAT_P010 FOURCC('P', '0', '1', '0')
GLenum FourCCFormatToGLInternalFormat(int format, bool *isYUV)
{
*isYUV = false;
switch (format)
{
case DRM_FORMAT_R8:
return GL_R8;
case DRM_FORMAT_R16:
return GL_R16_EXT;
case DRM_FORMAT_GR88:
return GL_RG8_EXT;
case DRM_FORMAT_ABGR8888:
return GL_RGBA8;
case DRM_FORMAT_XBGR8888:
return GL_RGB8;
case DRM_FORMAT_ARGB8888:
return GL_BGRA8_EXT;
case DRM_FORMAT_XRGB8888:
return GL_RGB8;
case DRM_FORMAT_ABGR2101010:
case DRM_FORMAT_ARGB2101010:
return GL_RGB10_A2_EXT;
case DRM_FORMAT_RGB565:
return GL_RGB565;
case DRM_FORMAT_NV12:
case DRM_FORMAT_YVU420:
case DRM_FORMAT_P010:
*isYUV = true;
return GL_RGB8;
default:
NOTREACHED();
WARN() << "Unknown dma_buf format " << format << " used to initialize an EGL image.";
return GL_RGB8;
}
}
} // namespace
namespace rx
{
DmaBufImageSiblingEGL::DmaBufImageSiblingEGL(const egl::AttributeMap &attribs)
: mAttribs(attribs), mFormat(GL_NONE), mYUV(false)
{
ASSERT(mAttribs.contains(EGL_WIDTH));
mSize.width = mAttribs.getAsInt(EGL_WIDTH);
ASSERT(mAttribs.contains(EGL_HEIGHT));
mSize.height = mAttribs.getAsInt(EGL_HEIGHT);
mSize.depth = 1;
int fourCCFormat = mAttribs.getAsInt(EGL_LINUX_DRM_FOURCC_EXT);
mFormat = gl::Format(FourCCFormatToGLInternalFormat(fourCCFormat, &mYUV));
}
DmaBufImageSiblingEGL::~DmaBufImageSiblingEGL() {}
egl::Error DmaBufImageSiblingEGL::initialize(const egl::Display *display)
{
return egl::NoError();
}
gl::Format DmaBufImageSiblingEGL::getFormat() const
{
return mFormat;
}
bool DmaBufImageSiblingEGL::isRenderable(const gl::Context *context) const
{
return true;
}
bool DmaBufImageSiblingEGL::isTexturable(const gl::Context *context) const
{
return true;
}
bool DmaBufImageSiblingEGL::isYUV() const
{
return mYUV;
}
gl::Extents DmaBufImageSiblingEGL::getSize() const
{
return mSize;
}
size_t DmaBufImageSiblingEGL::getSamples() const
{
return 0;
}
EGLClientBuffer DmaBufImageSiblingEGL::getBuffer() const
{
return nullptr;
}
void DmaBufImageSiblingEGL::getImageCreationAttributes(std::vector<EGLint> *outAttributes) const
{
EGLenum kForwardedAttribs[] = {EGL_WIDTH,
EGL_HEIGHT,
EGL_LINUX_DRM_FOURCC_EXT,
EGL_DMA_BUF_PLANE0_FD_EXT,
EGL_DMA_BUF_PLANE0_OFFSET_EXT,
EGL_DMA_BUF_PLANE0_PITCH_EXT,
EGL_DMA_BUF_PLANE1_FD_EXT,
EGL_DMA_BUF_PLANE1_OFFSET_EXT,
EGL_DMA_BUF_PLANE1_PITCH_EXT,
EGL_DMA_BUF_PLANE2_FD_EXT,
EGL_DMA_BUF_PLANE2_OFFSET_EXT,
EGL_DMA_BUF_PLANE2_PITCH_EXT,
EGL_YUV_COLOR_SPACE_HINT_EXT,
EGL_SAMPLE_RANGE_HINT_EXT,
EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT,
EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT,
EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT,
EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT,
EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT,
EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT,
EGL_DMA_BUF_PLANE3_FD_EXT,
EGL_DMA_BUF_PLANE3_OFFSET_EXT,
EGL_DMA_BUF_PLANE3_PITCH_EXT,
EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT,
EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT};
for (EGLenum forwardedAttrib : kForwardedAttribs)
{
if (mAttribs.contains(forwardedAttrib))
{
outAttributes->push_back(forwardedAttrib);
outAttributes->push_back(mAttribs.getAsInt(forwardedAttrib));
}
}
}
} // namespace rx