Bug 1236762 - Simplify locking APIs for SharedSurface. - r=jrmuizel

This commit is contained in:
Jeff Gilbert 2016-01-05 15:57:44 -08:00
parent e0dc3b7265
commit b66e705f39
16 changed files with 28 additions and 378 deletions

View File

@ -249,27 +249,6 @@ SharedSurface::UnlockProd()
mIsLocked = false;
}
void
SharedSurface::Fence_ContentThread()
{
MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
Fence_ContentThread_Impl();
}
bool
SharedSurface::WaitSync_ContentThread()
{
MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
return WaitSync_ContentThread_Impl();
}
bool
SharedSurface::PollSync_ContentThread()
{
MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
return PollSync_ContentThread_Impl();
}
////////////////////////////////////////////////////////////////////////
// SurfaceFactory

View File

@ -100,16 +100,10 @@ protected:
virtual void LockProdImpl() = 0;
virtual void UnlockProdImpl() = 0;
virtual void ProducerAcquireImpl() {}
virtual void ProducerReleaseImpl() {
Fence();
}
virtual void ProducerReadAcquireImpl() {}
virtual void ProducerReadReleaseImpl() {}
virtual void ConsumerAcquireImpl() {
WaitSync();
}
virtual void ConsumerReleaseImpl() {}
virtual void ProducerAcquireImpl() = 0;
virtual void ProducerReleaseImpl() = 0;
virtual void ProducerReadAcquireImpl() { ProducerAcquireImpl(); }
virtual void ProducerReadReleaseImpl() { ProducerReleaseImpl(); }
public:
void ProducerAcquire() {
@ -132,39 +126,7 @@ public:
ProducerReadReleaseImpl();
mIsProducerAcquired = false;
}
void ConsumerAcquire() {
MOZ_ASSERT(!mIsConsumerAcquired);
ConsumerAcquireImpl();
mIsConsumerAcquired = true;
}
void ConsumerRelease() {
MOZ_ASSERT(mIsConsumerAcquired);
ConsumerReleaseImpl();
mIsConsumerAcquired = false;
}
virtual void Fence() = 0;
virtual bool WaitSync() = 0;
virtual bool PollSync() = 0;
// Use these if you can. They can only be called from the Content
// thread, though!
void Fence_ContentThread();
bool WaitSync_ContentThread();
bool PollSync_ContentThread();
protected:
virtual void Fence_ContentThread_Impl() {
Fence();
}
virtual bool WaitSync_ContentThread_Impl() {
return WaitSync();
}
virtual bool PollSync_ContentThread_Impl() {
return PollSync();
}
public:
// This function waits until the buffer is no longer being used.
// To optimize the performance, some implementaions recycle SharedSurfaces
// even when its buffer is still being used.

View File

@ -134,24 +134,6 @@ SharedSurface_ANGLEShareHandle::UnlockProdImpl()
{
}
void
SharedSurface_ANGLEShareHandle::Fence()
{
mGL->fFinish();
}
bool
SharedSurface_ANGLEShareHandle::WaitSync()
{
return true;
}
bool
SharedSurface_ANGLEShareHandle::PollSync()
{
return true;
}
void
SharedSurface_ANGLEShareHandle::ProducerAcquireImpl()
{
@ -174,7 +156,7 @@ SharedSurface_ANGLEShareHandle::ProducerReleaseImpl()
mKeyedMutex->ReleaseSync(0);
return;
}
Fence();
mGL->fFinish();
}
void
@ -192,77 +174,6 @@ SharedSurface_ANGLEShareHandle::ProducerReadReleaseImpl()
}
}
void
SharedSurface_ANGLEShareHandle::ConsumerAcquireImpl()
{
if (!mConsumerTexture) {
RefPtr<ID3D11Texture2D> tex;
HRESULT hr = gfxWindowsPlatform::GetPlatform()->GetD3D11Device()->OpenSharedResource(mShareHandle,
__uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**)getter_AddRefs(tex));
if (SUCCEEDED(hr)) {
mConsumerTexture = tex;
RefPtr<IDXGIKeyedMutex> mutex;
hr = tex->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
if (SUCCEEDED(hr)) {
mConsumerKeyedMutex = mutex;
}
}
}
if (mConsumerKeyedMutex) {
HRESULT hr = mConsumerKeyedMutex->AcquireSync(0, 10000);
if (hr == WAIT_TIMEOUT) {
MOZ_CRASH("GFX: ANGLE consumer mutex timeout");
}
}
}
void
SharedSurface_ANGLEShareHandle::ConsumerReleaseImpl()
{
if (mConsumerKeyedMutex) {
mConsumerKeyedMutex->ReleaseSync(0);
}
}
void
SharedSurface_ANGLEShareHandle::Fence_ContentThread_Impl()
{
if (mFence) {
MOZ_ASSERT(mGL->IsExtensionSupported(GLContext::NV_fence));
mGL->fSetFence(mFence, LOCAL_GL_ALL_COMPLETED_NV);
mGL->fFlush();
return;
}
Fence();
}
bool
SharedSurface_ANGLEShareHandle::WaitSync_ContentThread_Impl()
{
if (mFence) {
mGL->MakeCurrent();
mGL->fFinishFence(mFence);
return true;
}
return WaitSync();
}
bool
SharedSurface_ANGLEShareHandle::PollSync_ContentThread_Impl()
{
if (mFence) {
mGL->MakeCurrent();
return mGL->fTestFence(mFence);
}
return PollSync();
}
bool
SharedSurface_ANGLEShareHandle::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
{

View File

@ -62,19 +62,10 @@ public:
virtual void LockProdImpl() override;
virtual void UnlockProdImpl() override;
virtual void Fence() override;
virtual void ProducerAcquireImpl() override;
virtual void ProducerReleaseImpl() override;
virtual void ProducerReadAcquireImpl() override;
virtual void ProducerReadReleaseImpl() override;
virtual void ConsumerAcquireImpl() override;
virtual void ConsumerReleaseImpl() override;
virtual bool WaitSync() override;
virtual bool PollSync() override;
virtual void Fence_ContentThread_Impl() override;
virtual bool WaitSync_ContentThread_Impl() override;
virtual bool PollSync_ContentThread_Impl() override;
const RefPtr<ID3D11Texture2D>& GetConsumerTexture() const {
return mConsumerTexture;

View File

@ -328,25 +328,6 @@ void
SharedSurface_D3D11Interop::UnlockProdImpl()
{ }
void
SharedSurface_D3D11Interop::Fence()
{
// TODO fence properly. This kills performance.
mGL->fFinish();
}
bool
SharedSurface_D3D11Interop::WaitSync()
{
return true;
}
bool
SharedSurface_D3D11Interop::PollSync()
{
return true;
}
void
SharedSurface_D3D11Interop::ProducerAcquireImpl()
{
@ -382,81 +363,9 @@ SharedSurface_D3D11Interop::ProducerReleaseImpl()
if (mKeyedMutex) {
mKeyedMutex->ReleaseSync(0);
}
Fence();
}
void
SharedSurface_D3D11Interop::ConsumerAcquireImpl()
{
if (!mConsumerTexture) {
RefPtr<ID3D11Texture2D> tex;
RefPtr<ID3D11Device> device = gfxWindowsPlatform::GetPlatform()->GetD3D11Device();
HRESULT hr = device->OpenSharedResource(mSharedHandle,
__uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**) getter_AddRefs(tex));
if (SUCCEEDED(hr)) {
mConsumerTexture = tex;
RefPtr<IDXGIKeyedMutex> mutex;
hr = tex->QueryInterface((IDXGIKeyedMutex**) getter_AddRefs(mutex));
if (SUCCEEDED(hr)) {
mConsumerKeyedMutex = mutex;
}
}
}
if (mConsumerKeyedMutex) {
const uint64_t keyValue = 0;
const DWORD timeoutMs = 10000;
HRESULT hr = mConsumerKeyedMutex->AcquireSync(keyValue, timeoutMs);
if (hr == WAIT_TIMEOUT) {
MOZ_CRASH();
}
}
}
void
SharedSurface_D3D11Interop::ConsumerReleaseImpl()
{
if (mConsumerKeyedMutex) {
mConsumerKeyedMutex->ReleaseSync(0);
}
}
void
SharedSurface_D3D11Interop::Fence_ContentThread_Impl()
{
if (mFence) {
MOZ_ASSERT(mGL->IsExtensionSupported(GLContext::NV_fence));
mGL->fSetFence(mFence, LOCAL_GL_ALL_COMPLETED_NV);
mGL->fFlush();
return;
}
Fence();
}
bool
SharedSurface_D3D11Interop::WaitSync_ContentThread_Impl()
{
if (mFence) {
mGL->MakeCurrent();
mGL->fFinishFence(mFence);
return true;
}
return WaitSync();
}
bool
SharedSurface_D3D11Interop::PollSync_ContentThread_Impl()
{
if (mFence) {
mGL->MakeCurrent();
return mGL->fTestFence(mFence);
}
return PollSync();
// TODO fence properly. This kills performance.
mGL->fFinish();
}
bool

View File

@ -65,17 +65,8 @@ public:
virtual void LockProdImpl() override;
virtual void UnlockProdImpl() override;
virtual void Fence() override;
virtual void ProducerAcquireImpl() override;
virtual void ProducerReleaseImpl() override;
virtual void ConsumerAcquireImpl() override;
virtual void ConsumerReleaseImpl() override;
virtual bool WaitSync() override;
virtual bool PollSync() override;
virtual void Fence_ContentThread_Impl() override;
virtual bool WaitSync_ContentThread_Impl() override;
virtual bool PollSync_ContentThread_Impl() override;
virtual GLuint ProdRenderbuffer() override {
return mProdRB;

View File

@ -113,7 +113,7 @@ SharedSurface_EGLImage::GetTextureFlags() const
}
void
SharedSurface_EGLImage::Fence()
SharedSurface_EGLImage::ProducerReleaseImpl()
{
MutexAutoLock lock(mMutex);
mGL->MakeCurrent();
@ -140,48 +140,6 @@ SharedSurface_EGLImage::Fence()
mGL->fFinish();
}
bool
SharedSurface_EGLImage::WaitSync()
{
MutexAutoLock lock(mMutex);
if (!mSync) {
// We must not be needed.
return true;
}
MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
// Wait FOREVER, primarily because some NVIDIA (at least Tegra) drivers
// have ClientWaitSync returning immediately if the timeout delay is anything
// else than FOREVER.
//
// FIXME: should we try to use a finite timeout delay where possible?
EGLint status = mEGL->fClientWaitSync(Display(),
mSync,
0,
LOCAL_EGL_FOREVER);
return status == LOCAL_EGL_CONDITION_SATISFIED;
}
bool
SharedSurface_EGLImage::PollSync()
{
MutexAutoLock lock(mMutex);
if (!mSync) {
// We must not be needed.
return true;
}
MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
EGLint status = 0;
MOZ_ALWAYS_TRUE( mEGL->fGetSyncAttrib(mEGL->Display(),
mSync,
LOCAL_EGL_SYNC_STATUS_KHR,
&status) );
return status == LOCAL_EGL_SIGNALED_KHR;
}
EGLDisplay
SharedSurface_EGLImage::Display() const
{

View File

@ -68,9 +68,8 @@ public:
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
virtual void Fence() override;
virtual bool WaitSync() override;
virtual bool PollSync() override;
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual GLuint ProdTexture() override {
return mProdTex;

View File

@ -66,9 +66,8 @@ public:
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
virtual void Fence() override {}
virtual bool WaitSync() override { return true; }
virtual bool PollSync() override { return true; }
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override {}
virtual GLuint ProdTexture() override {
return mTex;
@ -134,12 +133,9 @@ public:
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual void Fence() override {}
virtual bool WaitSync() override { MOZ_CRASH("should not be called"); }
virtual bool PollSync() override { MOZ_CRASH("should not be called"); }
virtual GLuint ProdTexture() override {
return mTex;
}

View File

@ -55,7 +55,7 @@ SharedSurface_GLXDrawable::SharedSurface_GLXDrawable(GLContext* gl,
{}
void
SharedSurface_GLXDrawable::Fence()
SharedSurface_GLXDrawable::ProducerReleaseImpl()
{
mGL->MakeCurrent();
mGL->fFlush();

View File

@ -24,9 +24,8 @@ public:
bool deallocateClient,
bool inSameProcess);
virtual void Fence() override;
virtual bool WaitSync() override { return true; }
virtual bool PollSync() override { return true; }
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual void LockProdImpl() override;
virtual void UnlockProdImpl() override;

View File

@ -158,7 +158,7 @@ SharedSurface_Gralloc::~SharedSurface_Gralloc()
}
void
SharedSurface_Gralloc::Fence()
SharedSurface_Gralloc::ProducerReleaseImpl()
{
if (mSync) {
MOZ_ALWAYS_TRUE( mEGL->fDestroySync(mEGL->Display(), mSync) );
@ -222,54 +222,6 @@ SharedSurface_Gralloc::Fence()
}
}
bool
SharedSurface_Gralloc::WaitSync()
{
if (!mSync) {
// We must not be needed.
return true;
}
MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
EGLint status = mEGL->fClientWaitSync(mEGL->Display(),
mSync,
0,
LOCAL_EGL_FOREVER);
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
return false;
}
MOZ_ALWAYS_TRUE( mEGL->fDestroySync(mEGL->Display(), mSync) );
mSync = 0;
return true;
}
bool
SharedSurface_Gralloc::PollSync()
{
if (!mSync) {
// We must not be needed.
return true;
}
MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
EGLint status = 0;
MOZ_ALWAYS_TRUE( mEGL->fGetSyncAttrib(mEGL->Display(),
mSync,
LOCAL_EGL_SYNC_STATUS_KHR,
&status) );
if (status != LOCAL_EGL_SIGNALED_KHR) {
return false;
}
MOZ_ALWAYS_TRUE( mEGL->fDestroySync(mEGL->Display(), mSync) );
mSync = 0;
return true;
}
void
SharedSurface_Gralloc::WaitForBufferOwnership()
{

View File

@ -57,9 +57,8 @@ protected:
public:
virtual ~SharedSurface_Gralloc();
virtual void Fence() override;
virtual bool WaitSync() override;
virtual bool PollSync() override;
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual void WaitForBufferOwnership() override;

View File

@ -30,7 +30,7 @@ SharedSurface_IOSurface::Create(const RefPtr<MacIOSurface>& ioSurf,
}
void
SharedSurface_IOSurface::Fence()
SharedSurface_IOSurface::ProducerReleaseImpl()
{
mGL->MakeCurrent();
mGL->fFlush();

View File

@ -36,9 +36,8 @@ public:
virtual void LockProdImpl() override { }
virtual void UnlockProdImpl() override { }
virtual void Fence() override;
virtual bool WaitSync() override { return true; }
virtual bool PollSync() override { return true; }
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
GLint x, GLint y, GLsizei width, GLsizei height,

View File

@ -335,8 +335,13 @@ CloneSurface(gl::SharedSurface* src, gl::SurfaceFactory* factory)
if (!dest) {
return nullptr;
}
gl::SharedSurface* destSurf = dest->Surf();
destSurf->ProducerAcquire();
SharedSurface::ProdCopy(src, dest->Surf(), factory);
dest->Surf()->Fence();
destSurf->ProducerRelease();
return dest.forget();
}