tor-browser

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

WebGLFramebuffer.h (7787B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      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/. */
      5 
      6 #ifndef WEBGL_FRAMEBUFFER_H_
      7 #define WEBGL_FRAMEBUFFER_H_
      8 
      9 #include <bitset>
     10 #include <vector>
     11 
     12 #include "GLScreenBuffer.h"
     13 #include "WebGLObjectModel.h"
     14 #include "WebGLStrongTypes.h"
     15 #include "WebGLTexture.h"
     16 #include "WebGLTypes.h"
     17 #include "mozilla/WeakPtr.h"
     18 
     19 namespace mozilla {
     20 
     21 class WebGLFramebuffer;
     22 class WebGLRenderbuffer;
     23 class WebGLTexture;
     24 
     25 template <typename T>
     26 class PlacementArray;
     27 
     28 namespace gl {
     29 class GLContext;
     30 class MozFramebuffer;
     31 }  // namespace gl
     32 
     33 namespace webgl {
     34 struct FbAttachInfo final {
     35  WebGLRenderbuffer* rb = nullptr;
     36  WebGLTexture* tex = nullptr;
     37  uint32_t mipLevel = 0;
     38  uint32_t zLayer = 0;
     39  uint32_t zLayerCount = 1;
     40  bool isMultiview = false;
     41 };
     42 }  // namespace webgl
     43 
     44 class WebGLFBAttachPoint final {
     45  friend class WebGLFramebuffer;
     46 
     47 public:
     48  const GLenum mAttachmentPoint = 0;
     49  const bool mDeferAttachment = false;
     50 
     51 private:
     52  RefPtr<WebGLTexture> mTexturePtr;
     53  RefPtr<WebGLRenderbuffer> mRenderbufferPtr;
     54  uint32_t mTexImageLayer = 0;
     55  uint8_t mTexImageZLayerCount = 1;
     56  uint8_t mTexImageLevel = 0;
     57  bool mIsMultiview = false;
     58 
     59  ////
     60 
     61  WebGLFBAttachPoint();
     62  explicit WebGLFBAttachPoint(WebGLFBAttachPoint&);  // Make this private.
     63  WebGLFBAttachPoint(const WebGLContext* webgl, GLenum attachmentPoint);
     64 
     65 public:
     66  ~WebGLFBAttachPoint();
     67 
     68  ////
     69 
     70  bool HasAttachment() const {
     71    return bool(mTexturePtr) || bool(mRenderbufferPtr);
     72  }
     73 
     74  void Clear();
     75 
     76  void Set(gl::GLContext* gl, const webgl::FbAttachInfo&);
     77 
     78  WebGLTexture* Texture() const { return mTexturePtr; }
     79  WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; }
     80 
     81  Maybe<size_t> ColorAttachmentId() const {
     82    const size_t id = mAttachmentPoint - LOCAL_GL_COLOR_ATTACHMENT0;
     83    if (id >= webgl::kMaxDrawBuffers) return {};
     84    return Some(id);
     85  }
     86 
     87  auto Layer() const { return mTexImageLayer; }
     88  auto ZLayerCount() const { return mTexImageZLayerCount; }
     89  auto MipLevel() const { return mTexImageLevel; }
     90  const auto& IsMultiview() const { return mIsMultiview; }
     91 
     92  void AttachmentName(nsCString* out) const;
     93 
     94  const webgl::ImageInfo* GetImageInfo() const;
     95 
     96  bool IsComplete(WebGLContext* webgl, nsCString* const out_info) const;
     97 
     98  void DoAttachment(gl::GLContext* gl) const;
     99 
    100  Maybe<double> GetParameter(WebGLContext* webgl, GLenum attachment,
    101                             GLenum pname) const;
    102 
    103  bool IsEquivalentForFeedback(const WebGLFBAttachPoint& other) const {
    104    if (!HasAttachment() || !other.HasAttachment()) return false;
    105 
    106 #define _(X) (X == other.X)
    107    return (_(mRenderbufferPtr) && _(mTexturePtr) && _(mTexImageLevel) &&
    108            _(mTexImageLayer) && _(mTexImageZLayerCount));
    109 #undef _
    110  }
    111 
    112  ////
    113 
    114  struct Ordered {
    115    const WebGLFBAttachPoint& mRef;
    116 
    117    explicit Ordered(const WebGLFBAttachPoint& ref) : mRef(ref) {}
    118 
    119    bool operator<(const Ordered& other) const {
    120      MOZ_ASSERT(mRef.HasAttachment() && other.mRef.HasAttachment());
    121 
    122 #define ORDER_BY(X) \
    123  if (X != other.X) return X < other.X;
    124 
    125      ORDER_BY(mRef.mRenderbufferPtr)
    126      ORDER_BY(mRef.mTexturePtr)
    127      ORDER_BY(mRef.mTexImageLevel)
    128      ORDER_BY(mRef.mTexImageLayer)
    129      ORDER_BY(mRef.mTexImageZLayerCount)
    130 
    131 #undef ORDER_BY
    132      return false;
    133    }
    134  };
    135 };
    136 
    137 class WebGLFramebuffer final : public WebGLContextBoundObject,
    138                               public SupportsWeakPtr,
    139                               public CacheInvalidator {
    140 public:
    141  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLFramebuffer, override)
    142 
    143  const GLuint mGLName;
    144  bool mHasBeenBound = false;
    145  const UniquePtr<gl::MozFramebuffer> mOpaque;
    146  bool mInOpaqueRAF = false;
    147  // Swap chain that may be used to present this framebuffer, for opaque
    148  // framebuffers or other use cases. (e.g. DrawTargetWebgl)
    149  gl::SwapChain mSwapChain;
    150 
    151 private:
    152  mutable uint64_t mNumFBStatusInvals = 0;
    153 
    154  ////
    155 
    156 protected:
    157  WebGLFBAttachPoint mDepthAttachment;
    158  WebGLFBAttachPoint mStencilAttachment;
    159  WebGLFBAttachPoint mDepthStencilAttachment;
    160 
    161  std::array<WebGLFBAttachPoint, webgl::kMaxDrawBuffers> mColorAttachments = {};
    162  std::bitset<webgl::kMaxDrawBuffers> mDrawBufferEnabled = {1};
    163  ////
    164 
    165  std::vector<WebGLFBAttachPoint*> mAttachments;  // Non-null.
    166 
    167  std::vector<const WebGLFBAttachPoint*> mColorDrawBuffers;  // Non-null
    168  const WebGLFBAttachPoint* mColorReadBuffer;                // Null if NONE
    169 
    170  ////
    171 
    172  struct CompletenessInfo final {
    173    const WebGLFramebuffer* fb = nullptr;
    174 
    175    uint32_t width = 0;
    176    uint32_t height = 0;
    177    std::bitset<webgl::kMaxDrawBuffers> hasAttachment = 0;
    178    std::bitset<webgl::kMaxDrawBuffers> isAttachmentF32 = 0;
    179    uint8_t zLayerCount = 1;
    180    bool isMultiview = false;
    181 
    182    // IsFeedback
    183    std::vector<const WebGLFBAttachPoint*> texAttachments;  // Non-null
    184 
    185    ~CompletenessInfo();
    186  };
    187  friend struct CompletenessInfo;
    188 
    189  mutable CacheMaybe<const CompletenessInfo> mCompletenessInfo;
    190 
    191  ////
    192 
    193 public:
    194  WebGLFramebuffer(WebGLContext* webgl, GLuint fbo);
    195  WebGLFramebuffer(WebGLContext* webgl, UniquePtr<gl::MozFramebuffer> fbo);
    196  ~WebGLFramebuffer() override;
    197 
    198  ////
    199 
    200  bool HasDuplicateAttachments() const;
    201  bool HasDefinedAttachments() const;
    202  bool HasIncompleteAttachments(nsCString* const out_info) const;
    203  bool AllImageRectsMatch() const;
    204  bool AllImageSamplesMatch() const;
    205  FBStatus PrecheckFramebufferStatus(nsCString* const out_info) const;
    206 
    207 protected:
    208  Maybe<WebGLFBAttachPoint*> GetAttachPoint(GLenum attachment);  // Fallible
    209  Maybe<WebGLFBAttachPoint*> GetColorAttachPoint(
    210      GLenum attachment);  // Fallible
    211  void DoDeferredAttachments() const;
    212  void RefreshDrawBuffers() const;
    213  void RefreshReadBuffer() const;
    214  void ResolveAttachmentData() const;
    215 
    216 public:
    217  void DetachTexture(const WebGLTexture* tex);
    218  void DetachRenderbuffer(const WebGLRenderbuffer* rb);
    219  bool ValidateAndInitAttachments(GLenum incompleteFbError) const;
    220  bool ValidateClearBufferType(GLenum buffer, uint32_t drawBuffer,
    221                               webgl::AttribBaseType funcType) const;
    222 
    223  bool ValidateForColorRead(const webgl::FormatUsageInfo** out_format,
    224                            uint32_t* out_width, uint32_t* out_height) const;
    225 
    226  ////////////////
    227  // Getters
    228 
    229 #define GETTER(X) \
    230  const decltype(m##X)& X() const { return m##X; }
    231 
    232  GETTER(DepthAttachment)
    233  GETTER(StencilAttachment)
    234  GETTER(DepthStencilAttachment)
    235  GETTER(Attachments)
    236  GETTER(ColorDrawBuffers)
    237  GETTER(ColorReadBuffer)
    238 
    239 #undef GETTER
    240 
    241  const auto& ColorAttachment0() const { return mColorAttachments[0]; }
    242  const auto& DrawBufferEnabled() const { return mDrawBufferEnabled; }
    243 
    244  ////////////////
    245  // Invalidation
    246 
    247  const auto* GetCompletenessInfo() const { return mCompletenessInfo.get(); }
    248 
    249  ////////////////
    250  // WebGL funcs
    251 
    252  bool IsCheckFramebufferStatusComplete() const {
    253    return CheckFramebufferStatus() == LOCAL_GL_FRAMEBUFFER_COMPLETE;
    254  }
    255 
    256  FBStatus CheckFramebufferStatus() const;
    257  bool FramebufferAttach(GLenum attachEnum,
    258                         const webgl::FbAttachInfo& toAttach);
    259  void DrawBuffers(const std::vector<GLenum>& buffers);
    260  void ReadBuffer(GLenum attachPoint);
    261 
    262  Maybe<double> GetAttachmentParameter(GLenum attachment, GLenum pname);
    263 
    264  static void BlitFramebuffer(WebGLContext* webgl, GLint srcX0, GLint srcY0,
    265                              GLint srcX1, GLint srcY1, GLint dstX0,
    266                              GLint dstY0, GLint dstX1, GLint dstY1,
    267                              GLbitfield mask, GLenum filter);
    268 };
    269 
    270 }  // namespace mozilla
    271 
    272 #endif  // WEBGL_FRAMEBUFFER_H_