gfx/gl/GLScreenBuffer.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
     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/. */
     6 /* GLScreenBuffer is the abstraction for the "default framebuffer" used
     7  * by an offscreen GLContext. Since it's only for offscreen GLContext's,
     8  * it's only useful for things like WebGL, and is NOT used by the
     9  * compositor's GLContext. Remember that GLContext provides an abstraction
    10  * so that even if you want to draw to the 'screen', even if that's not
    11  * actually the screen, just draw to 0. This GLScreenBuffer class takes the
    12  * logic handling out of GLContext.
    13 */
    15 #ifndef SCREEN_BUFFER_H_
    16 #define SCREEN_BUFFER_H_
    18 #include "SurfaceTypes.h"
    19 #include "SurfaceStream.h"
    20 #include "GLContextTypes.h"
    21 #include "GLDefs.h"
    22 #include "mozilla/gfx/2D.h"
    23 #include "mozilla/gfx/Point.h"
    25 // Forwards:
    26 class gfxImageSurface;
    28 namespace mozilla {
    29     namespace gfx {
    30         class SurfaceStream;
    31         class SharedSurface;
    32     }
    33     namespace gl {
    34         class GLContext;
    35         class SharedSurface_GL;
    36         class SurfaceFactory_GL;
    37     }
    38 }
    40 namespace mozilla {
    41 namespace gl {
    43 class DrawBuffer
    44 {
    45 protected:
    46     typedef struct gfx::SurfaceCaps SurfaceCaps;
    48 public:
    49     // Infallible, may return null if unneeded.
    50     static DrawBuffer* Create(GLContext* const gl,
    51                               const SurfaceCaps& caps,
    52                               const GLFormats& formats,
    53                               const gfx::IntSize& size);
    55 protected:
    56     GLContext* const mGL;
    57     const gfx::IntSize mSize;
    58     const GLuint mFB;
    59     const GLuint mColorMSRB;
    60     const GLuint mDepthRB;
    61     const GLuint mStencilRB;
    63     DrawBuffer(GLContext* gl,
    64                const gfx::IntSize& size,
    65                GLuint fb,
    66                GLuint colorMSRB,
    67                GLuint depthRB,
    68                GLuint stencilRB)
    69         : mGL(gl)
    70         , mSize(size)
    71         , mFB(fb)
    72         , mColorMSRB(colorMSRB)
    73         , mDepthRB(depthRB)
    74         , mStencilRB(stencilRB)
    75     {}
    77 public:
    78     virtual ~DrawBuffer();
    80     const gfx::IntSize& Size() const {
    81         return mSize;
    82     }
    84     GLuint FB() const {
    85         return mFB;
    86     }
    87 };
    89 class ReadBuffer
    90 {
    91 protected:
    92     typedef struct gfx::SurfaceCaps SurfaceCaps;
    94 public:
    95     // Infallible, always non-null.
    96     static ReadBuffer* Create(GLContext* gl,
    97                               const SurfaceCaps& caps,
    98                               const GLFormats& formats,
    99                               SharedSurface_GL* surf);
   101 protected:
   102     GLContext* const mGL;
   104     const GLuint mFB;
   105     // mFB has the following attachments:
   106     const GLuint mDepthRB;
   107     const GLuint mStencilRB;
   108     // note no mColorRB here: this is provided by mSurf.
   109     SharedSurface_GL* mSurf; // Owned by GLScreenBuffer's SurfaceStream.
   111     ReadBuffer(GLContext* gl,
   112                GLuint fb,
   113                GLuint depthRB,
   114                GLuint stencilRB,
   115                SharedSurface_GL* surf)
   116         : mGL(gl)
   117         , mFB(fb)
   118         , mDepthRB(depthRB)
   119         , mStencilRB(stencilRB)
   120         , mSurf(surf)
   121     {}
   123 public:
   124     virtual ~ReadBuffer();
   126     // Cannot attach a surf of a different AttachType or Size than before.
   127     void Attach(SharedSurface_GL* surf);
   129     const gfx::IntSize& Size() const;
   131     GLuint FB() const {
   132         return mFB;
   133     }
   135     SharedSurface_GL* SharedSurf() const {
   136         return mSurf;
   137     }
   138 };
   141 class GLScreenBuffer
   142 {
   143 protected:
   144     typedef class gfx::SurfaceStream SurfaceStream;
   145     typedef class gfx::SharedSurface SharedSurface;
   146     typedef gfx::SurfaceStreamType SurfaceStreamType;
   147     typedef gfx::SharedSurfaceType SharedSurfaceType;
   148     typedef struct gfx::SurfaceCaps SurfaceCaps;
   150 public:
   151     // Infallible.
   152     static GLScreenBuffer* Create(GLContext* gl,
   153                                   const gfx::IntSize& size,
   154                                   const SurfaceCaps& caps);
   156 protected:
   157     GLContext* const mGL;         // Owns us.
   158     SurfaceCaps mCaps;
   159     SurfaceFactory_GL* mFactory;  // Owned by us.
   160     RefPtr<SurfaceStream> mStream;
   162     DrawBuffer* mDraw;            // Owned by us.
   163     ReadBuffer* mRead;            // Owned by us.
   165     bool mNeedsBlit;
   167     // Below are the parts that help us pretend to be framebuffer 0:
   168     GLuint mUserDrawFB;
   169     GLuint mUserReadFB;
   170     GLuint mInternalDrawFB;
   171     GLuint mInternalReadFB;
   173 #ifdef DEBUG
   174     bool mInInternalMode_DrawFB;
   175     bool mInInternalMode_ReadFB;
   176 #endif
   178     GLScreenBuffer(GLContext* gl,
   179                    const SurfaceCaps& caps,
   180                    SurfaceFactory_GL* factory,
   181                    SurfaceStream* stream)
   182         : mGL(gl)
   183         , mCaps(caps)
   184         , mFactory(factory)
   185         , mStream(stream)
   186         , mDraw(nullptr)
   187         , mRead(nullptr)
   188         , mNeedsBlit(true)
   189         , mUserDrawFB(0)
   190         , mUserReadFB(0)
   191         , mInternalDrawFB(0)
   192         , mInternalReadFB(0)
   193 #ifdef DEBUG
   194         , mInInternalMode_DrawFB(true)
   195         , mInInternalMode_ReadFB(true)
   196 #endif
   197     {}
   199 public:
   200     virtual ~GLScreenBuffer();
   202     SurfaceStream* Stream() const {
   203         return mStream;
   204     }
   206     SurfaceFactory_GL* Factory() const {
   207         return mFactory;
   208     }
   210     SharedSurface_GL* SharedSurf() const {
   211         MOZ_ASSERT(mRead);
   212         return mRead->SharedSurf();
   213     }
   215     bool PreserveBuffer() const {
   216         return mCaps.preserve;
   217     }
   219     const SurfaceCaps& Caps() const {
   220         return mCaps;
   221     }
   223     GLuint DrawFB() const {
   224         if (!mDraw)
   225             return ReadFB();
   227         return mDraw->FB();
   228     }
   230     GLuint ReadFB() const {
   231         return mRead->FB();
   232     }
   234     void DeletingFB(GLuint fb);
   236     const gfx::IntSize& Size() const {
   237         MOZ_ASSERT(mRead);
   238         MOZ_ASSERT(!mDraw || mDraw->Size() == mRead->Size());
   239         return mRead->Size();
   240     }
   242     void BindAsFramebuffer(GLContext* const gl, GLenum target) const;
   244     void RequireBlit();
   245     void AssureBlitted();
   246     void AfterDrawCall();
   247     void BeforeReadCall();
   249     /**
   250      * Attempts to read pixels from the current bound framebuffer, if
   251      * it is backed by a SharedSurface_GL.
   252      *
   253      * Returns true if the pixel data has been read back, false
   254      * otherwise.
   255      */
   256     bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
   257                     GLenum format, GLenum type, GLvoid *pixels);
   259     /* Morph swaps out our SurfaceStream mechanism and replaces it with
   260      * one best suited to our platform and compositor configuration.
   261      *
   262      * Must be called on the producing thread.
   263      * We haven't made any guarantee that rendering is actually
   264      * done when Morph is run, just that it can't run concurrently
   265      * with rendering. This means that we can't just drop the contents
   266      * of the buffer, since we may only be partially done rendering.
   267      *
   268      * Once you pass newFactory into Morph, newFactory will be owned by
   269      * GLScreenBuffer, so `forget` any references to it that still exist.
   270      */
   271     void Morph(SurfaceFactory_GL* newFactory, SurfaceStreamType streamType);
   273 protected:
   274     // Returns false on error or inability to resize.
   275     bool Swap(const gfx::IntSize& size);
   277 public:
   278     bool PublishFrame(const gfx::IntSize& size);
   280     bool Resize(const gfx::IntSize& size);
   282     void Readback(SharedSurface_GL* src, gfx::DataSourceSurface* dest);
   283     void DeprecatedReadback(SharedSurface_GL* src, gfxImageSurface* dest);
   285 protected:
   286     void Attach(SharedSurface* surface, const gfx::IntSize& size);
   288     DrawBuffer* CreateDraw(const gfx::IntSize& size);
   289     ReadBuffer* CreateRead(SharedSurface_GL* surf);
   291 public:
   292     /* `fb` in these functions is the framebuffer the GLContext is hoping to
   293      * bind. When this is 0, we intercept the call and bind our own
   294      * framebuffers. As a client of these functions, just bind 0 when you want
   295      * to draw to the default framebuffer/'screen'.
   296      */
   297     void BindFB(GLuint fb);
   298     void BindDrawFB(GLuint fb);
   299     void BindReadFB(GLuint fb);
   300     GLuint GetFB() const;
   301     GLuint GetDrawFB() const;
   302     GLuint GetReadFB() const;
   304     // Here `fb` is the actual framebuffer you want bound. Binding 0 will
   305     // bind the (generally useless) default framebuffer.
   306     void BindDrawFB_Internal(GLuint fb);
   307     void BindReadFB_Internal(GLuint fb);
   308 };
   310 }   // namespace gl
   311 }   // namespace mozilla
   313 #endif  // SCREEN_BUFFER_H_

mercurial