1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef MOZILLA_GFX_PersistentBUFFERPROVIDER_H 7 #define MOZILLA_GFX_PersistentBUFFERPROVIDER_H 8 9 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 10 #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed, etc 11 #include "mozilla/layers/LayersTypes.h" 12 #include "mozilla/layers/ShadowLayers.h" 13 #include "mozilla/gfx/Types.h" 14 #include "mozilla/Vector.h" 15 16 namespace mozilla { 17 18 namespace gfx { 19 class SourceSurface; 20 class DrawTarget; 21 } 22 23 namespace layers { 24 25 class CopyableCanvasLayer; 26 27 /** 28 * A PersistentBufferProvider is for users which require the temporary use of 29 * a DrawTarget to draw into. When they're done drawing they return the 30 * DrawTarget, when they later need to continue drawing they get a DrawTarget 31 * from the provider again, the provider will guarantee the contents of the 32 * previously returned DrawTarget is persisted into the one newly returned. 33 */ 34 class PersistentBufferProvider : public RefCounted<PersistentBufferProvider> 35 { 36 public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProvider)37 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProvider) 38 39 virtual ~PersistentBufferProvider() { } 40 GetType()41 virtual LayersBackend GetType() { return LayersBackend::LAYERS_NONE; } 42 43 /** 44 * Get a DrawTarget from the PersistentBufferProvider. 45 * 46 * \param aPersistedRect This indicates the area of the DrawTarget that needs 47 * to have remained the same since the call to 48 * ReturnDrawTarget. 49 */ 50 virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) = 0; 51 52 /** 53 * Return a DrawTarget to the PersistentBufferProvider and indicate the 54 * contents of this DrawTarget is to be considered current by the 55 * BufferProvider. The caller should forget any references to the DrawTarget. 56 */ 57 virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) = 0; 58 59 virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() = 0; 60 61 virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) = 0; 62 GetTextureClient()63 virtual TextureClient* GetTextureClient() { return nullptr; } 64 OnShutdown()65 virtual void OnShutdown() {} 66 SetForwarder(ShadowLayerForwarder * aFwd)67 virtual bool SetForwarder(ShadowLayerForwarder* aFwd) { return true; } 68 69 /** 70 * Return true if this provider preserves the drawing state (clips, transforms, 71 * etc.) across frames. In practice this means users of the provider can skip 72 * popping all of the clips at the end of the frames and pushing them back at 73 * the beginning of the following frames, which can be costly (cf. bug 1294351). 74 */ 75 virtual bool PreservesDrawingState() const = 0; 76 }; 77 78 79 class PersistentBufferProviderBasic : public PersistentBufferProvider 80 { 81 public: 82 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic, override) 83 84 static already_AddRefed<PersistentBufferProviderBasic> 85 Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, gfx::BackendType aBackend); 86 87 explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget); 88 GetType()89 virtual LayersBackend GetType() override { return LayersBackend::LAYERS_BASIC; } 90 91 virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) override; 92 93 virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override; 94 95 virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() override; 96 97 virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override; 98 PreservesDrawingState()99 virtual bool PreservesDrawingState() const override { return true; } 100 private: 101 ~PersistentBufferProviderBasic(); 102 103 RefPtr<gfx::DrawTarget> mDrawTarget; 104 RefPtr<gfx::SourceSurface> mSnapshot; 105 }; 106 107 108 /** 109 * Provides access to a buffer which can be sent to the compositor without 110 * requiring a copy. 111 */ 112 class PersistentBufferProviderShared : public PersistentBufferProvider 113 , public ActiveResource 114 { 115 public: 116 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderShared, override) 117 118 static already_AddRefed<PersistentBufferProviderShared> 119 Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, 120 ShadowLayerForwarder* aFwd); 121 GetType()122 virtual LayersBackend GetType() override { return LayersBackend::LAYERS_CLIENT; } 123 124 virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) override; 125 126 virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override; 127 128 virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() override; 129 130 virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override; 131 132 virtual TextureClient* GetTextureClient() override; 133 134 virtual void NotifyInactive() override; 135 OnShutdown()136 virtual void OnShutdown() override { Destroy(); } 137 138 virtual bool SetForwarder(ShadowLayerForwarder* aFwd) override; 139 PreservesDrawingState()140 virtual bool PreservesDrawingState() const override { return false; } 141 protected: 142 PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, 143 ShadowLayerForwarder* aFwd, 144 RefPtr<TextureClient>& aTexture); 145 146 ~PersistentBufferProviderShared(); 147 148 TextureClient* GetTexture(Maybe<uint32_t> aIndex); CheckIndex(uint32_t aIndex)149 bool CheckIndex(uint32_t aIndex) { return aIndex < mTextures.length(); } 150 151 void Destroy(); 152 153 gfx::IntSize mSize; 154 gfx::SurfaceFormat mFormat; 155 RefPtr<ShadowLayerForwarder> mFwd; 156 Vector<RefPtr<TextureClient>, 4> mTextures; 157 // Offset of the texture in mTextures that the canvas uses. 158 Maybe<uint32_t> mBack; 159 // Offset of the texture in mTextures that is presented to the compositor. 160 Maybe<uint32_t> mFront; 161 162 RefPtr<gfx::DrawTarget> mDrawTarget; 163 RefPtr<gfx::SourceSurface > mSnapshot; 164 }; 165 166 struct AutoReturnSnapshot 167 { 168 PersistentBufferProvider* mBufferProvider; 169 RefPtr<gfx::SourceSurface>* mSnapshot; 170 171 explicit AutoReturnSnapshot(PersistentBufferProvider* aProvider = nullptr) mBufferProviderAutoReturnSnapshot172 : mBufferProvider(aProvider) 173 , mSnapshot(nullptr) 174 {} 175 ~AutoReturnSnapshotAutoReturnSnapshot176 ~AutoReturnSnapshot() 177 { 178 if (mBufferProvider) { 179 mBufferProvider->ReturnSnapshot(mSnapshot ? mSnapshot->forget() : nullptr); 180 } 181 } 182 }; 183 184 } // namespace layers 185 } // namespace mozilla 186 187 #endif 188