/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 4; -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* SharedSurface abstracts an actual surface (can be a GL texture, but * not necessarily) that handles sharing. * Its specializations are: * SharedSurface_Basic (client-side bitmap, does readback) * SharedSurface_GLTexture * SharedSurface_EGLImage * SharedSurface_ANGLEShareHandle */ #ifndef SHARED_SURFACE_H_ #define SHARED_SURFACE_H_ #include #include #include #include "GLContext.h" // Bug 1635644 #include "GLContextTypes.h" #include "GLDefs.h" #include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" #include "mozilla/gfx/Point.h" #include "mozilla/Mutex.h" #include "mozilla/UniquePtr.h" #include "mozilla/WeakPtr.h" #include "SurfaceTypes.h" class nsIThread; namespace mozilla { namespace gfx { class DataSourceSurface; class DrawTarget; } // namespace gfx namespace layers { class KnowsCompositor; enum class LayersBackend : int8_t; class LayersIPCChannel; class SharedSurfaceTextureClient; class SurfaceDescriptor; class TextureClient; enum class TextureFlags : uint32_t; enum class TextureType : int8_t; } // namespace layers namespace gl { class MozFramebuffer; struct ScopedBindFramebuffer; class SurfaceFactory; struct PartialSharedSurfaceDesc { const WeakPtr gl; const SharedSurfaceType type; const layers::TextureType consumerType; const bool canRecycle; bool operator==(const PartialSharedSurfaceDesc& rhs) const { return gl == rhs.gl && type == rhs.type && consumerType == rhs.consumerType && canRecycle == rhs.canRecycle; } }; struct SharedSurfaceDesc : public PartialSharedSurfaceDesc { gfx::IntSize size = {}; gfx::ColorSpace2 colorSpace = gfx::ColorSpace2::UNKNOWN; bool operator==(const SharedSurfaceDesc& rhs) const { return PartialSharedSurfaceDesc::operator==(rhs) && size == rhs.size && colorSpace == rhs.colorSpace; } bool operator!=(const SharedSurfaceDesc& rhs) const { return !(*this == rhs); } }; class SharedSurface { public: const SharedSurfaceDesc mDesc; const UniquePtr mFb; // null if we should use fb=0. protected: bool mIsLocked = false; bool mIsProducerAcquired = false; SharedSurface(const SharedSurfaceDesc&, UniquePtr); public: virtual ~SharedSurface(); bool IsLocked() const { return mIsLocked; } bool IsProducerAcquired() const { return mIsProducerAcquired; } // This locks the SharedSurface as the production buffer for the context. // This is needed by backends which use PBuffers and/or EGLSurfaces. void LockProd(); // Unlocking is harmless if we're already unlocked. void UnlockProd(); // This surface has been moved to the front buffer and will not be locked // again until it is recycled. Do any finalization steps here. virtual void Commit() {} protected: virtual void LockProdImpl(){}; virtual void UnlockProdImpl(){}; virtual void ProducerAcquireImpl(){}; virtual void ProducerReleaseImpl(){}; virtual void ProducerReadAcquireImpl() { ProducerAcquireImpl(); } virtual void ProducerReadReleaseImpl() { ProducerReleaseImpl(); } public: void ProducerAcquire() { MOZ_ASSERT(!mIsProducerAcquired); ProducerAcquireImpl(); mIsProducerAcquired = true; } void ProducerRelease() { MOZ_ASSERT(mIsProducerAcquired); ProducerReleaseImpl(); mIsProducerAcquired = false; } void ProducerReadAcquire() { MOZ_ASSERT(!mIsProducerAcquired); ProducerReadAcquireImpl(); mIsProducerAcquired = true; } void ProducerReadRelease() { MOZ_ASSERT(mIsProducerAcquired); ProducerReadReleaseImpl(); mIsProducerAcquired = false; } // This function waits until the buffer is no longer being used. // To optimize the performance, some implementaions recycle SharedSurfaces // even when its buffer is still being used. virtual void WaitForBufferOwnership() {} // Returns true if the buffer is available. // You can call WaitForBufferOwnership to wait for availability. virtual bool IsBufferAvailable() const { return true; } virtual bool NeedsIndirectReads() const { return false; } // Returns true if the surface is still valid to use. If false, the underlying // resource has been released and we must allocate a new surface instead. virtual bool IsValid() const { return true; }; virtual Maybe ToSurfaceDescriptor() = 0; }; // - class SurfaceFactory { public: const PartialSharedSurfaceDesc mDesc; layers::TextureType GetConsumerType() const { return mDesc.consumerType; } protected: Mutex mMutex MOZ_UNANNOTATED; public: static UniquePtr Create(GLContext*, layers::TextureType); protected: explicit SurfaceFactory(const PartialSharedSurfaceDesc&); public: virtual ~SurfaceFactory(); protected: virtual UniquePtr CreateSharedImpl( const SharedSurfaceDesc&) = 0; public: UniquePtr CreateShared(const gfx::IntSize& size, gfx::ColorSpace2 cs) { return CreateSharedImpl({mDesc, size, cs}); } }; template inline UniquePtr AsUnique(T* const p) { return UniquePtr(p); } } // namespace gl } // namespace mozilla #endif // SHARED_SURFACE_H_