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