Reland "EGL: Implement EGL_EXT_image_dma_buf_import_modifiers"

This is a reland of commit 1d8dce2587

New changes:
 - fail softly on buggy drivers (which are part of the CI)

Original change's description:
> EGL: Implement EGL_EXT_image_dma_buf_import_modifiers
>
> This reverts Ifbb0a182171646df8161f6f42eafe2a476fea6b2 and implements
> the previously missing bits. Inspired by the corresponding Vulkan
> implementation.
>
> The extension is used by an upcoming Exo feature which was successfully
> tested with this patch, see
> https://chromium-review.googlesource.com/c/chromium/src/+/3857556
>
> Bug: angleproject:7664
> Change-Id: I951d1a787e1db3a77b19fcea6186b7aa0a29872f
> Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3904345
> Reviewed-by: Geoff Lang <geofflang@chromium.org>
> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>

Bug: angleproject:7664
Change-Id: I732fc9dad54366553987104fa035bde2afe08ecd
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3924350
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Robert Mader 2022-09-19 15:08:54 +02:00 коммит произвёл Angle LUCI CQ
Родитель 9925671c8b
Коммит f53eac299f
4 изменённых файлов: 116 добавлений и 1 удалений

Просмотреть файл

@ -1046,4 +1046,53 @@ const FunctionsEGL *DisplayEGL::getFunctionsEGL() const
return mEGL;
}
bool DisplayEGL::supportsDmaBufFormat(EGLint format) const
{
return std::find(std::begin(mDrmFormats), std::end(mDrmFormats), format) !=
std::end(mDrmFormats);
}
egl::Error DisplayEGL::queryDmaBufFormats(EGLint maxFormats, EGLint *formats, EGLint *numFormats)
{
if (!mDrmFormatsInitialized)
{
EGLint numFormatsInit = 0;
if (mEGL->queryDmaBufFormatsEXT(0, nullptr, &numFormatsInit) && numFormatsInit > 0)
{
mDrmFormats.resize(numFormatsInit);
if (!mEGL->queryDmaBufFormatsEXT(numFormatsInit, mDrmFormats.data(), &numFormatsInit))
{
mDrmFormats.resize(0);
}
}
mDrmFormatsInitialized = true;
}
EGLint formatsSize = static_cast<EGLint>(mDrmFormats.size());
*numFormats = formatsSize;
if (maxFormats > 0)
{
// Do not copy data beyond the limits of the vector
maxFormats = std::min(maxFormats, formatsSize);
std::memcpy(formats, mDrmFormats.data(), maxFormats * sizeof(EGLint));
}
return egl::NoError();
}
egl::Error DisplayEGL::queryDmaBufModifiers(EGLint drmFormat,
EGLint maxModifiers,
EGLuint64KHR *modifiers,
EGLBoolean *externalOnly,
EGLint *numModifiers)
{
if (!mEGL->queryDmaBufModifiersEXT(drmFormat, maxModifiers, modifiers, externalOnly,
numModifiers))
return egl::Error(mEGL->getError(), "eglQueryDmaBufModifiersEXT failed");
return egl::NoError();
}
} // namespace rx

Просмотреть файл

@ -106,6 +106,14 @@ class DisplayEGL : public DisplayGL
const FunctionsEGL *getFunctionsEGL() const;
bool supportsDmaBufFormat(EGLint format) const override;
egl::Error queryDmaBufFormats(EGLint maxFormats, EGLint *formats, EGLint *numFormats) override;
egl::Error queryDmaBufModifiers(EGLint format,
EGLint maxModifiers,
EGLuint64KHR *modifiers,
EGLBoolean *externalOnly,
EGLint *numModifiers) override;
protected:
virtual EGLint fixSurfaceType(EGLint surfaceType) const;
@ -165,6 +173,10 @@ class DisplayEGL : public DisplayGL
bool mSupportsNoConfigContexts = false;
EGLSurface mMockPbuffer = EGL_NO_SURFACE;
// Supported DRM formats
std::vector<EGLint> mDrmFormats;
bool mDrmFormatsInitialized = false;
};
} // namespace rx

Просмотреть файл

@ -85,7 +85,10 @@ struct FunctionsEGL::EGLDispatchTable
getFrameTimestampSupportedANDROIDPtr(nullptr),
getFrameTimestampsANDROIDPtr(nullptr),
dupNativeFenceFDANDROIDPtr(nullptr)
dupNativeFenceFDANDROIDPtr(nullptr),
queryDmaBufFormatsEXTPtr(nullptr),
queryDmaBufModifiersEXTPtr(nullptr)
{}
// 1.0
@ -148,6 +151,10 @@ struct FunctionsEGL::EGLDispatchTable
// EGL_ANDROID_native_fence_sync
PFNEGLDUPNATIVEFENCEFDANDROIDPROC dupNativeFenceFDANDROIDPtr;
// EGL_EXT_image_dma_buf_import_modifiers
PFNEGLQUERYDMABUFFORMATSEXTPROC queryDmaBufFormatsEXTPtr;
PFNEGLQUERYDMABUFMODIFIERSEXTPROC queryDmaBufModifiersEXTPtr;
};
FunctionsEGL::FunctionsEGL()
@ -291,6 +298,28 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay)
}
}
if (hasExtension("EGL_EXT_image_dma_buf_import_modifiers"))
{
// Some drivers, notably older versions of ANGLE, announce this extension without
// implementing the following functions. Fail softly in such cases.
// See anglebug.com/7664 for details.
if (!SetPtr(&mFnPtrs->queryDmaBufFormatsEXTPtr,
getProcAddress("eglQueryDmaBufFormatsEXT")) ||
!SetPtr(&mFnPtrs->queryDmaBufModifiersEXTPtr,
getProcAddress("eglQueryDmaBufModifiersEXT")))
{
mFnPtrs->queryDmaBufFormatsEXTPtr = nullptr;
mFnPtrs->queryDmaBufModifiersEXTPtr = nullptr;
mExtensions.erase(
std::remove_if(mExtensions.begin(), mExtensions.end(),
[](const std::string &extension) {
return extension.compare(
"EGL_EXT_image_dma_buf_import_modifiers") == 0;
}),
mExtensions.end());
}
}
#undef ANGLE_GET_PROC_OR_ERROR
return egl::NoError();
@ -595,4 +624,21 @@ EGLint FunctionsEGL::dupNativeFenceFDANDROID(EGLSync sync) const
return mFnPtrs->dupNativeFenceFDANDROIDPtr(mEGLDisplay, sync);
}
EGLint FunctionsEGL::queryDmaBufFormatsEXT(EGLint maxFormats,
EGLint *formats,
EGLint *numFormats) const
{
return mFnPtrs->queryDmaBufFormatsEXTPtr(mEGLDisplay, maxFormats, formats, numFormats);
}
EGLint FunctionsEGL::queryDmaBufModifiersEXT(EGLint format,
EGLint maxModifiers,
EGLuint64KHR *modifiers,
EGLBoolean *externalOnly,
EGLint *numModifiers) const
{
return mFnPtrs->queryDmaBufModifiersEXTPtr(mEGLDisplay, format, maxModifiers, modifiers,
externalOnly, numModifiers);
}
} // namespace rx

Просмотреть файл

@ -105,6 +105,14 @@ class FunctionsEGL
EGLint dupNativeFenceFDANDROID(EGLSync sync) const;
EGLint queryDmaBufFormatsEXT(EGLint maxFormats, EGLint *formats, EGLint *numFormats) const;
EGLint queryDmaBufModifiersEXT(EGLint format,
EGLint maxModifiers,
EGLuint64KHR *modifiers,
EGLBoolean *externalOnly,
EGLint *numModifiers) const;
private:
// So as to isolate from angle we do not include angleutils.h and cannot
// use angle::NonCopyable so we replicated it here instead.