1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MOZILLA_GFX_SOURCESURFACEVOLATILEDATA_H_ 8 #define MOZILLA_GFX_SOURCESURFACEVOLATILEDATA_H_ 9 10 #include "mozilla/gfx/2D.h" 11 #include "mozilla/Mutex.h" 12 #include "mozilla/VolatileBuffer.h" 13 14 namespace mozilla { 15 namespace gfx { 16 17 /** 18 * This class is used to wrap volatile data buffers used for source surfaces. 19 * The Map and Unmap semantics are used to guarantee that the volatile data 20 * buffer is not freed by the operating system while the surface is in active 21 * use. If GetData is expected to return a non-null value without a 22 * corresponding Map call (and verification of the result), the surface data 23 * should be wrapped in a temporary SourceSurfaceRawData with a ScopedMap 24 * closure. 25 */ 26 class SourceSurfaceVolatileData : public DataSourceSurface { 27 public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceVolatileData,override)28 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceVolatileData, override) 29 30 SourceSurfaceVolatileData() 31 : mMutex("SourceSurfaceVolatileData"), 32 mStride(0), 33 mMapCount(0), 34 mFormat(SurfaceFormat::UNKNOWN), 35 mWasPurged(false) {} 36 37 bool Init(const IntSize& aSize, int32_t aStride, SurfaceFormat aFormat); 38 GetData()39 uint8_t* GetData() override { return mVBufPtr; } Stride()40 int32_t Stride() override { return mStride; } 41 GetType()42 SurfaceType GetType() const override { return SurfaceType::DATA; } GetSize()43 IntSize GetSize() const override { return mSize; } GetFormat()44 SurfaceFormat GetFormat() const override { return mFormat; } 45 46 void GuaranteePersistance() override; 47 48 void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, size_t& aHeapSizeOut, 49 size_t& aNonHeapSizeOut, 50 size_t& aExtHandlesOut) const override; 51 OnHeap()52 bool OnHeap() const override { return mVBuf->OnHeap(); } 53 54 // Althought Map (and Moz2D in general) isn't normally threadsafe, 55 // we want to allow it for SourceSurfaceVolatileData since it should 56 // always be fine (for reading at least). 57 // 58 // This is the same as the base class implementation except using 59 // mMapCount instead of mIsMapped since that breaks for multithread. Map(MapType,MappedSurface * aMappedSurface)60 bool Map(MapType, MappedSurface* aMappedSurface) override { 61 MutexAutoLock lock(mMutex); 62 if (mWasPurged) { 63 return false; 64 } 65 if (mMapCount == 0) { 66 mVBufPtr = mVBuf; 67 } 68 if (mVBufPtr.WasBufferPurged()) { 69 mWasPurged = true; 70 return false; 71 } 72 aMappedSurface->mData = mVBufPtr; 73 aMappedSurface->mStride = mStride; 74 ++mMapCount; 75 return true; 76 } 77 Unmap()78 void Unmap() override { 79 MutexAutoLock lock(mMutex); 80 MOZ_ASSERT(mMapCount > 0); 81 MOZ_ASSERT(!mWasPurged); 82 if (--mMapCount == 0) { 83 mVBufPtr = nullptr; 84 } 85 } 86 87 private: ~SourceSurfaceVolatileData()88 ~SourceSurfaceVolatileData() override { MOZ_ASSERT(mMapCount == 0); } 89 90 Mutex mMutex; 91 int32_t mStride; 92 int32_t mMapCount; 93 IntSize mSize; 94 RefPtr<VolatileBuffer> mVBuf; 95 VolatileBufferPtr<uint8_t> mVBufPtr; 96 SurfaceFormat mFormat; 97 bool mWasPurged; 98 }; 99 100 } // namespace gfx 101 } // namespace mozilla 102 103 #endif /* MOZILLA_GFX_SOURCESURFACEVOLATILEDATA_H_ */ 104