Bug 1649354 - Add android Fence handling to Compositor r=jnicol
AHardwareBuffer requests to handle android fences. There are 2 type of fences, release fence and acquire fence. Some ideas were borrowed from b2g's FenceHandle implementation. The release fence is a fence that is used for waiting until usage/composite of AHardwareBuffer is ended. It needs to be delivered from host side to client side. It is delivered via ImageBridge, since some TextureClientd str recycled without recycle callback. The acquire fence is a fence that is used for waiting until rendering to its AHardwareBuffer is completed. It is delivered from client side to host side. Differential Revision: https://phabricator.services.mozilla.com/D87298
This commit is contained in:
@@ -727,8 +727,8 @@ AndroidHardwareBufferTextureHost::Create(
|
||||
TextureFlags aFlags, const SurfaceDescriptorAndroidHardwareBuffer& aDesc) {
|
||||
RefPtr<AndroidHardwareBuffer> buffer =
|
||||
AndroidHardwareBuffer::FromFileDescriptor(
|
||||
const_cast<ipc::FileDescriptor&>(aDesc.handle()), aDesc.size(),
|
||||
aDesc.format());
|
||||
const_cast<ipc::FileDescriptor&>(aDesc.handle()), aDesc.bufferId(),
|
||||
aDesc.size(), aDesc.format());
|
||||
if (!buffer) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -852,6 +852,29 @@ gl::GLContext* AndroidHardwareBufferTextureHost::gl() const {
|
||||
}
|
||||
|
||||
bool AndroidHardwareBufferTextureHost::Lock() {
|
||||
if (!mAndroidHardwareBuffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fenceFd = mAndroidHardwareBuffer->GetAndResetAcquireFence();
|
||||
if (fenceFd.IsValid()) {
|
||||
const auto& gle = gl::GLContextEGL::Cast(gl());
|
||||
const auto& egl = gle->mEgl;
|
||||
|
||||
auto rawFD = fenceFd.TakePlatformHandle();
|
||||
const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID,
|
||||
rawFD.get(), LOCAL_EGL_NONE};
|
||||
|
||||
EGLSync sync =
|
||||
egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
|
||||
if (sync) {
|
||||
egl->fClientWaitSync(sync, 0, LOCAL_EGL_FOREVER);
|
||||
egl->fDestroySync(sync);
|
||||
} else {
|
||||
gfxCriticalNote << "Failed to create EGLSync from acquire fence fd";
|
||||
}
|
||||
}
|
||||
|
||||
return mTextureSource && mTextureSource->IsValid();
|
||||
}
|
||||
|
||||
@@ -896,6 +919,30 @@ void AndroidHardwareBufferTextureHost::DeallocateDeviceData() {
|
||||
DestroyEGLImage();
|
||||
}
|
||||
|
||||
void AndroidHardwareBufferTextureHost::SetAcquireFence(
|
||||
mozilla::ipc::FileDescriptor&& aFenceFd) {
|
||||
if (!mAndroidHardwareBuffer) {
|
||||
return;
|
||||
}
|
||||
mAndroidHardwareBuffer->SetAcquireFence(std::move(aFenceFd));
|
||||
}
|
||||
|
||||
void AndroidHardwareBufferTextureHost::SetReleaseFence(
|
||||
mozilla::ipc::FileDescriptor&& aFenceFd) {
|
||||
if (!mAndroidHardwareBuffer) {
|
||||
return;
|
||||
}
|
||||
mAndroidHardwareBuffer->SetReleaseFence(std::move(aFenceFd));
|
||||
}
|
||||
|
||||
mozilla::ipc::FileDescriptor
|
||||
AndroidHardwareBufferTextureHost::GetAndResetReleaseFence() {
|
||||
if (!mAndroidHardwareBuffer) {
|
||||
return mozilla::ipc::FileDescriptor();
|
||||
}
|
||||
return mAndroidHardwareBuffer->GetAndResetReleaseFence();
|
||||
}
|
||||
|
||||
void AndroidHardwareBufferTextureHost::CreateRenderTexture(
|
||||
const wr::ExternalImageId& aExternalImageId) {
|
||||
RefPtr<wr::RenderTextureHost> texture =
|
||||
@@ -1065,6 +1112,7 @@ bool EGLImageTextureHost::Lock() {
|
||||
|
||||
if (mSync) {
|
||||
MOZ_ASSERT(egl->IsExtensionSupported(EGLExtension::KHR_fence_sync));
|
||||
// XXX eglWaitSyncKHR() is better api. Bug 1660434 is going to fix it.
|
||||
status = egl->fClientWaitSync(mSync, 0, LOCAL_EGL_FOREVER);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user