tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PixelLocalStorage.h (7251B)


      1 //
      2 // Copyright 2022 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // PixelLocalStorage.h: Defines the renderer-agnostic container classes
      8 // gl::PixelLocalStorage and gl::PixelLocalStoragePlane for
      9 // ANGLE_shader_pixel_local_storage.
     10 
     11 #ifndef LIBANGLE_PIXEL_LOCAL_STORAGE_H_
     12 #define LIBANGLE_PIXEL_LOCAL_STORAGE_H_
     13 
     14 #include "angle_gl.h"
     15 #include "libANGLE/ImageIndex.h"
     16 #include "libANGLE/angletypes.h"
     17 
     18 namespace gl
     19 {
     20 
     21 class Context;
     22 class Texture;
     23 
     24 // Holds the configuration of an ANGLE_shader_pixel_local_storage plane.
     25 //
     26 // Unlike normal framebuffer attachments, pixel local storage planes don't take effect until the
     27 // application calls glBeginPixelLocalStorageANGLE, and the manner in which they take effect is
     28 // highly dependent on the backend implementation. A PixelLocalStoragePlane is just a plain data
     29 // description what to set up later once PLS is enabled.
     30 class PixelLocalStoragePlane : angle::NonCopyable
     31 {
     32  public:
     33    ~PixelLocalStoragePlane();
     34 
     35    // Called when the context is lost or destroyed. Causes this class to clear its GL object
     36    // handles.
     37    void onContextObjectsLost();
     38 
     39    // Called when the owning framebuffer is being destroyed. Causes this class to release its
     40    // texture object reference.
     41    void onFramebufferDestroyed(const Context *);
     42 
     43    void deinitialize(Context *);
     44    void setMemoryless(Context *, GLenum internalformat);
     45    void setTextureBacked(Context *, Texture *, int level, int layer);
     46 
     47    bool isDeinitialized() const { return mInternalformat == GL_NONE; }
     48 
     49    // Returns true if the texture ID bound to this plane has been deleted.
     50    //
     51    // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage
     52    // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to
     53    // which it was bound is automatically converted to a memoryless plane of matching
     54    // internalformat.
     55    bool isTextureIDDeleted(const Context *) const;
     56 
     57    bool isMemoryless() const
     58    {
     59        // isMemoryless() should be false if the plane is deinitialized.
     60        ASSERT(!(isDeinitialized() && mMemoryless));
     61        return mMemoryless;
     62    }
     63 
     64    GLenum getInternalformat() const { return mInternalformat; }
     65 
     66    // Implements glGetIntegeri_v() for GL_PIXEL_LOCAL_FORMAT_ANGLE,
     67    // GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, and
     68    // GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE
     69    GLint getIntegeri(const Context *, GLenum target, GLuint index) const;
     70 
     71    // If this plane is texture backed, stores the bound texture image's {width, height, 0} to
     72    // Extents and returns true. Otherwise returns false, meaning the plane is either deinitialized
     73    // or memoryless.
     74    bool getTextureImageExtents(const Context *, Extents *extents) const;
     75 
     76    // Attaches this plane to the specified color attachment point on the current draw framebuffer.
     77    void attachToDrawFramebuffer(Context *, Extents plsExtents, GLenum colorAttachment);
     78 
     79    // Clears the draw buffer at 0-based index 'drawbuffer' on the current framebuffer. Reads the
     80    // clear value from 'data' if 'loadop' is GL_CLEAR_ANGLE, otherwise clears to zero.
     81    //
     82    // 'data' is interpereted as either 4 GLfloats, 4 GLints, or 4 GLuints, depending on
     83    // mInternalFormat.
     84    //
     85    // The context must internally disable the scissor test before calling this method, since the
     86    // intention is to clear the entire surface.
     87    void performLoadOperationClear(Context *, GLint drawbuffer, GLenum loadop, const void *data);
     88 
     89    // Binds this PLS plane to a texture image unit for image load/store shader operations.
     90    void bindToImage(Context *, Extents plsExtents, GLuint unit, bool needsR32Packing);
     91 
     92  private:
     93    // Ensures we have an internal backing texture for memoryless planes. In GL, we need a backing
     94    // texture even if the plane is memoryless; glInvalidateFramebuffer() will ideally prevent the
     95    // driver from writing out data where possible.
     96    void ensureBackingIfMemoryless(Context *, Extents plsSize);
     97 
     98    GLenum mInternalformat = GL_NONE;  // GL_NONE if this plane is in a deinitialized state.
     99    bool mMemoryless       = false;
    100    TextureID mMemorylessTextureID{};  // We own memoryless backing textures and must delete them.
    101    ImageIndex mTextureImageIndex;
    102    Texture *mTextureRef = nullptr;
    103 };
    104 
    105 // Manages a collection of PixelLocalStoragePlanes and applies them to ANGLE's GL state.
    106 //
    107 // The main magic of ANGLE_shader_pixel_local_storage happens inside shaders, so we just emulate the
    108 // client API on top of ANGLE's OpenGL ES API for simplicity.
    109 class PixelLocalStorage
    110 {
    111  public:
    112    static std::unique_ptr<PixelLocalStorage> Make(const Context *);
    113 
    114    PixelLocalStorage();
    115    virtual ~PixelLocalStorage();
    116 
    117    // Called when the owning framebuffer is being destroyed.
    118    void onFramebufferDestroyed(const Context *);
    119 
    120    // Deletes any GL objects that have been allocated for pixel local storage. These can't be
    121    // cleaned up in the destructor because they require a non-const Context object.
    122    void deleteContextObjects(Context *);
    123 
    124    const PixelLocalStoragePlane &getPlane(GLint plane) const
    125    {
    126        ASSERT(0 <= plane && plane < IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES);
    127        return mPlanes[plane];
    128    }
    129 
    130    PixelLocalStoragePlane &getPlane(GLint plane)
    131    {
    132        ASSERT(0 <= plane && plane < IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES);
    133        return mPlanes[plane];
    134    }
    135 
    136    // ANGLE_shader_pixel_local_storage API.
    137    void deinitialize(Context *context, GLint plane) { mPlanes[plane].deinitialize(context); }
    138    void setMemoryless(Context *context, GLint plane, GLenum internalformat)
    139    {
    140        mPlanes[plane].setMemoryless(context, internalformat);
    141    }
    142    void setTextureBacked(Context *context, GLint plane, Texture *tex, int level, int layer)
    143    {
    144        mPlanes[plane].setTextureBacked(context, tex, level, layer);
    145    }
    146    void begin(Context *, GLsizei n, const GLenum loadops[], const void *cleardata);
    147    void end(Context *);
    148    void barrier(Context *);
    149 
    150  protected:
    151    // Called when the context is lost or destroyed. Causes the subclass to clear its GL object
    152    // handles.
    153    virtual void onContextObjectsLost() = 0;
    154 
    155    // Called when the framebuffer is being destroyed. Causes the subclass to delete its frontend GL
    156    // object handles.
    157    virtual void onDeleteContextObjects(Context *) = 0;
    158 
    159    // ANGLE_shader_pixel_local_storage API.
    160    virtual void onBegin(Context *,
    161                         GLsizei n,
    162                         const GLenum loadops[],
    163                         const char *cleardata,
    164                         Extents plsSize)                     = 0;
    165    virtual void onEnd(Context *, GLsizei numActivePLSPlanes) = 0;
    166    virtual void onBarrier(Context *)                         = 0;
    167 
    168  private:
    169    std::array<PixelLocalStoragePlane, IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES> mPlanes;
    170 
    171    // "n" from the last call to begin(), or 0 if pixel local storage is not active.
    172    GLsizei mNumActivePLSPlanes = 0;
    173 };
    174 
    175 }  // namespace gl
    176 
    177 #endif  // LIBANGLE_PIXEL_LOCAL_STORAGE_H_