Commit 85ae836f by Jiajia Qin Committed by Commit Bot

GL: Implement EGL_EXT_image_dma_buf_import

Add support for the EGL_EXT_image_dma_buf_import on EGL implementations that support it natively. This extensin is used on ozone to import native compositing buffers. This patch also adds new tokens in EGL_EXT_image_dma_buf_import_modifiers which are used in eglCreateImageKHR. BUG=angleproject:4529 Change-Id: I49bff831b591fb19fcdcec1145c7a61f5d8020c4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2128190 Commit-Queue: Jiajia Qin <jiajia.qin@intel.com> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent a56537a3
...@@ -1155,6 +1155,7 @@ bool IsExternalImageTarget(EGLenum target) ...@@ -1155,6 +1155,7 @@ bool IsExternalImageTarget(EGLenum target)
{ {
case EGL_NATIVE_BUFFER_ANDROID: case EGL_NATIVE_BUFFER_ANDROID:
case EGL_D3D11_TEXTURE_ANGLE: case EGL_D3D11_TEXTURE_ANGLE:
case EGL_LINUX_DMA_BUF_EXT:
return true; return true;
default: default:
......
...@@ -1385,6 +1385,9 @@ std::vector<std::string> DisplayExtensions::getStrings() const ...@@ -1385,6 +1385,9 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_KHR_no_config_context", noConfigContext, &extensionStrings); InsertExtensionString("EGL_KHR_no_config_context", noConfigContext, &extensionStrings);
InsertExtensionString("EGL_IMG_context_priority", contextPriority, &extensionStrings); InsertExtensionString("EGL_IMG_context_priority", contextPriority, &extensionStrings);
InsertExtensionString("EGL_KHR_create_context_no_error", createContextNoError, &extensionStrings); InsertExtensionString("EGL_KHR_create_context_no_error", createContextNoError, &extensionStrings);
InsertExtensionString("EGL_EXT_image_dma_buf_import", imageDmaBufImportEXT, &extensionStrings);
InsertExtensionString("EGL_EXT_image_dma_buf_import_modifiers", imageDmaBufImportModifiersEXT, &extensionStrings);
// clang-format on // clang-format on
return extensionStrings; return extensionStrings;
......
...@@ -1057,6 +1057,12 @@ struct DisplayExtensions ...@@ -1057,6 +1057,12 @@ struct DisplayExtensions
// EGL_EXT_image_gl_colorspace // EGL_EXT_image_gl_colorspace
bool imageGlColorspace = false; bool imageGlColorspace = false;
// EGL_EXT_image_dma_buf_import
bool imageDmaBufImportEXT = false;
// EGL_EXT_image_dma_buf_import_modifiers
bool imageDmaBufImportModifiersEXT = false;
}; };
struct DeviceExtensions struct DeviceExtensions
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "libANGLE/renderer/gl/ContextGL.h" #include "libANGLE/renderer/gl/ContextGL.h"
#include "libANGLE/renderer/gl/RendererGL.h" #include "libANGLE/renderer/gl/RendererGL.h"
#include "libANGLE/renderer/gl/egl/ContextEGL.h" #include "libANGLE/renderer/gl/egl/ContextEGL.h"
#include "libANGLE/renderer/gl/egl/DmaBufImageSiblingEGL.h"
#include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h" #include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h"
#include "libANGLE/renderer/gl/egl/ImageEGL.h" #include "libANGLE/renderer/gl/egl/ImageEGL.h"
#include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h" #include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h"
...@@ -644,6 +645,11 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -644,6 +645,11 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->framebufferTargetANDROID = mEGL->hasExtension("EGL_ANDROID_framebuffer_target"); outExtensions->framebufferTargetANDROID = mEGL->hasExtension("EGL_ANDROID_framebuffer_target");
outExtensions->imageDmaBufImportEXT = mEGL->hasExtension("EGL_EXT_image_dma_buf_import");
outExtensions->imageDmaBufImportModifiersEXT =
mEGL->hasExtension("EGL_EXT_image_dma_buf_import_modifiers");
DisplayGL::generateExtensions(outExtensions); DisplayGL::generateExtensions(outExtensions);
} }
...@@ -712,4 +718,36 @@ void DisplayEGL::populateFeatureList(angle::FeatureList *features) ...@@ -712,4 +718,36 @@ void DisplayEGL::populateFeatureList(angle::FeatureList *features)
mRenderer->getFeatures().populateFeatureList(features); mRenderer->getFeatures().populateFeatureList(features);
} }
egl::Error DisplayEGL::validateImageClientBuffer(const gl::Context *context,
EGLenum target,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const
{
switch (target)
{
case EGL_LINUX_DMA_BUF_EXT:
return egl::NoError();
default:
return DisplayGL::validateImageClientBuffer(context, target, clientBuffer, attribs);
}
}
ExternalImageSiblingImpl *DisplayEGL::createExternalImageSibling(const gl::Context *context,
EGLenum target,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs)
{
switch (target)
{
case EGL_LINUX_DMA_BUF_EXT:
ASSERT(context == nullptr);
ASSERT(buffer == nullptr);
return new DmaBufImageSiblingEGL(attribs);
default:
return DisplayGL::createExternalImageSibling(context, target, buffer, attribs);
}
}
} // namespace rx } // namespace rx
...@@ -90,6 +90,16 @@ class DisplayEGL : public DisplayGL ...@@ -90,6 +90,16 @@ class DisplayEGL : public DisplayGL
void populateFeatureList(angle::FeatureList *features) override; void populateFeatureList(angle::FeatureList *features) override;
egl::Error validateImageClientBuffer(const gl::Context *context,
EGLenum target,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const override;
ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
EGLenum target,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs) override;
protected: protected:
egl::Error initializeContext(EGLContext shareContext, egl::Error initializeContext(EGLContext shareContext,
const egl::AttributeMap &eglAttributes, const egl::AttributeMap &eglAttributes,
......
//
// 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 rx
{
DmaBufImageSiblingEGL::DmaBufImageSiblingEGL(const egl::AttributeMap &attribs)
: mAttribs(attribs), mFormat(GL_NONE)
{
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;
// TODO(geofflang): Implement a conversion table from DRM_FORMAT_* to GL format to expose a
// valid mFormat to know if this image can be rendered to. For now it's fine to always say we're
// RGBA8. http://anglebug.com/4529
mFormat = gl::Format(GL_RGBA8);
}
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;
}
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
//
// 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.h: Defines the DmaBufImageSiblingEGL to wrap EGL images
// created from dma_buf objects
#ifndef LIBANGLE_RENDERER_GL_EGL_DMABUFIMAGESIBLINGEGL_H_
#define LIBANGLE_RENDERER_GL_EGL_DMABUFIMAGESIBLINGEGL_H_
#include "libANGLE/renderer/gl/egl/ExternalImageSiblingEGL.h"
namespace rx
{
class DmaBufImageSiblingEGL : public ExternalImageSiblingEGL
{
public:
DmaBufImageSiblingEGL(const egl::AttributeMap &attribs);
~DmaBufImageSiblingEGL() override;
egl::Error initialize(const egl::Display *display) override;
// ExternalImageSiblingImpl interface
gl::Format getFormat() const override;
bool isRenderable(const gl::Context *context) const override;
bool isTexturable(const gl::Context *context) const override;
gl::Extents getSize() const override;
size_t getSamples() const override;
// ExternalImageSiblingEGL interface
EGLClientBuffer getBuffer() const override;
void getImageCreationAttributes(std::vector<EGLint> *outAttributes) const override;
private:
egl::AttributeMap mAttribs;
gl::Extents mSize;
gl::Format mFormat;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_EGL_DMABUFIMAGESIBLINGEGL_H_
...@@ -22,6 +22,7 @@ class ExternalImageSiblingEGL : public ExternalImageSiblingImpl ...@@ -22,6 +22,7 @@ class ExternalImageSiblingEGL : public ExternalImageSiblingImpl
~ExternalImageSiblingEGL() override {} ~ExternalImageSiblingEGL() override {}
virtual EGLClientBuffer getBuffer() const = 0; virtual EGLClientBuffer getBuffer() const = 0;
virtual void getImageCreationAttributes(std::vector<EGLint> *outAttributes) const {}
}; };
} // namespace rx } // namespace rx
......
...@@ -78,6 +78,9 @@ egl::Error ImageEGL::initialize(const egl::Display *display) ...@@ -78,6 +78,9 @@ egl::Error ImageEGL::initialize(const egl::Display *display)
GetImplAs<ExternalImageSiblingEGL>(GetAs<egl::ExternalImageSibling>(mState.source)); GetImplAs<ExternalImageSiblingEGL>(GetAs<egl::ExternalImageSibling>(mState.source));
buffer = externalImageSibling->getBuffer(); buffer = externalImageSibling->getBuffer();
mNativeInternalFormat = externalImageSibling->getFormat().info->sizedInternalFormat; mNativeInternalFormat = externalImageSibling->getFormat().info->sizedInternalFormat;
// Add any additional attributes this type of image sibline requires
externalImageSibling->getImageCreationAttributes(&attributes);
} }
else else
{ {
......
...@@ -932,6 +932,7 @@ egl::ConfigSet DisplayOzone::generateConfigs() ...@@ -932,6 +932,7 @@ egl::ConfigSet DisplayOzone::generateConfigs()
egl::ConfigSet configs; egl::ConfigSet configs;
egl::Config config; egl::Config config;
config.bufferSize = 32;
config.redSize = 8; config.redSize = 8;
config.greenSize = 8; config.greenSize = 8;
config.blueSize = 8; config.blueSize = 8;
......
...@@ -2165,6 +2165,109 @@ Error ValidateCreateImage(const Display *display, ...@@ -2165,6 +2165,109 @@ Error ValidateCreateImage(const Display *display,
} }
break; break;
case EGL_WIDTH:
case EGL_HEIGHT:
if (target != EGL_LINUX_DMA_BUF_EXT)
{
return EglBadParameter()
<< "Parameter cannot be used if target is not EGL_LINUX_DMA_BUF_EXT";
}
break;
case EGL_LINUX_DRM_FOURCC_EXT:
case EGL_DMA_BUF_PLANE0_FD_EXT:
case EGL_DMA_BUF_PLANE0_OFFSET_EXT:
case EGL_DMA_BUF_PLANE0_PITCH_EXT:
case EGL_DMA_BUF_PLANE1_FD_EXT:
case EGL_DMA_BUF_PLANE1_OFFSET_EXT:
case EGL_DMA_BUF_PLANE1_PITCH_EXT:
case EGL_DMA_BUF_PLANE2_FD_EXT:
case EGL_DMA_BUF_PLANE2_OFFSET_EXT:
case EGL_DMA_BUF_PLANE2_PITCH_EXT:
if (!displayExtensions.imageDmaBufImportEXT)
{
return EglBadParameter() << "Parameter cannot be used without "
"EGL_EXT_image_dma_buf_import support.";
}
break;
case EGL_YUV_COLOR_SPACE_HINT_EXT:
if (!displayExtensions.imageDmaBufImportEXT)
{
return EglBadParameter() << "Parameter cannot be used without "
"EGL_EXT_image_dma_buf_import support.";
}
switch (value)
{
case EGL_ITU_REC601_EXT:
case EGL_ITU_REC709_EXT:
case EGL_ITU_REC2020_EXT:
break;
default:
return EglBadParameter()
<< "Invalid value for EGL_YUV_COLOR_SPACE_HINT_EXT.";
}
break;
case EGL_SAMPLE_RANGE_HINT_EXT:
if (!displayExtensions.imageDmaBufImportEXT)
{
return EglBadParameter() << "Parameter cannot be used without "
"EGL_EXT_image_dma_buf_import support.";
}
switch (value)
{
case EGL_YUV_FULL_RANGE_EXT:
case EGL_YUV_NARROW_RANGE_EXT:
break;
default:
return EglBadParameter() << "Invalid value for EGL_SAMPLE_RANGE_HINT_EXT.";
}
break;
case EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT:
case EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT:
if (!displayExtensions.imageDmaBufImportEXT)
{
return EglBadParameter() << "Parameter cannot be used without "
"EGL_EXT_image_dma_buf_import support.";
}
switch (value)
{
case EGL_YUV_CHROMA_SITING_0_EXT:
case EGL_YUV_CHROMA_SITING_0_5_EXT:
break;
default:
return EglBadParameter()
<< "Invalid value for EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT or "
"EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT.";
}
break;
case EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT:
case EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT:
case EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT:
case EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT:
case EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT:
case EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT:
case EGL_DMA_BUF_PLANE3_FD_EXT:
case EGL_DMA_BUF_PLANE3_OFFSET_EXT:
case EGL_DMA_BUF_PLANE3_PITCH_EXT:
case EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT:
case EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT:
if (!displayExtensions.imageDmaBufImportModifiersEXT)
{
return EglBadParameter() << "Parameter cannot be used without "
"EGL_EXT_image_dma_buf_import_modifiers support.";
}
break;
default: default:
return EglBadParameter() return EglBadParameter()
<< "invalid attribute: 0x" << std::hex << std::uppercase << attribute; << "invalid attribute: 0x" << std::hex << std::uppercase << attribute;
...@@ -2373,6 +2476,67 @@ Error ValidateCreateImage(const Display *display, ...@@ -2373,6 +2476,67 @@ Error ValidateCreateImage(const Display *display,
ANGLE_TRY(display->validateImageClientBuffer(context, target, buffer, attributes)); ANGLE_TRY(display->validateImageClientBuffer(context, target, buffer, attributes));
break; break;
case EGL_LINUX_DMA_BUF_EXT:
if (!displayExtensions.imageDmaBufImportEXT)
{
return EglBadParameter() << "EGL_EXT_image_dma_buf_import not supported.";
}
if (context != nullptr)
{
return EglBadContext() << "ctx must be EGL_NO_CONTEXT.";
}
if (buffer != nullptr)
{
return EglBadParameter() << "buffer must be NULL.";
}
{
EGLenum kRequiredParameters[] = {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};
for (EGLenum requiredParameter : kRequiredParameters)
{
if (!attributes.contains(requiredParameter))
{
return EglBadParameter()
<< "Missing required parameter " << gl::FmtHex(requiredParameter)
<< " for image target EGL_LINUX_DMA_BUF_EXT.";
}
}
bool containPlane0ModifierLo =
attributes.contains(EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT);
bool containPlane0ModifierHi =
attributes.contains(EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT);
bool containPlane1ModifierLo =
attributes.contains(EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT);
bool containPlane1ModifierHi =
attributes.contains(EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT);
bool containPlane2ModifierLo =
attributes.contains(EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT);
bool containPlane2ModifierHi =
attributes.contains(EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT);
bool containPlane3ModifierLo =
attributes.contains(EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT);
bool containPlane3ModifierHi =
attributes.contains(EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT);
if ((containPlane0ModifierLo ^ containPlane0ModifierHi) ||
(containPlane1ModifierLo ^ containPlane1ModifierHi) ||
(containPlane2ModifierLo ^ containPlane2ModifierHi) ||
(containPlane3ModifierLo ^ containPlane3ModifierHi))
{
return EglBadParameter()
<< "the list of attributes contains EGL_DMA_BUF_PLANE*_MODIFIER_LO_EXT "
"but not EGL_DMA_BUF_PLANE*_MODIFIER_HI_EXT or vice versa.";
}
}
break;
default: default:
return EglBadParameter() return EglBadParameter()
<< "invalid target: 0x" << std::hex << std::uppercase << target; << "invalid target: 0x" << std::hex << std::uppercase << target;
......
...@@ -820,6 +820,8 @@ libangle_gl_egl_sources = [ ...@@ -820,6 +820,8 @@ libangle_gl_egl_sources = [
"src/libANGLE/renderer/gl/egl/ContextEGL.h", "src/libANGLE/renderer/gl/egl/ContextEGL.h",
"src/libANGLE/renderer/gl/egl/DisplayEGL.cpp", "src/libANGLE/renderer/gl/egl/DisplayEGL.cpp",
"src/libANGLE/renderer/gl/egl/DisplayEGL.h", "src/libANGLE/renderer/gl/egl/DisplayEGL.h",
"src/libANGLE/renderer/gl/egl/DmaBufImageSiblingEGL.cpp",
"src/libANGLE/renderer/gl/egl/DmaBufImageSiblingEGL.h",
"src/libANGLE/renderer/gl/egl/ExternalImageSiblingEGL.h", "src/libANGLE/renderer/gl/egl/ExternalImageSiblingEGL.h",
"src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp", "src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp",
"src/libANGLE/renderer/gl/egl/FunctionsEGL.h", "src/libANGLE/renderer/gl/egl/FunctionsEGL.h",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment