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_