SharedSurface.h (5983B)
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 4; -*- */ 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 /* SharedSurface abstracts an actual surface (can be a GL texture, but 7 * not necessarily) that handles sharing. 8 * Its specializations are: 9 * SharedSurface_Basic (client-side bitmap, does readback) 10 * SharedSurface_GLTexture 11 * SharedSurface_EGLImage 12 * SharedSurface_ANGLEShareHandle 13 */ 14 15 #ifndef SHARED_SURFACE_H_ 16 #define SHARED_SURFACE_H_ 17 18 #include <queue> 19 #include <stdint.h> 20 21 #include "GLContext.h" // Bug 1635644 22 #include "GLContextTypes.h" 23 #include "GLDefs.h" 24 #include "mozilla/Attributes.h" 25 #include "mozilla/gfx/Point.h" 26 #include "mozilla/Mutex.h" 27 #include "mozilla/UniquePtr.h" 28 #include "mozilla/WeakPtr.h" 29 #include "SurfaceTypes.h" 30 31 class nsIThread; 32 33 namespace mozilla { 34 namespace gfx { 35 class DataSourceSurface; 36 class DrawTarget; 37 } // namespace gfx 38 39 namespace layers { 40 class KnowsCompositor; 41 enum class LayersBackend : int8_t; 42 class LayersIPCChannel; 43 class SharedSurfaceTextureClient; 44 class SurfaceDescriptor; 45 class TextureClient; 46 enum class TextureFlags : uint32_t; 47 enum class TextureType : int8_t; 48 } // namespace layers 49 50 namespace gl { 51 52 class MozFramebuffer; 53 struct ScopedBindFramebuffer; 54 class SurfaceFactory; 55 56 struct PartialSharedSurfaceDesc { 57 const WeakPtr<GLContext> gl; 58 const SharedSurfaceType type; 59 const layers::TextureType consumerType; 60 const bool canRecycle; 61 62 bool operator==(const PartialSharedSurfaceDesc& rhs) const { 63 return gl == rhs.gl && type == rhs.type && 64 consumerType == rhs.consumerType && canRecycle == rhs.canRecycle; 65 } 66 }; 67 struct SharedSurfaceDesc : public PartialSharedSurfaceDesc { 68 gfx::IntSize size = {}; 69 gfx::ColorSpace2 colorSpace = gfx::ColorSpace2::UNKNOWN; 70 71 bool operator==(const SharedSurfaceDesc& rhs) const { 72 return PartialSharedSurfaceDesc::operator==(rhs) && size == rhs.size && 73 colorSpace == rhs.colorSpace; 74 } 75 bool operator!=(const SharedSurfaceDesc& rhs) const { 76 return !(*this == rhs); 77 } 78 }; 79 80 class SharedSurface { 81 public: 82 const SharedSurfaceDesc mDesc; 83 const UniquePtr<MozFramebuffer> mFb; // null if we should use fb=0. 84 85 protected: 86 bool mIsLocked = false; 87 bool mIsProducerAcquired = false; 88 89 SharedSurface(const SharedSurfaceDesc&, UniquePtr<MozFramebuffer>); 90 91 public: 92 virtual ~SharedSurface(); 93 94 bool IsLocked() const { return mIsLocked; } 95 bool IsProducerAcquired() const { return mIsProducerAcquired; } 96 97 // This locks the SharedSurface as the production buffer for the context. 98 // This is needed by backends which use PBuffers and/or EGLSurfaces. 99 void LockProd(); 100 101 // Unlocking is harmless if we're already unlocked. 102 void UnlockProd(); 103 104 // This surface has been moved to the front buffer and will not be locked 105 // again until it is recycled. Do any finalization steps here. 106 virtual void Commit() {} 107 108 protected: 109 virtual void LockProdImpl() {}; 110 virtual void UnlockProdImpl() {}; 111 112 virtual void ProducerAcquireImpl() {}; 113 virtual void ProducerReleaseImpl() {}; 114 115 virtual void ProducerReadAcquireImpl() { ProducerAcquireImpl(); } 116 virtual void ProducerReadReleaseImpl() { ProducerReleaseImpl(); } 117 118 public: 119 void ProducerAcquire() { 120 MOZ_ASSERT(!mIsProducerAcquired); 121 ProducerAcquireImpl(); 122 mIsProducerAcquired = true; 123 } 124 void ProducerRelease() { 125 MOZ_ASSERT(mIsProducerAcquired); 126 ProducerReleaseImpl(); 127 mIsProducerAcquired = false; 128 } 129 void ProducerReadAcquire() { 130 MOZ_ASSERT(!mIsProducerAcquired); 131 ProducerReadAcquireImpl(); 132 mIsProducerAcquired = true; 133 } 134 void ProducerReadRelease() { 135 MOZ_ASSERT(mIsProducerAcquired); 136 ProducerReadReleaseImpl(); 137 mIsProducerAcquired = false; 138 } 139 140 // This function waits until the buffer is no longer being used. 141 // To optimize the performance, some implementaions recycle SharedSurfaces 142 // even when its buffer is still being used. 143 virtual void WaitForBufferOwnership() {} 144 145 // Returns true if the buffer is available. 146 // You can call WaitForBufferOwnership to wait for availability. 147 virtual bool IsBufferAvailable() const { return true; } 148 149 virtual bool NeedsIndirectReads() const { return false; } 150 151 // Returns true if the surface is still valid to use. If false, the underlying 152 // resource has been released and we must allocate a new surface instead. 153 virtual bool IsValid() const { return true; }; 154 155 virtual Maybe<layers::SurfaceDescriptor> ToSurfaceDescriptor() = 0; 156 157 void BeginWrite() { 158 WaitForBufferOwnership(); 159 ProducerAcquire(); 160 LockProd(); 161 } 162 163 void EndWrite() { 164 UnlockProd(); 165 ProducerRelease(); 166 Commit(); 167 } 168 169 void BeginRead() { 170 WaitForBufferOwnership(); 171 LockProd(); 172 ProducerReadAcquire(); 173 } 174 175 void EndRead() { 176 ProducerReadRelease(); 177 UnlockProd(); 178 } 179 }; 180 181 // - 182 183 class SurfaceFactory { 184 public: 185 const PartialSharedSurfaceDesc mDesc; 186 187 layers::TextureType GetConsumerType() const { return mDesc.consumerType; } 188 189 protected: 190 Mutex mMutex MOZ_UNANNOTATED; 191 192 public: 193 static UniquePtr<SurfaceFactory> Create(GLContext*, layers::TextureType); 194 195 protected: 196 explicit SurfaceFactory(const PartialSharedSurfaceDesc&); 197 198 public: 199 virtual ~SurfaceFactory(); 200 201 protected: 202 virtual UniquePtr<SharedSurface> CreateSharedImpl( 203 const SharedSurfaceDesc&) = 0; 204 205 public: 206 virtual bool SupportsCspaces() const { return false; } 207 208 UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size, 209 gfx::ColorSpace2 cs) { 210 if (!SupportsCspaces()) { 211 cs = gfx::ColorSpace2::Display; 212 } 213 return CreateSharedImpl({mDesc, size, cs}); 214 } 215 }; 216 217 template <typename T> 218 inline UniquePtr<T> AsUnique(T* const p) { 219 return UniquePtr<T>(p); 220 } 221 222 } // namespace gl 223 } // namespace mozilla 224 225 #endif // SHARED_SURFACE_H_