mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Bug 1331944 - Part 1. Add SourceSurfaceSharedDataWrapper and SourceSurfaceSharedData::HandleLock. r=jrmuizel
This commit is contained in:
parent
7e4a6c3456
commit
b8f42d8fa2
@ -11,6 +11,43 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
|
|
||||||
|
bool
|
||||||
|
SourceSurfaceSharedDataWrapper::Init(const IntSize& aSize,
|
||||||
|
int32_t aStride,
|
||||||
|
SurfaceFormat aFormat,
|
||||||
|
const SharedMemoryBasic::Handle& aHandle,
|
||||||
|
base::ProcessId aCreatorPid)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!mBuf);
|
||||||
|
mSize = aSize;
|
||||||
|
mStride = aStride;
|
||||||
|
mFormat = aFormat;
|
||||||
|
mCreatorPid = aCreatorPid;
|
||||||
|
|
||||||
|
size_t len = GetAlignedDataLength();
|
||||||
|
mBuf = MakeAndAddRef<SharedMemoryBasic>();
|
||||||
|
if (NS_WARN_IF(!mBuf->SetHandle(aHandle, ipc::SharedMemory::RightsReadOnly)) ||
|
||||||
|
NS_WARN_IF(!mBuf->Map(len))) {
|
||||||
|
mBuf = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBuf->CloseHandle();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SourceSurfaceSharedDataWrapper::Init(SourceSurfaceSharedData* aSurface)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!mBuf);
|
||||||
|
MOZ_ASSERT(aSurface);
|
||||||
|
mSize = aSurface->mSize;
|
||||||
|
mStride = aSurface->mStride;
|
||||||
|
mFormat = aSurface->mFormat;
|
||||||
|
mCreatorPid = base::GetCurrentProcId();
|
||||||
|
mBuf = aSurface->mBuf;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SourceSurfaceSharedData::Init(const IntSize &aSize,
|
SourceSurfaceSharedData::Init(const IntSize &aSize,
|
||||||
int32_t aStride,
|
int32_t aStride,
|
||||||
@ -67,6 +104,7 @@ SourceSurfaceSharedData::ShareToProcess(base::ProcessId aPid,
|
|||||||
SharedMemoryBasic::Handle& aHandle)
|
SharedMemoryBasic::Handle& aHandle)
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
|
MOZ_ASSERT(mHandleCount > 0);
|
||||||
|
|
||||||
if (mClosed) {
|
if (mClosed) {
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
@ -86,6 +124,9 @@ SourceSurfaceSharedData::CloseHandleInternal()
|
|||||||
mMutex.AssertCurrentThreadOwns();
|
mMutex.AssertCurrentThreadOwns();
|
||||||
|
|
||||||
if (mClosed) {
|
if (mClosed) {
|
||||||
|
MOZ_ASSERT(mHandleCount == 0);
|
||||||
|
MOZ_ASSERT(mFinalized);
|
||||||
|
MOZ_ASSERT(mShared);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,6 +140,7 @@ bool
|
|||||||
SourceSurfaceSharedData::ReallocHandle()
|
SourceSurfaceSharedData::ReallocHandle()
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
|
MOZ_ASSERT(mHandleCount > 0);
|
||||||
MOZ_ASSERT(mClosed);
|
MOZ_ASSERT(mClosed);
|
||||||
MOZ_ASSERT(mFinalized);
|
MOZ_ASSERT(mFinalized);
|
||||||
|
|
||||||
|
@ -13,6 +13,104 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
|
|
||||||
|
class SourceSurfaceSharedData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to wrap shared (as in process) data buffers allocated by
|
||||||
|
* a SourceSurfaceSharedData object. It may live in the same process or a
|
||||||
|
* different process from the actual SourceSurfaceSharedData object.
|
||||||
|
*
|
||||||
|
* If it is in the same process, mBuf is the same object as that in the surface.
|
||||||
|
* It is a useful abstraction over just using the surface directly, because it
|
||||||
|
* can have a different lifetime from the surface; if the surface gets freed,
|
||||||
|
* consumers may continue accessing the data in the buffer. Releasing the
|
||||||
|
* original surface is a signal which feeds into SharedSurfacesParent to decide
|
||||||
|
* to release the SourceSurfaceSharedDataWrapper.
|
||||||
|
*
|
||||||
|
* If it is in a different process, mBuf is a new SharedMemoryBasic object which
|
||||||
|
* mapped in the given shared memory handle as read only memory.
|
||||||
|
*/
|
||||||
|
class SourceSurfaceSharedDataWrapper final : public DataSourceSurface
|
||||||
|
{
|
||||||
|
typedef mozilla::ipc::SharedMemoryBasic SharedMemoryBasic;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceSharedDataWrapper, override)
|
||||||
|
|
||||||
|
SourceSurfaceSharedDataWrapper()
|
||||||
|
: mStride(0)
|
||||||
|
, mFormat(SurfaceFormat::UNKNOWN)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool Init(const IntSize& aSize,
|
||||||
|
int32_t aStride,
|
||||||
|
SurfaceFormat aFormat,
|
||||||
|
const SharedMemoryBasic::Handle& aHandle,
|
||||||
|
base::ProcessId aCreatorPid);
|
||||||
|
|
||||||
|
void Init(SourceSurfaceSharedData *aSurface);
|
||||||
|
|
||||||
|
base::ProcessId GetCreatorPid() const
|
||||||
|
{
|
||||||
|
return mCreatorPid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Stride() override { return mStride; }
|
||||||
|
|
||||||
|
SurfaceType GetType() const override { return SurfaceType::DATA; }
|
||||||
|
IntSize GetSize() const override { return mSize; }
|
||||||
|
SurfaceFormat GetFormat() const override { return mFormat; }
|
||||||
|
|
||||||
|
uint8_t* GetData() override
|
||||||
|
{
|
||||||
|
return static_cast<uint8_t*>(mBuf->memory());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnHeap() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Map(MapType, MappedSurface *aMappedSurface) override
|
||||||
|
{
|
||||||
|
aMappedSurface->mData = GetData();
|
||||||
|
aMappedSurface->mStride = mStride;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unmap() override
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool AddConsumer()
|
||||||
|
{
|
||||||
|
return ++mConsumers == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RemoveConsumer()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mConsumers > 0);
|
||||||
|
return --mConsumers == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t GetDataLength() const
|
||||||
|
{
|
||||||
|
return static_cast<size_t>(mStride) * mSize.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetAlignedDataLength() const
|
||||||
|
{
|
||||||
|
return mozilla::ipc::SharedMemory::PageAlignedSize(GetDataLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mStride;
|
||||||
|
uint32_t mConsumers;
|
||||||
|
IntSize mSize;
|
||||||
|
RefPtr<SharedMemoryBasic> mBuf;
|
||||||
|
SurfaceFormat mFormat;
|
||||||
|
base::ProcessId mCreatorPid;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to wrap shared (as in process) data buffers used by a
|
* This class is used to wrap shared (as in process) data buffers used by a
|
||||||
* source surface.
|
* source surface.
|
||||||
@ -28,6 +126,7 @@ public:
|
|||||||
: mMutex("SourceSurfaceSharedData")
|
: mMutex("SourceSurfaceSharedData")
|
||||||
, mStride(0)
|
, mStride(0)
|
||||||
, mMapCount(0)
|
, mMapCount(0)
|
||||||
|
, mHandleCount(0)
|
||||||
, mFormat(SurfaceFormat::UNKNOWN)
|
, mFormat(SurfaceFormat::UNKNOWN)
|
||||||
, mClosed(false)
|
, mClosed(false)
|
||||||
, mFinalized(false)
|
, mFinalized(false)
|
||||||
@ -35,7 +134,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Init(const IntSize &aSize,
|
bool Init(const IntSize& aSize,
|
||||||
int32_t aStride,
|
int32_t aStride,
|
||||||
SurfaceFormat aFormat);
|
SurfaceFormat aFormat);
|
||||||
|
|
||||||
@ -133,17 +232,65 @@ public:
|
|||||||
bool ReallocHandle();
|
bool ReallocHandle();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates we have finished writing to the buffer and it may be marked as
|
* Signals we have finished writing to the buffer and it may be marked as
|
||||||
* read only. May release the handle if possible (see CloseHandleInternal).
|
* read only. May release the handle if possible (see CloseHandleInternal).
|
||||||
*/
|
*/
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not the buffer can change. If this returns true, it is
|
||||||
|
* guaranteed to continue to do so for the remainder of the surface's life.
|
||||||
|
*/
|
||||||
|
bool IsFinalized() const
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
return mFinalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* While a HandleLock exists for the given surface, the shared memory handle
|
||||||
|
* cannot be released.
|
||||||
|
*/
|
||||||
|
class MOZ_STACK_CLASS HandleLock final {
|
||||||
|
public:
|
||||||
|
explicit HandleLock(SourceSurfaceSharedData* aSurface)
|
||||||
|
: mSurface(aSurface)
|
||||||
|
{
|
||||||
|
mSurface->LockHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
~HandleLock()
|
||||||
|
{
|
||||||
|
mSurface->UnlockHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RefPtr<SourceSurfaceSharedData> mSurface;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class SourceSurfaceSharedDataWrapper;
|
||||||
|
|
||||||
~SourceSurfaceSharedData() override
|
~SourceSurfaceSharedData() override
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mMapCount == 0);
|
MOZ_ASSERT(mMapCount == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LockHandle()
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
++mHandleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnlockHandle()
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
MOZ_ASSERT(mHandleCount > 0);
|
||||||
|
--mHandleCount;
|
||||||
|
mShared = true;
|
||||||
|
CloseHandleInternal();
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t* GetDataInternal() const;
|
uint8_t* GetDataInternal() const;
|
||||||
|
|
||||||
size_t GetDataLength() const
|
size_t GetDataLength() const
|
||||||
@ -165,6 +312,7 @@ private:
|
|||||||
mutable Mutex mMutex;
|
mutable Mutex mMutex;
|
||||||
int32_t mStride;
|
int32_t mStride;
|
||||||
int32_t mMapCount;
|
int32_t mMapCount;
|
||||||
|
int32_t mHandleCount;
|
||||||
IntSize mSize;
|
IntSize mSize;
|
||||||
RefPtr<SharedMemoryBasic> mBuf;
|
RefPtr<SharedMemoryBasic> mBuf;
|
||||||
RefPtr<SharedMemoryBasic> mOldBuf;
|
RefPtr<SharedMemoryBasic> mOldBuf;
|
||||||
|
Loading…
Reference in New Issue
Block a user