summaryrefslogtreecommitdiffstats
path: root/gfx/gl/SharedSurface.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/gl/SharedSurface.h')
-rw-r--r--gfx/gl/SharedSurface.h199
1 files changed, 199 insertions, 0 deletions
diff --git a/gfx/gl/SharedSurface.h b/gfx/gl/SharedSurface.h
new file mode 100644
index 0000000000..4168de69a2
--- /dev/null
+++ b/gfx/gl/SharedSurface.h
@@ -0,0 +1,199 @@
+/* -*- 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 <queue>
+#include <set>
+#include <stdint.h>
+
+#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<GLContext> 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<MozFramebuffer> mFb; // null if we should use fb=0.
+
+ protected:
+ bool mIsLocked = false;
+ bool mIsProducerAcquired = false;
+
+ SharedSurface(const SharedSurfaceDesc&, UniquePtr<MozFramebuffer>);
+
+ 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<layers::SurfaceDescriptor> ToSurfaceDescriptor() = 0;
+};
+
+// -
+
+class SurfaceFactory {
+ public:
+ const PartialSharedSurfaceDesc mDesc;
+
+ layers::TextureType GetConsumerType() const { return mDesc.consumerType; }
+
+ protected:
+ Mutex mMutex MOZ_UNANNOTATED;
+
+ public:
+ static UniquePtr<SurfaceFactory> Create(GLContext*, layers::TextureType);
+
+ protected:
+ explicit SurfaceFactory(const PartialSharedSurfaceDesc&);
+
+ public:
+ virtual ~SurfaceFactory();
+
+ protected:
+ virtual UniquePtr<SharedSurface> CreateSharedImpl(
+ const SharedSurfaceDesc&) = 0;
+
+ public:
+ UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size,
+ gfx::ColorSpace2 cs) {
+ return CreateSharedImpl({mDesc, size, cs});
+ }
+};
+
+template <typename T>
+inline UniquePtr<T> AsUnique(T* const p) {
+ return UniquePtr<T>(p);
+}
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // SHARED_SURFACE_H_