tor-browser

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

Framebuffer.h (21968B)


      1 //
      2 // Copyright 2002 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 // Framebuffer.h: Defines the gl::Framebuffer class. Implements GL framebuffer
      8 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
      9 
     10 #ifndef LIBANGLE_FRAMEBUFFER_H_
     11 #define LIBANGLE_FRAMEBUFFER_H_
     12 
     13 #include <vector>
     14 
     15 #include "common/FixedVector.h"
     16 #include "common/Optional.h"
     17 #include "common/angleutils.h"
     18 #include "libANGLE/Constants.h"
     19 #include "libANGLE/Debug.h"
     20 #include "libANGLE/Error.h"
     21 #include "libANGLE/FramebufferAttachment.h"
     22 #include "libANGLE/Observer.h"
     23 #include "libANGLE/RefCountObject.h"
     24 #include "libANGLE/State.h"
     25 #include "libANGLE/angletypes.h"
     26 
     27 namespace rx
     28 {
     29 class GLImplFactory;
     30 class FramebufferImpl;
     31 class RenderbufferImpl;
     32 class SurfaceImpl;
     33 }  // namespace rx
     34 
     35 namespace egl
     36 {
     37 class Display;
     38 class Surface;
     39 }  // namespace egl
     40 
     41 namespace gl
     42 {
     43 struct Caps;
     44 class Context;
     45 struct Extensions;
     46 class Framebuffer;
     47 class ImageIndex;
     48 class PixelLocalStorage;
     49 class Renderbuffer;
     50 class TextureCapsMap;
     51 
     52 struct FramebufferStatus
     53 {
     54    bool isComplete() const;
     55 
     56    static FramebufferStatus Complete();
     57    static FramebufferStatus Incomplete(GLenum status, const char *reason);
     58 
     59    GLenum status      = GL_FRAMEBUFFER_COMPLETE;
     60    const char *reason = nullptr;
     61 };
     62 
     63 class FramebufferState final : angle::NonCopyable
     64 {
     65  public:
     66    explicit FramebufferState(rx::Serial serial);
     67    FramebufferState(const Caps &caps, FramebufferID id, rx::Serial serial);
     68    ~FramebufferState();
     69 
     70    const std::string &getLabel() const;
     71    uint32_t getReadIndex() const;
     72 
     73    const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const;
     74    const FramebufferAttachment *getReadAttachment() const;
     75    const FramebufferAttachment *getFirstNonNullAttachment() const;
     76    const FramebufferAttachment *getFirstColorAttachment() const;
     77    const FramebufferAttachment *getDepthOrStencilAttachment() const;
     78    const FramebufferAttachment *getStencilOrDepthStencilAttachment() const;
     79    const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const;
     80    const FramebufferAttachment *getDepthAttachment() const;
     81    const FramebufferAttachment *getStencilAttachment() const;
     82    const FramebufferAttachment *getDepthStencilAttachment() const;
     83    const FramebufferAttachment *getReadPixelsAttachment(GLenum readFormat) const;
     84 
     85    const DrawBuffersVector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; }
     86    DrawBufferMask getEnabledDrawBuffers() const { return mEnabledDrawBuffers; }
     87    GLenum getReadBufferState() const { return mReadBufferState; }
     88 
     89    const DrawBuffersVector<FramebufferAttachment> &getColorAttachments() const
     90    {
     91        return mColorAttachments;
     92    }
     93    const DrawBufferMask getColorAttachmentsMask() const { return mColorAttachmentsMask; }
     94 
     95    const Extents getAttachmentExtentsIntersection() const;
     96    bool attachmentsHaveSameDimensions() const;
     97    bool hasSeparateDepthAndStencilAttachments() const;
     98    bool colorAttachmentsAreUniqueImages() const;
     99    Box getDimensions() const;
    100    Extents getExtents() const;
    101 
    102    const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const;
    103    size_t getDrawBufferCount() const;
    104 
    105    GLint getDefaultWidth() const { return mDefaultWidth; }
    106    GLint getDefaultHeight() const { return mDefaultHeight; }
    107    GLint getDefaultSamples() const { return mDefaultSamples; }
    108    bool getDefaultFixedSampleLocations() const { return mDefaultFixedSampleLocations; }
    109    GLint getDefaultLayers() const { return mDefaultLayers; }
    110    bool getFlipY() const { return mFlipY; }
    111 
    112    bool hasDepth() const;
    113    bool hasStencil() const;
    114 
    115    bool hasExternalTextureAttachment() const;
    116    bool hasYUVAttachment() const;
    117 
    118    bool isMultiview() const;
    119 
    120    ANGLE_INLINE GLsizei getNumViews() const
    121    {
    122        const FramebufferAttachment *attachment = getFirstNonNullAttachment();
    123        if (attachment == nullptr)
    124        {
    125            return FramebufferAttachment::kDefaultNumViews;
    126        }
    127        return attachment->getNumViews();
    128    }
    129 
    130    GLint getBaseViewIndex() const;
    131 
    132    SrgbWriteControlMode getWriteControlMode() const { return mSrgbWriteControlMode; }
    133 
    134    FramebufferID id() const { return mId; }
    135 
    136    bool isDefault() const;
    137 
    138    const Offset &getSurfaceTextureOffset() const { return mSurfaceTextureOffset; }
    139 
    140    rx::Serial getFramebufferSerial() const { return mFramebufferSerial; }
    141 
    142    bool isBoundAsDrawFramebuffer(const Context *context) const;
    143 
    144  private:
    145    const FramebufferAttachment *getWebGLDepthStencilAttachment() const;
    146    const FramebufferAttachment *getWebGLDepthAttachment() const;
    147    const FramebufferAttachment *getWebGLStencilAttachment() const;
    148 
    149    friend class Framebuffer;
    150 
    151    // The Framebuffer ID is unique to a Context.
    152    // The Framebuffer Serial is unique to a Share Group.
    153    FramebufferID mId;
    154    rx::Serial mFramebufferSerial;
    155    std::string mLabel;
    156 
    157    DrawBuffersVector<FramebufferAttachment> mColorAttachments;
    158    FramebufferAttachment mDepthAttachment;
    159    FramebufferAttachment mStencilAttachment;
    160 
    161    // Tracks all the color buffers attached to this FramebufferDesc
    162    DrawBufferMask mColorAttachmentsMask;
    163 
    164    DrawBuffersVector<GLenum> mDrawBufferStates;
    165    GLenum mReadBufferState;
    166    DrawBufferMask mEnabledDrawBuffers;
    167    ComponentTypeMask mDrawBufferTypeMask;
    168 
    169    GLint mDefaultWidth;
    170    GLint mDefaultHeight;
    171    GLint mDefaultSamples;
    172    bool mDefaultFixedSampleLocations;
    173    GLint mDefaultLayers;
    174    bool mFlipY;
    175 
    176    // It's necessary to store all this extra state so we can restore attachments
    177    // when DEPTH_STENCIL/DEPTH/STENCIL is unbound in WebGL 1.
    178    FramebufferAttachment mWebGLDepthStencilAttachment;
    179    FramebufferAttachment mWebGLDepthAttachment;
    180    FramebufferAttachment mWebGLStencilAttachment;
    181    bool mWebGLDepthStencilConsistent;
    182 
    183    // Tracks if we need to initialize the resources for each attachment.
    184    angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS + 2> mResourceNeedsInit;
    185 
    186    bool mDefaultFramebufferReadAttachmentInitialized;
    187    FramebufferAttachment mDefaultFramebufferReadAttachment;
    188 
    189    // EXT_sRGB_write_control
    190    SrgbWriteControlMode mSrgbWriteControlMode;
    191 
    192    Offset mSurfaceTextureOffset;
    193 };
    194 
    195 class Framebuffer final : public angle::ObserverInterface,
    196                          public LabeledObject,
    197                          public angle::Subject
    198 {
    199  public:
    200    // Constructor to build default framebuffers.
    201    Framebuffer(const Context *context, rx::GLImplFactory *factory);
    202    // Constructor to build application-defined framebuffers
    203    Framebuffer(const Context *context, rx::GLImplFactory *factory, FramebufferID id);
    204 
    205    ~Framebuffer() override;
    206    void onDestroy(const Context *context);
    207 
    208    egl::Error setSurfaces(const Context *context,
    209                           egl::Surface *surface,
    210                           egl::Surface *readSurface);
    211    void setReadSurface(const Context *context, egl::Surface *readSurface);
    212    egl::Error unsetSurfaces(const Context *context);
    213    angle::Result setLabel(const Context *context, const std::string &label) override;
    214    const std::string &getLabel() const override;
    215 
    216    rx::FramebufferImpl *getImplementation() const { return mImpl; }
    217 
    218    FramebufferID id() const { return mState.mId; }
    219 
    220    void setAttachment(const Context *context,
    221                       GLenum type,
    222                       GLenum binding,
    223                       const ImageIndex &textureIndex,
    224                       FramebufferAttachmentObject *resource);
    225    void setAttachmentMultisample(const Context *context,
    226                                  GLenum type,
    227                                  GLenum binding,
    228                                  const ImageIndex &textureIndex,
    229                                  FramebufferAttachmentObject *resource,
    230                                  GLsizei samples);
    231    void setAttachmentMultiview(const Context *context,
    232                                GLenum type,
    233                                GLenum binding,
    234                                const ImageIndex &textureIndex,
    235                                FramebufferAttachmentObject *resource,
    236                                GLsizei numViews,
    237                                GLint baseViewIndex);
    238    void resetAttachment(const Context *context, GLenum binding);
    239 
    240    bool detachTexture(const Context *context, TextureID texture);
    241    bool detachRenderbuffer(const Context *context, RenderbufferID renderbuffer);
    242 
    243    const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const;
    244    const FramebufferAttachment *getDepthAttachment() const;
    245    const FramebufferAttachment *getStencilAttachment() const;
    246    const FramebufferAttachment *getDepthStencilAttachment() const;
    247    const FramebufferAttachment *getDepthOrStencilAttachment() const;
    248    const FramebufferAttachment *getStencilOrDepthStencilAttachment() const;
    249    const FramebufferAttachment *getReadColorAttachment() const;
    250    GLenum getReadColorAttachmentType() const;
    251    const FramebufferAttachment *getFirstColorAttachment() const;
    252    const FramebufferAttachment *getFirstNonNullAttachment() const;
    253 
    254    const DrawBuffersVector<FramebufferAttachment> &getColorAttachments() const
    255    {
    256        return mState.mColorAttachments;
    257    }
    258 
    259    const FramebufferState &getState() const { return mState; }
    260 
    261    const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const;
    262    bool isMultiview() const;
    263    bool readDisallowedByMultiview() const;
    264    GLsizei getNumViews() const;
    265    GLint getBaseViewIndex() const;
    266    Extents getExtents() const;
    267 
    268    size_t getDrawbufferStateCount() const;
    269    GLenum getDrawBufferState(size_t drawBuffer) const;
    270    const DrawBuffersVector<GLenum> &getDrawBufferStates() const;
    271    void setDrawBuffers(size_t count, const GLenum *buffers);
    272    const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const;
    273    ComponentType getDrawbufferWriteType(size_t drawBuffer) const;
    274    ComponentTypeMask getDrawBufferTypeMask() const;
    275    DrawBufferMask getDrawBufferMask() const;
    276    bool hasEnabledDrawBuffer() const;
    277 
    278    GLenum getReadBufferState() const;
    279    void setReadBuffer(GLenum buffer);
    280 
    281    size_t getNumColorAttachments() const;
    282    bool hasDepth() const;
    283    bool hasStencil() const;
    284 
    285    bool hasExternalTextureAttachment() const;
    286    bool hasYUVAttachment() const;
    287 
    288    bool usingExtendedDrawBuffers() const;
    289 
    290    // This method calls checkStatus.
    291    int getSamples(const Context *context) const;
    292    int getReadBufferResourceSamples(const Context *context) const;
    293 
    294    angle::Result getSamplePosition(const Context *context, size_t index, GLfloat *xy) const;
    295 
    296    GLint getDefaultWidth() const;
    297    GLint getDefaultHeight() const;
    298    GLint getDefaultSamples() const;
    299    bool getDefaultFixedSampleLocations() const;
    300    GLint getDefaultLayers() const;
    301    bool getFlipY() const;
    302    void setDefaultWidth(const Context *context, GLint defaultWidth);
    303    void setDefaultHeight(const Context *context, GLint defaultHeight);
    304    void setDefaultSamples(const Context *context, GLint defaultSamples);
    305    void setDefaultFixedSampleLocations(const Context *context, bool defaultFixedSampleLocations);
    306    void setDefaultLayers(GLint defaultLayers);
    307    void setFlipY(bool flipY);
    308 
    309    void invalidateCompletenessCache();
    310    ANGLE_INLINE bool cachedStatusValid() { return mCachedStatus.valid(); }
    311 
    312    ANGLE_INLINE const FramebufferStatus &checkStatus(const Context *context) const
    313    {
    314        // The default framebuffer is always complete except when it is surfaceless in which
    315        // case it is always unsupported.
    316        ASSERT(!isDefault() || mCachedStatus.valid());
    317        if (isDefault() || (!hasAnyDirtyBit() && mCachedStatus.valid()))
    318        {
    319            return mCachedStatus.value();
    320        }
    321 
    322        return checkStatusImpl(context);
    323    }
    324 
    325    // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE.
    326    ANGLE_INLINE bool isComplete(const Context *context) const
    327    {
    328        return checkStatus(context).isComplete();
    329    }
    330 
    331    bool hasValidDepthStencil() const;
    332 
    333    // Returns the offset into the texture backing the default framebuffer's surface if any. Returns
    334    // zero offset otherwise.  The renderer will apply the offset to scissor and viewport rects used
    335    // for draws, clears, and blits.
    336    const Offset &getSurfaceTextureOffset() const;
    337 
    338    angle::Result discard(const Context *context, size_t count, const GLenum *attachments);
    339    angle::Result invalidate(const Context *context, size_t count, const GLenum *attachments);
    340    angle::Result invalidateSub(const Context *context,
    341                                size_t count,
    342                                const GLenum *attachments,
    343                                const Rectangle &area);
    344 
    345    angle::Result clear(const Context *context, GLbitfield mask);
    346    angle::Result clearBufferfv(const Context *context,
    347                                GLenum buffer,
    348                                GLint drawbuffer,
    349                                const GLfloat *values);
    350    angle::Result clearBufferuiv(const Context *context,
    351                                 GLenum buffer,
    352                                 GLint drawbuffer,
    353                                 const GLuint *values);
    354    angle::Result clearBufferiv(const Context *context,
    355                                GLenum buffer,
    356                                GLint drawbuffer,
    357                                const GLint *values);
    358    angle::Result clearBufferfi(const Context *context,
    359                                GLenum buffer,
    360                                GLint drawbuffer,
    361                                GLfloat depth,
    362                                GLint stencil);
    363 
    364    GLenum getImplementationColorReadFormat(const Context *context);
    365    GLenum getImplementationColorReadType(const Context *context);
    366 
    367    angle::Result readPixels(const Context *context,
    368                             const Rectangle &area,
    369                             GLenum format,
    370                             GLenum type,
    371                             const PixelPackState &pack,
    372                             Buffer *packBuffer,
    373                             void *pixels);
    374 
    375    angle::Result blit(const Context *context,
    376                       const Rectangle &sourceArea,
    377                       const Rectangle &destArea,
    378                       GLbitfield mask,
    379                       GLenum filter);
    380    bool isDefault() const { return mState.isDefault(); }
    381 
    382    enum DirtyBitType : size_t
    383    {
    384        DIRTY_BIT_COLOR_ATTACHMENT_0,
    385        DIRTY_BIT_COLOR_ATTACHMENT_MAX =
    386            DIRTY_BIT_COLOR_ATTACHMENT_0 + IMPLEMENTATION_MAX_DRAW_BUFFERS,
    387        DIRTY_BIT_DEPTH_ATTACHMENT = DIRTY_BIT_COLOR_ATTACHMENT_MAX,
    388        DIRTY_BIT_STENCIL_ATTACHMENT,
    389        DIRTY_BIT_COLOR_BUFFER_CONTENTS_0,
    390        DIRTY_BIT_COLOR_BUFFER_CONTENTS_MAX =
    391            DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 + IMPLEMENTATION_MAX_DRAW_BUFFERS,
    392        DIRTY_BIT_DEPTH_BUFFER_CONTENTS = DIRTY_BIT_COLOR_BUFFER_CONTENTS_MAX,
    393        DIRTY_BIT_STENCIL_BUFFER_CONTENTS,
    394        DIRTY_BIT_DRAW_BUFFERS,
    395        DIRTY_BIT_READ_BUFFER,
    396        DIRTY_BIT_DEFAULT_WIDTH,
    397        DIRTY_BIT_DEFAULT_HEIGHT,
    398        DIRTY_BIT_DEFAULT_SAMPLES,
    399        DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS,
    400        DIRTY_BIT_DEFAULT_LAYERS,
    401        DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE,
    402        DIRTY_BIT_FLIP_Y,
    403        DIRTY_BIT_UNKNOWN,
    404        DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN
    405    };
    406 
    407    using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
    408    bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
    409 
    410    DrawBufferMask getActiveFloat32ColorAttachmentDrawBufferMask() const
    411    {
    412        return mFloat32ColorAttachmentBits & getDrawBufferMask();
    413    }
    414 
    415    bool hasResourceThatNeedsInit() const { return mState.mResourceNeedsInit.any(); }
    416 
    417    angle::Result syncState(const Context *context,
    418                            GLenum framebufferBinding,
    419                            Command command) const;
    420 
    421    void setWriteControlMode(SrgbWriteControlMode srgbWriteControlMode);
    422 
    423    // Observer implementation
    424    void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
    425 
    426    bool formsRenderingFeedbackLoopWith(const Context *context) const;
    427    bool formsCopyingFeedbackLoopWith(TextureID copyTextureID,
    428                                      GLint copyTextureLevel,
    429                                      GLint copyTextureLayer) const;
    430 
    431    angle::Result ensureClearAttachmentsInitialized(const Context *context, GLbitfield mask);
    432    angle::Result ensureClearBufferAttachmentsInitialized(const Context *context,
    433                                                          GLenum buffer,
    434                                                          GLint drawbuffer);
    435    angle::Result ensureDrawAttachmentsInitialized(const Context *context);
    436 
    437    // Conservatively initializes both read color and depth. Blit can access the depth buffer.
    438    angle::Result ensureReadAttachmentsInitialized(const Context *context);
    439    Box getDimensions() const;
    440 
    441    // ANGLE_shader_pixel_local_storage.
    442    // Lazily creates a PixelLocalStorage object for this Framebuffer.
    443    PixelLocalStorage &getPixelLocalStorage(const Context *);
    444    // Returns nullptr if the pixel local storage object has not been created yet.
    445    const PixelLocalStorage *peekPixelLocalStorage() const { return mPixelLocalStorage.get(); }
    446    // Detaches the the pixel local storage object so the Context can call deleteContextObjects().
    447    std::unique_ptr<PixelLocalStorage> detachPixelLocalStorage();
    448 
    449    static const FramebufferID kDefaultDrawFramebufferHandle;
    450 
    451  private:
    452    bool detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId);
    453    bool detachMatchingAttachment(const Context *context,
    454                                  FramebufferAttachment *attachment,
    455                                  GLenum matchType,
    456                                  GLuint matchId);
    457    FramebufferStatus checkStatusWithGLFrontEnd(const Context *context) const;
    458    const FramebufferStatus &checkStatusImpl(const Context *context) const;
    459    void setAttachment(const Context *context,
    460                       GLenum type,
    461                       GLenum binding,
    462                       const ImageIndex &textureIndex,
    463                       FramebufferAttachmentObject *resource,
    464                       GLsizei numViews,
    465                       GLuint baseViewIndex,
    466                       bool isMultiview,
    467                       GLsizei samplesIn);
    468    void commitWebGL1DepthStencilIfConsistent(const Context *context,
    469                                              GLsizei numViews,
    470                                              GLuint baseViewIndex,
    471                                              bool isMultiview,
    472                                              GLsizei samples);
    473    void setAttachmentImpl(const Context *context,
    474                           GLenum type,
    475                           GLenum binding,
    476                           const ImageIndex &textureIndex,
    477                           FramebufferAttachmentObject *resource,
    478                           GLsizei numViews,
    479                           GLuint baseViewIndex,
    480                           bool isMultiview,
    481                           GLsizei samples);
    482    void updateAttachment(const Context *context,
    483                          FramebufferAttachment *attachment,
    484                          size_t dirtyBit,
    485                          angle::ObserverBinding *onDirtyBinding,
    486                          GLenum type,
    487                          GLenum binding,
    488                          const ImageIndex &textureIndex,
    489                          FramebufferAttachmentObject *resource,
    490                          GLsizei numViews,
    491                          GLuint baseViewIndex,
    492                          bool isMultiview,
    493                          GLsizei samples);
    494 
    495    void markDrawAttachmentsInitialized(bool color, bool depth, bool stencil);
    496    void markBufferInitialized(GLenum bufferType, GLint bufferIndex);
    497    angle::Result ensureBufferInitialized(const Context *context,
    498                                          GLenum bufferType,
    499                                          GLint bufferIndex);
    500 
    501    // Checks that we have a partially masked clear:
    502    // * some color channels are masked out
    503    // * some stencil values are masked out
    504    // * scissor test partially overlaps the framebuffer
    505    bool partialClearNeedsInit(const Context *context, bool color, bool depth, bool stencil);
    506    bool partialBufferClearNeedsInit(const Context *context, GLenum bufferType);
    507 
    508    FramebufferAttachment *getAttachmentFromSubjectIndex(angle::SubjectIndex index);
    509 
    510    ANGLE_INLINE void updateFloat32ColorAttachmentBits(size_t index, const InternalFormat *format)
    511    {
    512        mFloat32ColorAttachmentBits.set(index, format->type == GL_FLOAT);
    513    }
    514 
    515    FramebufferState mState;
    516    rx::FramebufferImpl *mImpl;
    517 
    518    mutable Optional<FramebufferStatus> mCachedStatus;
    519    DrawBuffersVector<angle::ObserverBinding> mDirtyColorAttachmentBindings;
    520    angle::ObserverBinding mDirtyDepthAttachmentBinding;
    521    angle::ObserverBinding mDirtyStencilAttachmentBinding;
    522 
    523    mutable DirtyBits mDirtyBits;
    524    DrawBufferMask mFloat32ColorAttachmentBits;
    525 
    526    // The dirty bits guard is checked when we get a dependent state change message. We verify that
    527    // we don't set a dirty bit that isn't already set, when inside the dirty bits syncState.
    528    mutable Optional<DirtyBits> mDirtyBitsGuard;
    529 
    530    // ANGLE_shader_pixel_local_storage
    531    std::unique_ptr<PixelLocalStorage> mPixelLocalStorage;
    532 };
    533 
    534 using UniqueFramebufferPointer = angle::UniqueObjectPointer<Framebuffer, Context>;
    535 
    536 }  // namespace gl
    537 
    538 #endif  // LIBANGLE_FRAMEBUFFER_H_