/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/** * 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 SharedMemory object which * mapped in the given shared memory handle as read only memory.
*/ class SourceSurfaceSharedDataWrapper final : public DataSourceSurface { typedef mozilla::ipc::SharedMemory SharedMemory;
/** * This class is used to wrap shared (as in process) data buffers used by a * source surface.
*/ class SourceSurfaceSharedData : public DataSourceSurface { typedef mozilla::ipc::SharedMemory SharedMemory;
/** * Initialize the surface by creating a shared memory buffer with a size * determined by aSize, aStride and aFormat. If aShare is true, it will also * immediately attempt to share the surface with the GPU process via * SharedSurfacesChild.
*/ bool Init(const IntSize& aSize, int32_t aStride, SurfaceFormat aFormat, bool aShare = true);
uint8_t* GetData() final {
MutexAutoLock lock(mMutex); return GetDataInternal();
}
/** * Although Map (and Moz2D in general) isn't normally threadsafe, * we want to allow it for SourceSurfaceSharedData since it should * always be fine (for reading at least). * * This is the same as the base class implementation except using * mMapCount instead of mIsMapped since that breaks for multithread. * * Additionally if a reallocation happened while there were active * mappings, then we guarantee that GetData will continue to return * the same data pointer by retaining the old shared buffer until * the last mapping is freed via Unmap.
*/ bool Map(MapType aMapType, MappedSurface* aMappedSurface) final {
MutexAutoLock lock(mMutex); if (mFinalized && aMapType != MapType::READ) { // Once finalized the data may be write-protected returnfalse;
}
++mMapCount;
aMappedSurface->mData = GetDataInternal();
aMappedSurface->mStride = mStride; returntrue;
}
void Unmap() final {
MutexAutoLock lock(mMutex);
MOZ_ASSERT(mMapCount > 0); if (--mMapCount == 0) {
mOldBuf = nullptr;
}
}
/** * Get a handle to share to another process for this buffer. Returns: * NS_OK -- success, aHandle is valid. * NS_ERROR_NOT_AVAILABLE -- handle was closed, need to reallocate. * NS_ERROR_FAILURE -- failed to create a handle to share.
*/
nsresult CloneHandle(SharedMemory::Handle& aHandle);
/** * Indicates the buffer is not expected to be shared with any more processes. * May release the handle if possible (see CloseHandleInternal).
*/ void FinishedSharing() {
MutexAutoLock lock(mMutex);
mShared = true;
CloseHandleInternal();
}
/** * Indicates whether or not the buffer can be shared with another process * without reallocating. Note that this is racy and should only be used for * informational/reporting purposes.
*/ bool CanShare() const {
MutexAutoLock lock(mMutex); return !mClosed;
}
/** * Allocate a new shared memory buffer so that we can get a new handle for * sharing to new processes. CloneHandle must have failed with * NS_ERROR_NOT_AVAILABLE in order for this to be safe to call. Returns true * if the operation succeeds. If it fails, there is no state change.
*/ bool ReallocHandle();
/** * Signals we have finished writing to the buffer and it may be marked as * read only.
*/ 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;
}
/** * Yields a dirty rect of what has changed since it was last called.
*/
Maybe<IntRect> TakeDirtyRect() final {
MutexAutoLock lock(mMutex); if (mDirtyRect) {
Maybe<IntRect> ret = std::move(mDirtyRect); return ret;
} return Nothing();
}
/** * 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();
}
/** * Attempt to close the handle. Only if the buffer has been both finalized * and we have completed sharing will it be released.
*/ void CloseHandleInternal();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.