Bug 1929180 - Add external semaphore handling to DMABufSurface r=stransky

This is a preparation for Bug 1920763.

Add capability of importing Vulkan external semaphore to DMABufSurface(OpenGL).

Differential Revision: https://phabricator.services.mozilla.com/D227916
This commit is contained in:
sotaro 2024-11-05 08:15:15 +00:00
parent 89f6006188
commit 8328357295
4 changed files with 58 additions and 2 deletions

View File

@ -85,6 +85,7 @@ namespace layers {
FileHandleWrapper[] fence;
uint32_t uid;
FileDescriptor[] refCount;
nullable FileHandleWrapper semaphoreFd;
};
[Comparable] struct SurfaceTextureDescriptor {

View File

@ -46,6 +46,10 @@ wr::WrExternalImage RenderDMABUFTextureHost::Lock(uint8_t aChannelIndex,
mSurface->GetTexture(aChannelIndex));
}
if (auto texture = mSurface->GetTexture(aChannelIndex)) {
mSurface->MaybeSemaphoreWait(texture);
}
const gfx::IntSize size(mSurface->GetWidth(aChannelIndex),
mSurface->GetHeight(aChannelIndex));
return NativeTextureToWrExternalImage(

View File

@ -345,6 +345,50 @@ void DMABufSurface::FenceWait() {
egl->fDestroySync(sync);
}
void DMABufSurface::MaybeSemaphoreWait(GLuint aGlTexture) {
MOZ_ASSERT(aGlTexture);
if (!mSemaphoreFd) {
return;
}
if (!mGL) {
MOZ_DIAGNOSTIC_ASSERT(mGL,
"DMABufSurface::SemaphoreWait() missing GL context!");
return;
}
if (!mGL->IsExtensionSupported(gl::GLContext::EXT_semaphore) ||
!mGL->IsExtensionSupported(gl::GLContext::EXT_semaphore_fd)) {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
gfxCriticalNoteOnce << "EXT_semaphore_fd is not suppored";
return;
}
auto fd = mSemaphoreFd->ClonePlatformHandle();
// No need to try mSemaphoreFd twice.
mSemaphoreFd = nullptr;
GLuint semaphoreHandle = 0;
mGL->fGenSemaphoresEXT(1, &semaphoreHandle);
mGL->fImportSemaphoreFdEXT(semaphoreHandle,
LOCAL_GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd.release());
auto error = mGL->fGetError();
if (error != LOCAL_GL_NO_ERROR) {
gfxCriticalNoteOnce << "glImportSemaphoreFdEXT failed: " << error;
return;
}
GLenum srcLayout = LOCAL_GL_LAYOUT_COLOR_ATTACHMENT_EXT;
mGL->fWaitSemaphoreEXT(semaphoreHandle, 0, nullptr, 1, &aGlTexture,
&srcLayout);
error = mGL->fGetError();
if (error != LOCAL_GL_NO_ERROR) {
gfxCriticalNoteOnce << "glWaitSemaphoreEXT failed: " << error;
return;
}
}
bool DMABufSurface::OpenFileDescriptors(const MutexAutoLock& aProofOfLock) {
for (int i = 0; i < mBufferPlaneCount; i++) {
if (!OpenFileDescriptorForPlane(aProofOfLock, i)) {
@ -609,6 +653,10 @@ bool DMABufSurfaceRGBA::ImportSurfaceDescriptor(
mSyncFd = new gfx::FileHandleWrapper(std::move(fd));
}
if (desc.semaphoreFd()) {
mSemaphoreFd = desc.semaphoreFd();
}
if (desc.refCount().Length() > 0) {
GlobalRefCountImport(desc.refCount()[0].ClonePlatformHandle().release());
}
@ -665,7 +713,7 @@ bool DMABufSurfaceRGBA::Serialize(
aOutDescriptor = SurfaceDescriptorDMABuf(
mSurfaceType, modifiers, mGbmBufferFlags, fds, width, height, width,
height, format, strides, offsets, GetYUVColorSpace(), mColorRange,
fenceFDs, mUID, refCountFDs);
fenceFDs, mUID, refCountFDs, /* semaphoreFd */ nullptr);
return true;
}
@ -1460,7 +1508,7 @@ bool DMABufSurfaceYUV::Serialize(
aOutDescriptor = SurfaceDescriptorDMABuf(
mSurfaceType, modifiers, 0, fds, width, height, widthBytes, heightBytes,
format, strides, offsets, GetYUVColorSpace(), mColorRange, fenceFDs, mUID,
refCountFDs);
refCountFDs, /* semaphoreFd */ nullptr);
return true;
}

View File

@ -135,6 +135,8 @@ class DMABufSurface {
void FenceWait();
void FenceDelete();
void MaybeSemaphoreWait(GLuint aGlTexture);
// Set and get a global surface UID. The UID is shared across process
// and it's used to track surface lifetime in various parts of rendering
// engine.
@ -217,6 +219,7 @@ class DMABufSurface {
RefPtr<mozilla::gfx::FileHandleWrapper> mSyncFd;
EGLSyncKHR mSync;
RefPtr<mozilla::gfx::FileHandleWrapper> mSemaphoreFd;
RefPtr<mozilla::gl::GLContext> mGL;
int mGlobalRefCountFd;