tor-browser

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

GLBlitHelper.h (12269B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef GLBLITHELPER_H_
      8 #define GLBLITHELPER_H_
      9 
     10 #include <array>
     11 #include <cstdint>
     12 #include <map>
     13 #include <memory>
     14 #include <unordered_map>
     15 #include <variant>
     16 #include "Colorspaces.h"
     17 #include "GLConsts.h"
     18 #include "GLContextTypes.h"
     19 #include "GLTypes.h"
     20 #include "nsSize.h"
     21 #include "nsString.h"
     22 #include "nsTString.h"
     23 #include "mozilla/ipc/IPCTypes.h"
     24 #include "mozilla/Maybe.h"
     25 #include "mozilla/gfx/MatrixFwd.h"
     26 #include "mozilla/gfx/Point.h"
     27 #include "mozilla/gfx/Rect.h"
     28 #include "mozilla/gfx/Types.h"
     29 #include "gfxTypes.h"
     30 
     31 #include <map>
     32 
     33 #ifdef XP_WIN
     34 #  include <windows.h>
     35 #  include "mozilla/RefPtr.h"
     36 #  include "mozilla/ipc/IPCTypes.h"
     37 struct ID3D11Device;
     38 struct ID3D11Texture2D;
     39 #endif
     40 
     41 #ifdef XP_MACOSX
     42 class MacIOSurface;
     43 #endif
     44 
     45 #ifdef MOZ_WIDGET_ANDROID
     46 #  include "mozilla/java/GeckoSurfaceTextureWrappers.h"
     47 #endif
     48 
     49 #ifdef MOZ_WIDGET_GTK
     50 class DMABufSurface;
     51 #endif
     52 
     53 namespace mozilla {
     54 
     55 namespace layers {
     56 class Image;
     57 class GPUVideoImage;
     58 struct PlanarYCbCrData;
     59 class PlanarYCbCrImage;
     60 class SurfaceDescriptor;
     61 class SurfaceDescriptorBuffer;
     62 
     63 #ifdef XP_WIN
     64 class D3D11ShareHandleImage;
     65 class D3D11ZeroCopyTextureImage;
     66 class SurfaceDescriptorD3D10;
     67 class SurfaceDescriptorDXGIYCbCr;
     68 #endif
     69 
     70 #ifdef MOZ_WIDGET_ANDROID
     71 class SurfaceTextureDescriptor;
     72 #endif
     73 
     74 #ifdef XP_MACOSX
     75 class MacIOSurfaceImage;
     76 #endif
     77 
     78 #ifdef MOZ_WIDGET_GTK
     79 class DMABUFSurfaceImage;
     80 #endif
     81 }  // namespace layers
     82 
     83 namespace gl {
     84 
     85 class BindAnglePlanes;
     86 class GLBlitHelper;
     87 class GLContext;
     88 class Texture;
     89 
     90 bool GuessDivisors(const gfx::IntSize& ySize, const gfx::IntSize& uvSize,
     91                   gfx::IntSize* const out_divisors);
     92 
     93 template <uint8_t N>
     94 struct Mat {
     95  float m[N * N];  // column-major, for GL
     96 
     97  float& at(const uint8_t x, const uint8_t y) { return m[N * x + y]; }
     98  float at(const uint8_t x, const uint8_t y) const { return m[N * x + y]; }
     99 
    100  static Mat<N> I() {
    101    auto ret = Mat<N>{};
    102    for (uint8_t i = 0; i < N; i++) {
    103      ret.at(i, i) = 1.0f;
    104    }
    105    return ret;
    106  }
    107 
    108  Mat<N> operator*(const Mat<N>& r) const {
    109    Mat<N> ret;
    110    for (uint8_t x = 0; x < N; x++) {
    111      for (uint8_t y = 0; y < N; y++) {
    112        float sum = 0.0f;
    113        for (uint8_t i = 0; i < N; i++) {
    114          sum += at(i, y) * r.at(x, i);
    115        }
    116        ret.at(x, y) = sum;
    117      }
    118    }
    119    return ret;
    120  }
    121 };
    122 typedef Mat<3> Mat3;
    123 
    124 Mat3 SubRectMat3(float x, float y, float w, float h);
    125 Mat3 SubRectMat3(const gfx::IntRect& subrect, const gfx::IntSize& size);
    126 Mat3 SubRectMat3(const gfx::IntRect& bigSubrect, const gfx::IntSize& smallSize,
    127                 const gfx::IntSize& divisors);
    128 Mat3 MatrixToMat3(const gfx::Matrix& aMatrix);
    129 
    130 class DrawBlitProg final {
    131  const GLBlitHelper& mParent;
    132 
    133 public:
    134  const GLuint mProg;
    135  const GLint mLoc_uDestMatrix;
    136  const GLint mLoc_uTexMatrix0;
    137  const GLint mLoc_uTexMatrix1;
    138  const GLint mLoc_uColorLut;
    139  const GLint mLoc_uColorMatrix;
    140  GLenum mType_uColorMatrix = 0;
    141 
    142 public:
    143  struct Key final {
    144    const char* fragHeader = nullptr;
    145    std::array<const char*, 4> fragParts = {};
    146 
    147    auto Members() const { return std::tie(fragHeader, fragParts); }
    148    friend bool operator<(const Key& a, const Key& b) {
    149      return a.Members() < b.Members();
    150    }
    151  };
    152 
    153  DrawBlitProg(const GLBlitHelper* parent, GLuint prog);
    154  ~DrawBlitProg();
    155 
    156  struct BaseArgs final {
    157    Mat3 texMatrix0;
    158    bool yFlip;
    159    gfx::IntSize fbSize;  // Always needed for (at least) setting the viewport.
    160    gfx::IntRect destRect;
    161    gfx::IntSize texSize;
    162  };
    163  struct YUVArgs final {
    164    Mat3 texMatrix1;
    165    Maybe<gfx::YUVColorSpace> colorSpaceForMatrix;
    166  };
    167 
    168  void Draw(const BaseArgs& args, const YUVArgs* argsYUV = nullptr) const;
    169 };
    170 
    171 class ScopedSaveMultiTex final {
    172  GLContext& mGL;
    173  const size_t mTexUnits;
    174  const GLenum mTexTarget;
    175  const GLuint mOldTexUnit;
    176  GLuint mOldTexSampler[3];
    177  GLuint mOldTex[3];
    178 
    179 public:
    180  ScopedSaveMultiTex(GLContext* gl, size_t texUnits, GLenum texTarget);
    181  ~ScopedSaveMultiTex();
    182 };
    183 
    184 /** Buffer blitting helper */
    185 class GLBlitHelper final {
    186  friend class BindAnglePlanes;
    187  friend class DrawBlitProg;
    188  friend class GLContext;
    189 
    190  GLContext* const mGL;
    191  mutable std::map<DrawBlitProg::Key, std::unique_ptr<const DrawBlitProg>>
    192      mDrawBlitProgs;
    193 
    194  GLuint mQuadVAO = 0;
    195  GLuint mQuadVBO = 0;
    196  nsCString mDrawBlitProg_VersionLine;
    197  const GLuint mDrawBlitProg_VertShader;
    198 
    199  GLuint mYuvUploads[3] = {};
    200  gfx::IntSize mYuvUploads_YSize = {0, 0};
    201  gfx::IntSize mYuvUploads_UVSize = {0, 0};
    202 
    203 public:
    204  static std::optional<color::ColorProfileDesc> ToColorProfileDesc(
    205      gfx::ColorSpace2);
    206 
    207  struct ColorLutKey : DeriveCmpOpMembers<ColorLutKey> {
    208    std::variant<gfx::ColorSpace2, gfx::YUVRangedColorSpace> src;
    209    gfx::ColorSpace2 dst;
    210 
    211    auto Members() const { return std::tie(src, dst); }
    212 
    213    MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(ColorLutKey)
    214 
    215    struct Hasher : mozilla::StdHashMembers<ColorLutKey> {};
    216  };
    217 
    218 private:
    219  mutable std::unordered_map<ColorLutKey, std::shared_ptr<gl::Texture>,
    220                             ColorLutKey::Hasher>
    221      mColorLutTexMap;
    222 
    223 public:
    224  std::shared_ptr<gl::Texture> GetColorLutTex(const ColorLutKey& key) const;
    225 
    226 #ifdef XP_WIN
    227  mutable RefPtr<ID3D11Device> mD3D11;
    228 
    229  ID3D11Device* GetD3D11() const;
    230 #endif
    231 
    232  const DrawBlitProg& GetDrawBlitProg(const DrawBlitProg::Key& key) const;
    233 
    234 private:
    235  std::unique_ptr<const DrawBlitProg> CreateDrawBlitProg(
    236      const DrawBlitProg::Key& key) const;
    237 
    238  const char* GetAlphaMixin(Maybe<gfxAlphaType>) const;
    239 
    240 public:
    241  bool BlitPlanarYCbCr(const layers::PlanarYCbCrData&,
    242                       const gfx::IntRect& destRect, OriginPos destOrigin,
    243                       const gfx::IntSize& fbSize = gfx::IntSize(),
    244                       Maybe<gfxAlphaType> convertAlpha = {});
    245 #ifdef MOZ_WIDGET_ANDROID
    246  bool Blit(const java::GeckoSurfaceTexture::Ref& surfaceTexture,
    247            const gfx::IntSize& texSize, const gfx::IntRect& destRect,
    248            const OriginPos destOrigin,
    249            const gfx::IntSize& fbSize = gfx::IntSize(),
    250            Maybe<gfxAlphaType> convertAlpha = {}) const;
    251  bool Blit(EGLImage image, EGLSync fence, const gfx::IntSize& texSize,
    252            const gfx::IntRect& destRect, const OriginPos destOrigin,
    253            const gfx::IntSize& fbSize = gfx::IntSize(),
    254            Maybe<gfxAlphaType> convertAlpha = {}) const;
    255 #endif
    256 #ifdef XP_MACOSX
    257  bool BlitImage(layers::MacIOSurfaceImage* srcImage,
    258                 const gfx::IntRect& destRect, OriginPos destOrigin,
    259                 const gfx::IntSize& fbSize = gfx::IntSize()) const;
    260 #endif
    261 #ifdef MOZ_WIDGET_GTK
    262  bool Blit(DMABufSurface* surface, const gfx::IntRect& destRect,
    263            OriginPos destOrigin, const gfx::IntSize& fbSize = gfx::IntSize(),
    264            Maybe<gfxAlphaType> convertAlpha = {}) const;
    265  bool BlitImage(layers::DMABUFSurfaceImage* srcImage,
    266                 const gfx::IntRect& destRect, OriginPos destOrigin,
    267                 const gfx::IntSize& fbSize = gfx::IntSize()) const;
    268  bool BlitYCbCrImageToDMABuf(const layers::PlanarYCbCrData& yuvData,
    269                              DMABufSurface* surface);
    270 #endif
    271 
    272  explicit GLBlitHelper(GLContext* gl);
    273 
    274 public:
    275  ~GLBlitHelper();
    276 
    277  void BlitFramebuffer(const gfx::IntRect& srcRect,
    278                       const gfx::IntRect& destRect,
    279                       GLuint filter = LOCAL_GL_NEAREST) const;
    280  void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
    281                                    const gfx::IntRect& srcRect,
    282                                    const gfx::IntRect& destRect,
    283                                    GLuint filter = LOCAL_GL_NEAREST) const;
    284  void BlitFramebufferToTexture(GLuint destTex, const gfx::IntSize& srcSize,
    285                                const gfx::IntSize& destSize,
    286                                GLenum destTarget = LOCAL_GL_TEXTURE_2D) const;
    287  void BlitTextureToFramebuffer(GLuint srcTex, const gfx::IntSize& srcSize,
    288                                const gfx::IntSize& destSize,
    289                                GLenum srcTarget = LOCAL_GL_TEXTURE_2D) const;
    290  void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
    291                            const gfx::IntSize& srcSize,
    292                            const gfx::IntSize& destSize,
    293                            GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
    294                            GLenum destTarget = LOCAL_GL_TEXTURE_2D) const;
    295 
    296  void DrawBlitTextureToFramebuffer(
    297      GLuint srcTex, const gfx::IntSize& srcSize, const gfx::IntSize& destSize,
    298      GLenum srcTarget = LOCAL_GL_TEXTURE_2D, bool srcIsBGRA = false,
    299      bool yFlip = false, Maybe<gfxAlphaType> convertAlpha = {}) const;
    300 
    301  bool BlitImageToFramebuffer(layers::Image* srcImage,
    302                              const gfx::IntRect& destRect,
    303                              OriginPos destOrigin,
    304                              const gfx::IntSize& fbSize = gfx::IntSize());
    305  bool BlitSdToFramebuffer(const layers::SurfaceDescriptor&,
    306                           const gfx::IntRect& destRect, OriginPos destOrigin,
    307                           const gfx::IntSize& fbSize = gfx::IntSize(),
    308                           Maybe<gfxAlphaType> convertAlpha = {});
    309 
    310 private:
    311  bool BlitImage(layers::GPUVideoImage* srcImage, const gfx::IntRect& destRect,
    312                 OriginPos destOrigin,
    313                 const gfx::IntSize& fbSize = gfx::IntSize()) const;
    314 #ifdef XP_MACOSX
    315  bool BlitImage(MacIOSurface* const iosurf, const gfx::IntRect& destRect,
    316                 OriginPos destOrigin,
    317                 const gfx::IntSize& fbSize = gfx::IntSize(),
    318                 Maybe<gfxAlphaType> convertAlpha = {}) const;
    319 #endif
    320 #ifdef XP_WIN
    321  // GLBlitHelperD3D.cpp:
    322  bool BlitImage(layers::D3D11ShareHandleImage* srcImage,
    323                 const gfx::IntRect& destRect, OriginPos destOrigin,
    324                 const gfx::IntSize& fbSize = gfx::IntSize()) const;
    325  bool BlitImage(layers::D3D11ZeroCopyTextureImage* srcImage,
    326                 const gfx::IntRect& destRect, OriginPos destOrigin,
    327                 const gfx::IntSize& fbSize = gfx::IntSize()) const;
    328 
    329  bool BlitDescriptor(const layers::SurfaceDescriptorD3D10& desc,
    330                      const gfx::IntRect& destRect, OriginPos destOrigin,
    331                      const gfx::IntSize& fbSize = gfx::IntSize(),
    332                      Maybe<gfxAlphaType> convertAlpha = {}) const;
    333  bool BlitDescriptor(const layers::SurfaceDescriptorDXGIYCbCr& desc,
    334                      const gfx::IntRect& destRect, const OriginPos destOrigin,
    335                      const gfx::IntSize& fbSize = gfx::IntSize(),
    336                      Maybe<gfxAlphaType> convertAlpha = {}) const;
    337  bool BlitAngleYCbCr(const WindowsHandle (&handleList)[3],
    338                      const gfx::IntRect& clipRect, const gfx::IntSize& ySize,
    339                      const gfx::IntSize& uvSize,
    340                      const gfx::YUVColorSpace colorSpace,
    341                      const gfx::IntRect& destRect, OriginPos destOrigin,
    342                      const gfx::IntSize& fbSize = gfx::IntSize(),
    343                      Maybe<gfxAlphaType> convertAlpha = {}) const;
    344 #endif
    345 };
    346 
    347 // -
    348 // For DrawBlitProg::Key::fragParts
    349 
    350 extern const char* const kFragHeader_Tex2D;
    351 extern const char* const kFragHeader_Tex2DRect;
    352 extern const char* const kFragHeader_TexExt;
    353 
    354 extern const char* const kFragSample_OnePlane;
    355 extern const char* const kFragSample_TwoPlane;
    356 extern const char* const kFragSample_ThreePlane;
    357 
    358 extern const char* const kFragConvert_None;
    359 extern const char* const kFragConvert_BGR;
    360 extern const char* const kFragConvert_ColorMatrix;
    361 extern const char* const kFragConvert_ColorLut3d;
    362 extern const char* const kFragConvert_ColorLut2d;
    363 
    364 extern const char* const kFragMixin_AlphaMultColors;
    365 extern const char* const kFragMixin_AlphaUnpremultColors;
    366 extern const char* const kFragMixin_AlphaClampColors;
    367 extern const char* const kFragMixin_AlphaOne;
    368 
    369 }  // namespace gl
    370 }  // namespace mozilla
    371 
    372 #endif  // GLBLITHELPER_H_