summaryrefslogtreecommitdiff
path: root/gfx/gl/GLScreenBuffer.h
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /gfx/gl/GLScreenBuffer.h
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/gl/GLScreenBuffer.h')
-rw-r--r--gfx/gl/GLScreenBuffer.h301
1 files changed, 301 insertions, 0 deletions
diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h
new file mode 100644
index 0000000000..6cacf221db
--- /dev/null
+++ b/gfx/gl/GLScreenBuffer.h
@@ -0,0 +1,301 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* 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/. */
+
+/* GLScreenBuffer is the abstraction for the "default framebuffer" used
+ * by an offscreen GLContext. Since it's only for offscreen GLContext's,
+ * it's only useful for things like WebGL, and is NOT used by the
+ * compositor's GLContext. Remember that GLContext provides an abstraction
+ * so that even if you want to draw to the 'screen', even if that's not
+ * actually the screen, just draw to 0. This GLScreenBuffer class takes the
+ * logic handling out of GLContext.
+*/
+
+#ifndef SCREEN_BUFFER_H_
+#define SCREEN_BUFFER_H_
+
+#include "GLContextTypes.h"
+#include "GLDefs.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/UniquePtr.h"
+#include "SharedSurface.h"
+#include "SurfaceTypes.h"
+
+namespace mozilla {
+namespace layers {
+class KnowsCompositor;
+class LayersIPCChannel;
+class SharedSurfaceTextureClient;
+} // namespace layers
+
+namespace gl {
+
+class GLContext;
+class SharedSurface;
+class ShSurfHandle;
+class SurfaceFactory;
+
+class DrawBuffer
+{
+public:
+ // Fallible!
+ // But it may return true with *out_buffer==nullptr if unneeded.
+ static bool Create(GLContext* const gl,
+ const SurfaceCaps& caps,
+ const GLFormats& formats,
+ const gfx::IntSize& size,
+ UniquePtr<DrawBuffer>* out_buffer);
+
+protected:
+ GLContext* const mGL;
+public:
+ const gfx::IntSize mSize;
+ const GLsizei mSamples;
+ const GLuint mFB;
+protected:
+ const GLuint mColorMSRB;
+ const GLuint mDepthRB;
+ const GLuint mStencilRB;
+
+ DrawBuffer(GLContext* gl,
+ const gfx::IntSize& size,
+ GLsizei samples,
+ GLuint fb,
+ GLuint colorMSRB,
+ GLuint depthRB,
+ GLuint stencilRB)
+ : mGL(gl)
+ , mSize(size)
+ , mSamples(samples)
+ , mFB(fb)
+ , mColorMSRB(colorMSRB)
+ , mDepthRB(depthRB)
+ , mStencilRB(stencilRB)
+ {}
+
+public:
+ virtual ~DrawBuffer();
+};
+
+class ReadBuffer
+{
+public:
+ // Infallible, always non-null.
+ static UniquePtr<ReadBuffer> Create(GLContext* gl,
+ const SurfaceCaps& caps,
+ const GLFormats& formats,
+ SharedSurface* surf);
+
+protected:
+ GLContext* const mGL;
+public:
+ const GLuint mFB;
+protected:
+ // mFB has the following attachments:
+ const GLuint mDepthRB;
+ const GLuint mStencilRB;
+ // note no mColorRB here: this is provided by mSurf.
+ SharedSurface* mSurf;
+
+ ReadBuffer(GLContext* gl,
+ GLuint fb,
+ GLuint depthRB,
+ GLuint stencilRB,
+ SharedSurface* surf)
+ : mGL(gl)
+ , mFB(fb)
+ , mDepthRB(depthRB)
+ , mStencilRB(stencilRB)
+ , mSurf(surf)
+ {}
+
+public:
+ virtual ~ReadBuffer();
+
+ // Cannot attach a surf of a different AttachType or Size than before.
+ void Attach(SharedSurface* surf);
+
+ const gfx::IntSize& Size() const;
+
+ SharedSurface* SharedSurf() const {
+ return mSurf;
+ }
+
+ void SetReadBuffer(GLenum mode) const;
+};
+
+
+class GLScreenBuffer
+{
+public:
+ // Infallible.
+ static UniquePtr<GLScreenBuffer> Create(GLContext* gl,
+ const gfx::IntSize& size,
+ const SurfaceCaps& caps);
+
+ static UniquePtr<SurfaceFactory>
+ CreateFactory(GLContext* gl,
+ const SurfaceCaps& caps,
+ layers::KnowsCompositor* compositorConnection,
+ const layers::TextureFlags& flags);
+ static UniquePtr<SurfaceFactory>
+ CreateFactory(GLContext* gl,
+ const SurfaceCaps& caps,
+ layers::LayersIPCChannel* ipcChannel,
+ const mozilla::layers::LayersBackend backend,
+ const layers::TextureFlags& flags);
+
+protected:
+ GLContext* const mGL; // Owns us.
+public:
+ const SurfaceCaps mCaps;
+protected:
+ UniquePtr<SurfaceFactory> mFactory;
+
+ RefPtr<layers::SharedSurfaceTextureClient> mBack;
+ RefPtr<layers::SharedSurfaceTextureClient> mFront;
+
+ UniquePtr<DrawBuffer> mDraw;
+ UniquePtr<ReadBuffer> mRead;
+
+ bool mNeedsBlit;
+
+ GLenum mUserReadBufferMode;
+ GLenum mUserDrawBufferMode;
+
+ // Below are the parts that help us pretend to be framebuffer 0:
+ GLuint mUserDrawFB;
+ GLuint mUserReadFB;
+ GLuint mInternalDrawFB;
+ GLuint mInternalReadFB;
+
+#ifdef DEBUG
+ bool mInInternalMode_DrawFB;
+ bool mInInternalMode_ReadFB;
+#endif
+
+ GLScreenBuffer(GLContext* gl,
+ const SurfaceCaps& caps,
+ UniquePtr<SurfaceFactory> factory);
+
+public:
+ virtual ~GLScreenBuffer();
+
+ SurfaceFactory* Factory() const {
+ return mFactory.get();
+ }
+
+ const RefPtr<layers::SharedSurfaceTextureClient>& Front() const {
+ return mFront;
+ }
+
+ SharedSurface* SharedSurf() const {
+ MOZ_ASSERT(mRead);
+ return mRead->SharedSurf();
+ }
+
+ bool ShouldPreserveBuffer() const {
+ return mCaps.preserve;
+ }
+
+ GLuint DrawFB() const {
+ if (!mDraw)
+ return ReadFB();
+
+ return mDraw->mFB;
+ }
+
+ GLuint ReadFB() const {
+ return mRead->mFB;
+ }
+
+ GLsizei Samples() const {
+ if (!mDraw)
+ return 0;
+
+ return mDraw->mSamples;
+ }
+
+ uint32_t DepthBits() const;
+
+ void DeletingFB(GLuint fb);
+
+ const gfx::IntSize& Size() const {
+ MOZ_ASSERT(mRead);
+ MOZ_ASSERT(!mDraw || mDraw->mSize == mRead->Size());
+ return mRead->Size();
+ }
+
+ void BindAsFramebuffer(GLContext* const gl, GLenum target) const;
+
+ void RequireBlit();
+ void AssureBlitted();
+ void AfterDrawCall();
+ void BeforeReadCall();
+
+ bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
+ GLint y, GLsizei width, GLsizei height, GLint border);
+
+ void SetReadBuffer(GLenum userMode);
+ void SetDrawBuffer(GLenum userMode);
+
+ GLenum GetReadBufferMode() const { return mUserReadBufferMode; }
+ GLenum GetDrawBufferMode() const { return mUserDrawBufferMode; }
+
+ /**
+ * Attempts to read pixels from the current bound framebuffer, if
+ * it is backed by a SharedSurface.
+ *
+ * Returns true if the pixel data has been read back, false
+ * otherwise.
+ */
+ bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid* pixels);
+
+ // Morph changes the factory used to create surfaces.
+ void Morph(UniquePtr<SurfaceFactory> newFactory);
+
+protected:
+ // Returns false on error or inability to resize.
+ bool Swap(const gfx::IntSize& size);
+
+public:
+ bool PublishFrame(const gfx::IntSize& size);
+
+ bool Resize(const gfx::IntSize& size);
+
+protected:
+ bool Attach(SharedSurface* surf, const gfx::IntSize& size);
+
+ bool CreateDraw(const gfx::IntSize& size, UniquePtr<DrawBuffer>* out_buffer);
+ UniquePtr<ReadBuffer> CreateRead(SharedSurface* surf);
+
+public:
+ /* `fb` in these functions is the framebuffer the GLContext is hoping to
+ * bind. When this is 0, we intercept the call and bind our own
+ * framebuffers. As a client of these functions, just bind 0 when you want
+ * to draw to the default framebuffer/'screen'.
+ */
+ void BindFB(GLuint fb);
+ void BindDrawFB(GLuint fb);
+ void BindReadFB(GLuint fb);
+ GLuint GetFB() const;
+ GLuint GetDrawFB() const;
+ GLuint GetReadFB() const;
+
+ // Here `fb` is the actual framebuffer you want bound. Binding 0 will
+ // bind the (generally useless) default framebuffer.
+ void BindFB_Internal(GLuint fb);
+ void BindDrawFB_Internal(GLuint fb);
+ void BindReadFB_Internal(GLuint fb);
+
+ bool IsDrawFramebufferDefault() const;
+ bool IsReadFramebufferDefault() const;
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // SCREEN_BUFFER_H_