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         mFormat(SurfaceFormat::UNKNOWN),
34         mWasPurged(false) {}
35 
36   bool Init(const IntSize& aSize, int32_t aStride, SurfaceFormat aFormat);
37 
GetData()38   uint8_t* GetData() override { return mVBufPtr; }
Stride()39   int32_t Stride() override { return mStride; }
40 
GetType()41   SurfaceType GetType() const override { return SurfaceType::DATA; }
GetSize()42   IntSize GetSize() const override { return mSize; }
GetFormat()43   SurfaceFormat GetFormat() const override { return mFormat; }
44 
45   void GuaranteePersistance() override;
46 
47   void SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
48                            SizeOfInfo& aInfo) const override;
49 
OnHeap()50   bool OnHeap() const override { return mVBuf->OnHeap(); }
51 
52   // Althought Map (and Moz2D in general) isn't normally threadsafe,
53   // we want to allow it for SourceSurfaceVolatileData since it should
54   // always be fine (for reading at least).
55   //
56   // This is the same as the base class implementation except using
57   // mMapCount instead of mIsMapped since that breaks for multithread.
Map(MapType,MappedSurface * aMappedSurface)58   bool Map(MapType, MappedSurface* aMappedSurface) override {
59     MutexAutoLock lock(mMutex);
60     if (mWasPurged) {
61       return false;
62     }
63     if (mMapCount == 0) {
64       mVBufPtr = mVBuf;
65     }
66     if (mVBufPtr.WasBufferPurged()) {
67       mWasPurged = true;
68       return false;
69     }
70     aMappedSurface->mData = mVBufPtr;
71     aMappedSurface->mStride = mStride;
72     ++mMapCount;
73     return true;
74   }
75 
Unmap()76   void Unmap() override {
77     MutexAutoLock lock(mMutex);
78     MOZ_ASSERT(mMapCount > 0);
79     MOZ_ASSERT(!mWasPurged);
80     if (--mMapCount == 0) {
81       mVBufPtr = nullptr;
82     }
83   }
84 
85  private:
86   virtual ~SourceSurfaceVolatileData() = default;
87 
88   Mutex mMutex;
89   int32_t mStride;
90   IntSize mSize;
91   RefPtr<VolatileBuffer> mVBuf;
92   VolatileBufferPtr<uint8_t> mVBufPtr;
93   SurfaceFormat mFormat;
94   bool mWasPurged;
95 };
96 
97 }  // namespace gfx
98 }  // namespace mozilla
99 
100 #endif /* MOZILLA_GFX_SOURCESURFACEVOLATILEDATA_H_ */
101