Bug 1948890 - Use UniqueFileHandle for Android HardwareBuffer fences. r=gfx-reviewers,aosmond

We currently use ipc::FileDescriptor which is implicitly copyable, and
as a result we end up inadvertently duping the file descriptors in a few
places. This patch switches to UniqueFileHandle which makes cloning
explicit. This uncovers a few places where we were accidentally copying
the file descriptor, which this patch also fixes.

Differential Revision: https://phabricator.services.mozilla.com/D238595
This commit is contained in:
Jamie Nicol
2025-02-18 15:01:27 +00:00
parent d2d17b6243
commit 04e3dfee76
22 changed files with 88 additions and 126 deletions

View File

@@ -111,8 +111,7 @@ void SharedSurface_AndroidHardwareBuffer::ProducerReleaseImpl() {
MOZ_ASSERT(mSync); MOZ_ASSERT(mSync);
int rawFd = egl->fDupNativeFenceFDANDROID(mSync); int rawFd = egl->fDupNativeFenceFDANDROID(mSync);
if (rawFd >= 0) { if (rawFd >= 0) {
auto fenceFd = ipc::FileDescriptor(UniqueFileHandle(rawFd)); mAndroidHardwareBuffer->SetAcquireFence(UniqueFileHandle(rawFd));
mAndroidHardwareBuffer->SetAcquireFence(std::move(fenceFd));
} }
gl->fFlush(); gl->fFlush();
@@ -126,18 +125,16 @@ SharedSurface_AndroidHardwareBuffer::ToSurfaceDescriptor() {
} }
void SharedSurface_AndroidHardwareBuffer::WaitForBufferOwnership() { void SharedSurface_AndroidHardwareBuffer::WaitForBufferOwnership() {
ipc::FileDescriptor fenceFd = UniqueFileHandle fenceFd = mAndroidHardwareBuffer->GetAndResetReleaseFence();
mAndroidHardwareBuffer->GetAndResetReleaseFence(); if (!fenceFd) {
if (!fenceFd.IsValid()) {
return; return;
} }
const auto& gle = GLContextEGL::Cast(mDesc.gl); const auto& gle = GLContextEGL::Cast(mDesc.gl);
const auto& egl = gle->mEgl; const auto& egl = gle->mEgl;
auto rawFD = fenceFd.TakePlatformHandle(); const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID,
const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID, rawFD.get(), fenceFd.get(), LOCAL_EGL_NONE};
LOCAL_EGL_NONE};
EGLSync sync = egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); EGLSync sync = egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (!sync) { if (!sync) {
@@ -145,7 +142,7 @@ void SharedSurface_AndroidHardwareBuffer::WaitForBufferOwnership() {
return; return;
} }
// Release fd here, since it is owned by EGLSync // Release fd here, since it is owned by EGLSync
Unused << rawFD.release(); Unused << fenceFd.release();
egl->fClientWaitSync(sync, 0, LOCAL_EGL_FOREVER); egl->fClientWaitSync(sync, 0, LOCAL_EGL_FOREVER);
egl->fDestroySync(sync); egl->fDestroySync(sync);

View File

@@ -210,14 +210,8 @@ AndroidHardwareBuffer::~AndroidHardwareBuffer() {
int AndroidHardwareBuffer::Lock(uint64_t aUsage, const ARect* aRect, int AndroidHardwareBuffer::Lock(uint64_t aUsage, const ARect* aRect,
void** aOutVirtualAddress) { void** aOutVirtualAddress) {
ipc::FileDescriptor fd = GetAndResetReleaseFence(); UniqueFileHandle fd = GetAndResetReleaseFence();
int32_t fenceFd = -1; return AndroidHardwareBufferApi::Get()->Lock(mNativeBuffer, aUsage, fd.get(),
ipc::FileDescriptor::UniquePlatformHandle rawFd;
if (fd.IsValid()) {
rawFd = fd.TakePlatformHandle();
fenceFd = rawFd.get();
}
return AndroidHardwareBufferApi::Get()->Lock(mNativeBuffer, aUsage, fenceFd,
aRect, aOutVirtualAddress); aRect, aOutVirtualAddress);
} }
@@ -229,63 +223,43 @@ int AndroidHardwareBuffer::Unlock() {
return ret; return ret;
} }
ipc::FileDescriptor acquireFenceFd; SetAcquireFence(UniqueFileHandle(rawFd));
// The value -1 indicates that unlocking has already completed before
// the function returned and no further operations are necessary.
if (rawFd >= 0) {
acquireFenceFd = ipc::FileDescriptor(UniqueFileHandle(rawFd));
}
if (acquireFenceFd.IsValid()) {
SetAcquireFence(std::move(acquireFenceFd));
}
return 0; return 0;
} }
void AndroidHardwareBuffer::SetReleaseFence(ipc::FileDescriptor&& aFenceFd) { void AndroidHardwareBuffer::SetReleaseFence(UniqueFileHandle&& aFenceFd) {
MonitorAutoLock lock(AndroidHardwareBufferManager::Get()->GetMonitor()); MonitorAutoLock lock(AndroidHardwareBufferManager::Get()->GetMonitor());
SetReleaseFence(std::move(aFenceFd), lock); SetReleaseFence(std::move(aFenceFd), lock);
} }
void AndroidHardwareBuffer::SetReleaseFence(ipc::FileDescriptor&& aFenceFd, void AndroidHardwareBuffer::SetReleaseFence(UniqueFileHandle&& aFenceFd,
const MonitorAutoLock& aAutoLock) { const MonitorAutoLock& aAutoLock) {
mReleaseFenceFd = std::move(aFenceFd); mReleaseFenceFd = std::move(aFenceFd);
} }
void AndroidHardwareBuffer::SetAcquireFence(ipc::FileDescriptor&& aFenceFd) { void AndroidHardwareBuffer::SetAcquireFence(UniqueFileHandle&& aFenceFd) {
MonitorAutoLock lock(AndroidHardwareBufferManager::Get()->GetMonitor()); MonitorAutoLock lock(AndroidHardwareBufferManager::Get()->GetMonitor());
mAcquireFenceFd = std::move(aFenceFd); mAcquireFenceFd = std::move(aFenceFd);
} }
ipc::FileDescriptor AndroidHardwareBuffer::GetAndResetReleaseFence() { UniqueFileHandle AndroidHardwareBuffer::GetAndResetReleaseFence() {
MonitorAutoLock lock(AndroidHardwareBufferManager::Get()->GetMonitor()); MonitorAutoLock lock(AndroidHardwareBufferManager::Get()->GetMonitor());
if (!mReleaseFenceFd.IsValid()) {
return ipc::FileDescriptor();
}
return std::move(mReleaseFenceFd); return std::move(mReleaseFenceFd);
} }
ipc::FileDescriptor AndroidHardwareBuffer::GetAndResetAcquireFence() { UniqueFileHandle AndroidHardwareBuffer::GetAndResetAcquireFence() {
MonitorAutoLock lock(AndroidHardwareBufferManager::Get()->GetMonitor()); MonitorAutoLock lock(AndroidHardwareBufferManager::Get()->GetMonitor());
if (!mAcquireFenceFd.IsValid()) {
return ipc::FileDescriptor();
}
return std::move(mAcquireFenceFd); return std::move(mAcquireFenceFd);
} }
ipc::FileDescriptor AndroidHardwareBuffer::GetAcquireFence() { UniqueFileHandle AndroidHardwareBuffer::GetAcquireFence() const {
MonitorAutoLock lock(AndroidHardwareBufferManager::Get()->GetMonitor()); MonitorAutoLock lock(AndroidHardwareBufferManager::Get()->GetMonitor());
if (!mAcquireFenceFd) {
if (!mAcquireFenceFd.IsValid()) { return UniqueFileHandle();
return ipc::FileDescriptor();
} }
return mAcquireFenceFd; return DuplicateFileHandle(mAcquireFenceFd);
} }
StaticAutoPtr<AndroidHardwareBufferManager> StaticAutoPtr<AndroidHardwareBufferManager>

View File

@@ -18,6 +18,7 @@
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/StaticPtr.h" #include "mozilla/StaticPtr.h"
#include "mozilla/ThreadSafeWeakPtr.h" #include "mozilla/ThreadSafeWeakPtr.h"
#include "mozilla/UniquePtrExtensions.h"
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
@@ -99,15 +100,15 @@ class AndroidHardwareBuffer
AHardwareBuffer* GetNativeBuffer() const { return mNativeBuffer; } AHardwareBuffer* GetNativeBuffer() const { return mNativeBuffer; }
void SetAcquireFence(ipc::FileDescriptor&& aFenceFd); void SetAcquireFence(UniqueFileHandle&& aFenceFd);
void SetReleaseFence(ipc::FileDescriptor&& aFenceFd); void SetReleaseFence(UniqueFileHandle&& aFenceFd);
ipc::FileDescriptor GetAndResetReleaseFence(); UniqueFileHandle GetAndResetReleaseFence();
ipc::FileDescriptor GetAndResetAcquireFence(); UniqueFileHandle GetAndResetAcquireFence();
ipc::FileDescriptor GetAcquireFence(); UniqueFileHandle GetAcquireFence() const;
const gfx::IntSize mSize; const gfx::IntSize mSize;
const uint32_t mStride; const uint32_t mStride;
@@ -119,7 +120,7 @@ class AndroidHardwareBuffer
uint32_t aStride, gfx::SurfaceFormat aFormat, uint32_t aStride, gfx::SurfaceFormat aFormat,
uint64_t aId); uint64_t aId);
void SetReleaseFence(ipc::FileDescriptor&& aFenceFd, void SetReleaseFence(UniqueFileHandle&& aFenceFd,
const MonitorAutoLock& aAutoLock); const MonitorAutoLock& aAutoLock);
AHardwareBuffer* mNativeBuffer; AHardwareBuffer* mNativeBuffer;
@@ -133,12 +134,12 @@ class AndroidHardwareBuffer
// FileDescriptor of release fence. // FileDescriptor of release fence.
// Release fence is a fence that is used for waiting until usage/composite of // Release fence is a fence that is used for waiting until usage/composite of
// AHardwareBuffer is ended. The fence is delivered via ImageBridge. // AHardwareBuffer is ended. The fence is delivered via ImageBridge.
ipc::FileDescriptor mReleaseFenceFd; UniqueFileHandle mReleaseFenceFd;
// FileDescriptor of acquire fence. // FileDescriptor of acquire fence.
// Acquire fence is a fence that is used for waiting until rendering to // Acquire fence is a fence that is used for waiting until rendering to
// its AHardwareBuffer is completed. // its AHardwareBuffer is completed.
ipc::FileDescriptor mAcquireFenceFd; UniqueFileHandle mAcquireFenceFd;
static uint64_t GetNextId(); static uint64_t GetNextId();

View File

@@ -24,7 +24,6 @@
#include "mozilla/gfx/CriticalSection.h" #include "mozilla/gfx/CriticalSection.h"
#include "mozilla/gfx/Point.h" // for IntSize #include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/Types.h" // for SurfaceFormat #include "mozilla/gfx/Types.h" // for SurfaceFormat
#include "mozilla/ipc/FileDescriptor.h"
#include "mozilla/ipc/Shmem.h" // for Shmem #include "mozilla/ipc/Shmem.h" // for Shmem
#include "mozilla/layers/AtomicRefCountedWithFinalize.h" #include "mozilla/layers/AtomicRefCountedWithFinalize.h"
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc #include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
@@ -32,7 +31,8 @@
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/LayersTypes.h" #include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/SyncObject.h" #include "mozilla/layers/SyncObject.h"
#include "mozilla/mozalloc.h" // for operator delete #include "mozilla/mozalloc.h" // for operator delete
#include "mozilla/UniquePtrExtensions.h" // for UniqueFileHandle
#include "mozilla/webrender/WebRenderTypes.h" #include "mozilla/webrender/WebRenderTypes.h"
#include "nsCOMPtr.h" // for already_AddRefed #include "nsCOMPtr.h" // for already_AddRefed
#include "nsISupportsImpl.h" // for TextureImage::AddRef, etc #include "nsISupportsImpl.h" // for TextureImage::AddRef, etc
@@ -317,9 +317,7 @@ class TextureData {
// The acquire fence is a fence that is used for waiting until rendering to // The acquire fence is a fence that is used for waiting until rendering to
// its AHardwareBuffer is completed. // its AHardwareBuffer is completed.
// It is used only on android. // It is used only on android.
virtual mozilla::ipc::FileDescriptor GetAcquireFence() { virtual UniqueFileHandle GetAcquireFence() { return UniqueFileHandle(); }
return mozilla::ipc::FileDescriptor();
}
virtual bool RequiresRefresh() const { return false; } virtual bool RequiresRefresh() const { return false; }

View File

@@ -70,7 +70,7 @@ Maybe<uint64_t> SharedSurfaceTextureData::GetBufferId() const {
return Nothing(); return Nothing();
} }
mozilla::ipc::FileDescriptor SharedSurfaceTextureData::GetAcquireFence() { UniqueFileHandle SharedSurfaceTextureData::GetAcquireFence() {
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
if (mDesc.type() == if (mDesc.type() ==
SurfaceDescriptor::TSurfaceDescriptorAndroidHardwareBuffer) { SurfaceDescriptor::TSurfaceDescriptorAndroidHardwareBuffer) {
@@ -79,13 +79,13 @@ mozilla::ipc::FileDescriptor SharedSurfaceTextureData::GetAcquireFence() {
RefPtr<AndroidHardwareBuffer> buffer = RefPtr<AndroidHardwareBuffer> buffer =
AndroidHardwareBufferManager::Get()->GetBuffer(desc.bufferId()); AndroidHardwareBufferManager::Get()->GetBuffer(desc.bufferId());
if (!buffer) { if (!buffer) {
return ipc::FileDescriptor(); return UniqueFileHandle();
} }
return buffer->GetAcquireFence(); return buffer->GetAcquireFence();
} }
#endif #endif
return ipc::FileDescriptor(); return UniqueFileHandle();
} }
} // namespace layers } // namespace layers

View File

@@ -59,7 +59,7 @@ class SharedSurfaceTextureData : public TextureData {
Maybe<uint64_t> GetBufferId() const override; Maybe<uint64_t> GetBufferId() const override;
mozilla::ipc::FileDescriptor GetAcquireFence() override; UniqueFileHandle GetAcquireFence() override;
}; };
} // namespace layers } // namespace layers

View File

@@ -17,8 +17,7 @@
#include "mozilla/gfx/Matrix.h" #include "mozilla/gfx/Matrix.h"
#include "mozilla/gfx/Point.h" // for IntSize, IntPoint #include "mozilla/gfx/Point.h" // for IntSize, IntPoint
#include "mozilla/gfx/Rect.h" #include "mozilla/gfx/Rect.h"
#include "mozilla/gfx/Types.h" // for SurfaceFormat, etc #include "mozilla/gfx/Types.h" // for SurfaceFormat, etc
#include "mozilla/ipc/FileDescriptor.h"
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc #include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc #include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
#include "mozilla/layers/LayersMessages.h" #include "mozilla/layers/LayersMessages.h"
@@ -26,7 +25,8 @@
#include "mozilla/layers/TextureSourceProvider.h" #include "mozilla/layers/TextureSourceProvider.h"
#include "mozilla/mozalloc.h" // for operator delete #include "mozilla/mozalloc.h" // for operator delete
#include "mozilla/Range.h" #include "mozilla/Range.h"
#include "mozilla/UniquePtr.h" // for UniquePtr #include "mozilla/UniquePtr.h" // for UniquePtr
#include "mozilla/UniquePtrExtensions.h" // for UniqueFileHandle
#include "mozilla/webrender/WebRenderTypes.h" #include "mozilla/webrender/WebRenderTypes.h"
#include "nsCOMPtr.h" // for already_AddRefed #include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_WARNING #include "nsDebug.h" // for NS_WARNING
@@ -695,12 +695,12 @@ class TextureHost : public AtomicRefCountedWithFinalize<TextureHost> {
virtual bool NeedsYFlip() const; virtual bool NeedsYFlip() const;
virtual void SetAcquireFence(mozilla::ipc::FileDescriptor&& aFenceFd) {} virtual void SetAcquireFence(UniqueFileHandle&& aFenceFd) {}
virtual void SetReleaseFence(mozilla::ipc::FileDescriptor&& aFenceFd) {} virtual void SetReleaseFence(UniqueFileHandle&& aFenceFd) {}
virtual mozilla::ipc::FileDescriptor GetAndResetReleaseFence() { virtual UniqueFileHandle GetAndResetReleaseFence() {
return mozilla::ipc::FileDescriptor(); return UniqueFileHandle();
} }
virtual AndroidHardwareBuffer* GetAndroidHardwareBuffer() const { virtual AndroidHardwareBuffer* GetAndroidHardwareBuffer() const {

View File

@@ -316,10 +316,9 @@ Maybe<uint64_t> AndroidHardwareBufferTextureData::GetBufferId() const {
return Some(mAndroidHardwareBuffer->mId); return Some(mAndroidHardwareBuffer->mId);
} }
mozilla::ipc::FileDescriptor UniqueFileHandle AndroidHardwareBufferTextureData::GetAcquireFence() {
AndroidHardwareBufferTextureData::GetAcquireFence() {
if (!mAndroidHardwareBuffer) { if (!mAndroidHardwareBuffer) {
return ipc::FileDescriptor(); return UniqueFileHandle();
} }
return mAndroidHardwareBuffer->GetAcquireFence(); return mAndroidHardwareBuffer->GetAcquireFence();

View File

@@ -137,7 +137,7 @@ class AndroidHardwareBufferTextureData : public TextureData {
Maybe<uint64_t> GetBufferId() const override; Maybe<uint64_t> GetBufferId() const override;
mozilla::ipc::FileDescriptor GetAcquireFence() override; UniqueFileHandle GetAcquireFence() override;
AndroidHardwareBufferTextureData* AsAndroidHardwareBufferTextureData() AndroidHardwareBufferTextureData* AsAndroidHardwareBufferTextureData()
override { override {

View File

@@ -662,19 +662,18 @@ bool AndroidHardwareBufferTextureSource::EnsureEGLImage() {
} }
auto fenceFd = mAndroidHardwareBuffer->GetAndResetAcquireFence(); auto fenceFd = mAndroidHardwareBuffer->GetAndResetAcquireFence();
if (fenceFd.IsValid()) { if (fenceFd) {
const auto& gle = gl::GLContextEGL::Cast(mGL); const auto& gle = gl::GLContextEGL::Cast(mGL);
const auto& egl = gle->mEgl; const auto& egl = gle->mEgl;
auto rawFD = fenceFd.TakePlatformHandle();
const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID, const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID,
rawFD.get(), LOCAL_EGL_NONE}; fenceFd.get(), LOCAL_EGL_NONE};
EGLSync sync = EGLSync sync =
egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (sync) { if (sync) {
// Release fd here, since it is owned by EGLSync // Release fd here, since it is owned by EGLSync
Unused << rawFD.release(); Unused << fenceFd.release();
if (egl->IsExtensionSupported(gl::EGLExtension::KHR_wait_sync)) { if (egl->IsExtensionSupported(gl::EGLExtension::KHR_wait_sync)) {
egl->fWaitSync(sync, 0); egl->fWaitSync(sync, 0);
@@ -820,7 +819,7 @@ void AndroidHardwareBufferTextureHost::DeallocateDeviceData() {
} }
void AndroidHardwareBufferTextureHost::SetAcquireFence( void AndroidHardwareBufferTextureHost::SetAcquireFence(
mozilla::ipc::FileDescriptor&& aFenceFd) { UniqueFileHandle&& aFenceFd) {
if (!mAndroidHardwareBuffer) { if (!mAndroidHardwareBuffer) {
return; return;
} }
@@ -828,17 +827,16 @@ void AndroidHardwareBufferTextureHost::SetAcquireFence(
} }
void AndroidHardwareBufferTextureHost::SetReleaseFence( void AndroidHardwareBufferTextureHost::SetReleaseFence(
mozilla::ipc::FileDescriptor&& aFenceFd) { UniqueFileHandle&& aFenceFd) {
if (!mAndroidHardwareBuffer) { if (!mAndroidHardwareBuffer) {
return; return;
} }
mAndroidHardwareBuffer->SetReleaseFence(std::move(aFenceFd)); mAndroidHardwareBuffer->SetReleaseFence(std::move(aFenceFd));
} }
mozilla::ipc::FileDescriptor UniqueFileHandle AndroidHardwareBufferTextureHost::GetAndResetReleaseFence() {
AndroidHardwareBufferTextureHost::GetAndResetReleaseFence() {
if (!mAndroidHardwareBuffer) { if (!mAndroidHardwareBuffer) {
return mozilla::ipc::FileDescriptor(); return UniqueFileHandle();
} }
return mAndroidHardwareBuffer->GetAndResetReleaseFence(); return mAndroidHardwareBuffer->GetAndResetReleaseFence();
} }

View File

@@ -541,11 +541,11 @@ class AndroidHardwareBufferTextureHost : public TextureHost {
const Range<wr::ImageKey>& aImageKeys, const Range<wr::ImageKey>& aImageKeys,
PushDisplayItemFlagSet aFlags) override; PushDisplayItemFlagSet aFlags) override;
void SetAcquireFence(mozilla::ipc::FileDescriptor&& aFenceFd) override; void SetAcquireFence(UniqueFileHandle&& aFenceFd) override;
void SetReleaseFence(mozilla::ipc::FileDescriptor&& aFenceFd) override; void SetReleaseFence(UniqueFileHandle&& aFenceFd) override;
mozilla::ipc::FileDescriptor GetAndResetReleaseFence() override; UniqueFileHandle GetAndResetReleaseFence() override;
AndroidHardwareBuffer* GetAndroidHardwareBuffer() const override { AndroidHardwareBuffer* GetAndroidHardwareBuffer() const override {
return mAndroidHardwareBuffer; return mAndroidHardwareBuffer;

View File

@@ -658,7 +658,7 @@ void AsyncImagePipelineManager::HoldExternalImage(
void AsyncImagePipelineManager::NotifyPipelinesUpdated( void AsyncImagePipelineManager::NotifyPipelinesUpdated(
RefPtr<const wr::WebRenderPipelineInfo> aInfo, RefPtr<const wr::WebRenderPipelineInfo> aInfo,
wr::RenderedFrameId aLatestFrameId, wr::RenderedFrameId aLatestFrameId,
wr::RenderedFrameId aLastCompletedFrameId, ipc::FileDescriptor&& aFenceFd) { wr::RenderedFrameId aLastCompletedFrameId, UniqueFileHandle&& aFenceFd) {
MOZ_ASSERT(wr::RenderThread::IsInRenderThread()); MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
MOZ_ASSERT(mLastCompletedFrameId <= aLastCompletedFrameId.mId); MOZ_ASSERT(mLastCompletedFrameId <= aLastCompletedFrameId.mId);
MOZ_ASSERT(aLatestFrameId.IsValid()); MOZ_ASSERT(aLatestFrameId.IsValid());
@@ -701,7 +701,7 @@ void AsyncImagePipelineManager::ProcessPipelineUpdates() {
// submittedUpdates is a vector of RenderedFrameIds paired with vectors of // submittedUpdates is a vector of RenderedFrameIds paired with vectors of
// WebRenderPipelineInfo. // WebRenderPipelineInfo.
for (auto update : submittedUpdates) { for (auto& update : submittedUpdates) {
auto& holder = update.second; auto& holder = update.second;
const auto& info = holder.mInfo->Raw(); const auto& info = holder.mInfo->Raw();
@@ -736,10 +736,8 @@ void AsyncImagePipelineManager::ProcessPipelineRendered(
for (auto it = holder->mTextureHostsUntilRenderSubmitted.begin(); for (auto it = holder->mTextureHostsUntilRenderSubmitted.begin();
it != firstSubmittedHostToKeep; ++it) { it != firstSubmittedHostToKeep; ++it) {
const auto& entry = it; const auto& entry = it;
if (entry->mTexture->GetAndroidHardwareBuffer() && if (entry->mTexture->GetAndroidHardwareBuffer() && mReleaseFenceFd) {
mReleaseFenceFd.IsValid()) { entry->mTexture->SetReleaseFence(DuplicateFileHandle(mReleaseFenceFd));
ipc::FileDescriptor fenceFd = mReleaseFenceFd;
entry->mTexture->SetReleaseFence(std::move(fenceFd));
} }
} }
#endif #endif
@@ -826,8 +824,8 @@ wr::Epoch AsyncImagePipelineManager::GetNextImageEpoch() {
AsyncImagePipelineManager::WebRenderPipelineInfoHolder:: AsyncImagePipelineManager::WebRenderPipelineInfoHolder::
WebRenderPipelineInfoHolder(RefPtr<const wr::WebRenderPipelineInfo>&& aInfo, WebRenderPipelineInfoHolder(RefPtr<const wr::WebRenderPipelineInfo>&& aInfo,
ipc::FileDescriptor&& aFenceFd) UniqueFileHandle&& aFenceFd)
: mInfo(aInfo), mFenceFd(aFenceFd) {} : mInfo(aInfo), mFenceFd(std::move(aFenceFd)) {}
AsyncImagePipelineManager::WebRenderPipelineInfoHolder:: AsyncImagePipelineManager::WebRenderPipelineInfoHolder::
~WebRenderPipelineInfoHolder() = default; ~WebRenderPipelineInfoHolder() = default;

View File

@@ -10,8 +10,8 @@
#include <vector> #include <vector>
#include "CompositableHost.h" #include "CompositableHost.h"
#include "mozilla/UniquePtrExtensions.h"
#include "mozilla/gfx/Point.h" #include "mozilla/gfx/Point.h"
#include "mozilla/ipc/FileDescriptor.h"
#include "mozilla/layers/RemoteTextureMap.h" #include "mozilla/layers/RemoteTextureMap.h"
#include "mozilla/layers/TextureHost.h" #include "mozilla/layers/TextureHost.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
@@ -71,7 +71,7 @@ class AsyncImagePipelineManager final {
void NotifyPipelinesUpdated(RefPtr<const wr::WebRenderPipelineInfo> aInfo, void NotifyPipelinesUpdated(RefPtr<const wr::WebRenderPipelineInfo> aInfo,
wr::RenderedFrameId aLatestFrameId, wr::RenderedFrameId aLatestFrameId,
wr::RenderedFrameId aLastCompletedFrameId, wr::RenderedFrameId aLastCompletedFrameId,
ipc::FileDescriptor&& aFenceFd); UniqueFileHandle&& aFenceFd);
// This is run on the compositor thread to process mRenderSubmittedUpdates. We // This is run on the compositor thread to process mRenderSubmittedUpdates. We
// make this public because we need to invoke it from other places. // make this public because we need to invoke it from other places.
@@ -277,10 +277,11 @@ class AsyncImagePipelineManager final {
struct WebRenderPipelineInfoHolder { struct WebRenderPipelineInfoHolder {
WebRenderPipelineInfoHolder(RefPtr<const wr::WebRenderPipelineInfo>&& aInfo, WebRenderPipelineInfoHolder(RefPtr<const wr::WebRenderPipelineInfo>&& aInfo,
ipc::FileDescriptor&& aFenceFd); UniqueFileHandle&& aFenceFd);
~WebRenderPipelineInfoHolder(); ~WebRenderPipelineInfoHolder();
WebRenderPipelineInfoHolder(WebRenderPipelineInfoHolder&&) = default;
RefPtr<const wr::WebRenderPipelineInfo> mInfo; RefPtr<const wr::WebRenderPipelineInfo> mInfo;
ipc::FileDescriptor mFenceFd; UniqueFileHandle mFenceFd;
}; };
std::vector<std::pair<wr::RenderedFrameId, WebRenderPipelineInfoHolder>> std::vector<std::pair<wr::RenderedFrameId, WebRenderPipelineInfoHolder>>
@@ -291,7 +292,7 @@ class AsyncImagePipelineManager final {
std::vector<std::pair<wr::RenderedFrameId, std::vector<std::pair<wr::RenderedFrameId,
std::vector<UniquePtr<ForwardingTextureHost>>>> std::vector<UniquePtr<ForwardingTextureHost>>>>
mTexturesInUseByGPU; mTexturesInUseByGPU;
ipc::FileDescriptor mReleaseFenceFd; UniqueFileHandle mReleaseFenceFd;
}; };
} // namespace layers } // namespace layers

View File

@@ -195,17 +195,15 @@ bool WebRenderTextureHost::SupportsExternalCompositing(
return mWrappedTextureHost->SupportsExternalCompositing(aBackend); return mWrappedTextureHost->SupportsExternalCompositing(aBackend);
} }
void WebRenderTextureHost::SetAcquireFence( void WebRenderTextureHost::SetAcquireFence(UniqueFileHandle&& aFenceFd) {
mozilla::ipc::FileDescriptor&& aFenceFd) {
mWrappedTextureHost->SetAcquireFence(std::move(aFenceFd)); mWrappedTextureHost->SetAcquireFence(std::move(aFenceFd));
} }
void WebRenderTextureHost::SetReleaseFence( void WebRenderTextureHost::SetReleaseFence(UniqueFileHandle&& aFenceFd) {
mozilla::ipc::FileDescriptor&& aFenceFd) {
mWrappedTextureHost->SetReleaseFence(std::move(aFenceFd)); mWrappedTextureHost->SetReleaseFence(std::move(aFenceFd));
} }
mozilla::ipc::FileDescriptor WebRenderTextureHost::GetAndResetReleaseFence() { UniqueFileHandle WebRenderTextureHost::GetAndResetReleaseFence() {
return mWrappedTextureHost->GetAndResetReleaseFence(); return mWrappedTextureHost->GetAndResetReleaseFence();
} }

View File

@@ -97,11 +97,11 @@ class WebRenderTextureHost : public TextureHost {
bool SupportsExternalCompositing(WebRenderBackend aBackend) override; bool SupportsExternalCompositing(WebRenderBackend aBackend) override;
void SetAcquireFence(mozilla::ipc::FileDescriptor&& aFenceFd) override; void SetAcquireFence(UniqueFileHandle&& aFenceFd) override;
void SetReleaseFence(mozilla::ipc::FileDescriptor&& aFenceFd) override; void SetReleaseFence(UniqueFileHandle&& aFenceFd) override;
mozilla::ipc::FileDescriptor GetAndResetReleaseFence() override; UniqueFileHandle GetAndResetReleaseFence() override;
AndroidHardwareBuffer* GetAndroidHardwareBuffer() const override; AndroidHardwareBuffer* GetAndroidHardwareBuffer() const override;

View File

@@ -49,19 +49,18 @@ bool RenderAndroidHardwareBufferTextureHost::EnsureLockable() {
} }
auto fenceFd = mAndroidHardwareBuffer->GetAndResetAcquireFence(); auto fenceFd = mAndroidHardwareBuffer->GetAndResetAcquireFence();
if (fenceFd.IsValid()) { if (fenceFd) {
const auto& gle = gl::GLContextEGL::Cast(mGL); const auto& gle = gl::GLContextEGL::Cast(mGL);
const auto& egl = gle->mEgl; const auto& egl = gle->mEgl;
auto rawFD = fenceFd.TakePlatformHandle();
const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID, const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID,
rawFD.get(), LOCAL_EGL_NONE}; fenceFd.get(), LOCAL_EGL_NONE};
EGLSync sync = EGLSync sync =
egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (sync) { if (sync) {
// Release fd here, since it is owned by EGLSync // Release fd here, since it is owned by EGLSync
Unused << rawFD.release(); Unused << fenceFd.release();
if (egl->IsExtensionSupported(gl::EGLExtension::KHR_wait_sync)) { if (egl->IsExtensionSupported(gl::EGLExtension::KHR_wait_sync)) {
egl->fWaitSync(sync, 0); egl->fWaitSync(sync, 0);

View File

@@ -7,9 +7,9 @@
#ifndef MOZILLA_GFX_RENDERCOMPOSITOR_H #ifndef MOZILLA_GFX_RENDERCOMPOSITOR_H
#define MOZILLA_GFX_RENDERCOMPOSITOR_H #define MOZILLA_GFX_RENDERCOMPOSITOR_H
#include "mozilla/ipc/FileDescriptor.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "mozilla/UniquePtrExtensions.h"
#include "mozilla/webrender/WebRenderTypes.h" #include "mozilla/webrender/WebRenderTypes.h"
#include "Units.h" #include "Units.h"
@@ -206,8 +206,8 @@ class RenderCompositor {
// Release fence is a fence that is used for waiting until usage/composite of // Release fence is a fence that is used for waiting until usage/composite of
// AHardwareBuffer is ended. The fence is delivered to client side via // AHardwareBuffer is ended. The fence is delivered to client side via
// ImageBridge. It is used only on android. // ImageBridge. It is used only on android.
virtual ipc::FileDescriptor GetAndResetReleaseFence() { virtual UniqueFileHandle GetAndResetReleaseFence() {
return ipc::FileDescriptor(); return UniqueFileHandle();
} }
virtual bool IsPaused() { return false; } virtual bool IsPaused() { return false; }

View File

@@ -123,7 +123,7 @@ RenderedFrameId RenderCompositorEGL::EndFrame(
if (sync) { if (sync) {
int fenceFd = egl->fDupNativeFenceFDANDROID(sync); int fenceFd = egl->fDupNativeFenceFDANDROID(sync);
if (fenceFd >= 0) { if (fenceFd >= 0) {
mReleaseFenceFd = ipc::FileDescriptor(UniqueFileHandle(fenceFd)); mReleaseFenceFd = UniqueFileHandle(fenceFd);
} }
egl->fDestroySync(sync); egl->fDestroySync(sync);
sync = nullptr; sync = nullptr;
@@ -259,13 +259,12 @@ void RenderCompositorEGL::DestroyEGLSurface() {
} }
} }
ipc::FileDescriptor RenderCompositorEGL::GetAndResetReleaseFence() { UniqueFileHandle RenderCompositorEGL::GetAndResetReleaseFence() {
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
MOZ_ASSERT(!layers::AndroidHardwareBufferApi::Get() || MOZ_ASSERT(!layers::AndroidHardwareBufferApi::Get() || mReleaseFenceFd);
mReleaseFenceFd.IsValid());
return std::move(mReleaseFenceFd); return std::move(mReleaseFenceFd);
#else #else
return ipc::FileDescriptor(); return UniqueFileHandle();
#endif #endif
} }

View File

@@ -46,7 +46,7 @@ class RenderCompositorEGL : public RenderCompositor {
void SetBufferDamageRegion(const wr::DeviceIntRect* aRects, void SetBufferDamageRegion(const wr::DeviceIntRect* aRects,
size_t aNumRects) override; size_t aNumRects) override;
ipc::FileDescriptor GetAndResetReleaseFence() override; UniqueFileHandle GetAndResetReleaseFence() override;
protected: protected:
EGLSurface CreateEGLSurface(); EGLSurface CreateEGLSurface();
@@ -66,7 +66,7 @@ class RenderCompositorEGL : public RenderCompositor {
// Release fence is a fence that is used for waiting until usage/composite of // Release fence is a fence that is used for waiting until usage/composite of
// AHardwareBuffer is ended. The fence is delivered to client side via // AHardwareBuffer is ended. The fence is delivered to client side via
// ImageBridge. It is used only on android. // ImageBridge. It is used only on android.
ipc::FileDescriptor mReleaseFenceFd; UniqueFileHandle mReleaseFenceFd;
}; };
} // namespace wr } // namespace wr

View File

@@ -866,7 +866,7 @@ void RenderThread::UpdateAndRender(
renderer->GetCompositorBridge(), info, aStartId, renderer->GetCompositorBridge(), info, aStartId,
aStartTime, start, end, aRender, *aStats)); aStartTime, start, end, aRender, *aStats));
ipc::FileDescriptor fenceFd; UniqueFileHandle fenceFd;
if (latestFrameId.IsValid()) { if (latestFrameId.IsValid()) {
fenceFd = renderer->GetAndResetReleaseFence(); fenceFd = renderer->GetAndResetReleaseFence();

View File

@@ -280,7 +280,7 @@ void RendererOGL::WaitForGPU() {
} }
} }
ipc::FileDescriptor RendererOGL::GetAndResetReleaseFence() { UniqueFileHandle RendererOGL::GetAndResetReleaseFence() {
return mCompositor->GetAndResetReleaseFence(); return mCompositor->GetAndResetReleaseFence();
} }

View File

@@ -7,7 +7,7 @@
#ifndef MOZILLA_LAYERS_RENDEREROGL_H #ifndef MOZILLA_LAYERS_RENDEREROGL_H
#define MOZILLA_LAYERS_RENDEREROGL_H #define MOZILLA_LAYERS_RENDEREROGL_H
#include "mozilla/ipc/FileDescriptor.h" #include "mozilla/UniquePtrExtensions.h"
#include "mozilla/layers/CompositorTypes.h" #include "mozilla/layers/CompositorTypes.h"
#include "mozilla/gfx/Point.h" #include "mozilla/gfx/Point.h"
#include "mozilla/webrender/RenderThread.h" #include "mozilla/webrender/RenderThread.h"
@@ -70,7 +70,7 @@ class RendererOGL {
void WaitForGPU(); void WaitForGPU();
/// This can be called on the render thread only. /// This can be called on the render thread only.
ipc::FileDescriptor GetAndResetReleaseFence(); UniqueFileHandle GetAndResetReleaseFence();
/// This can be called on the render thread only. /// This can be called on the render thread only.
RenderedFrameId GetLastCompletedFrameId(); RenderedFrameId GetLastCompletedFrameId();