Blame gfx/gl/GLBlitHelper.h

Packit f0b94e
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
Packit f0b94e
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#ifndef GLBLITHELPER_H_
Packit f0b94e
#define GLBLITHELPER_H_
Packit f0b94e
Packit f0b94e
#include "GLContextTypes.h"
Packit f0b94e
#include "GLConsts.h"
Packit f0b94e
#include "nsSize.h"
Packit f0b94e
#include "ipc/IPCMessageUtils.h"
Packit f0b94e
#include "mozilla/Attributes.h"
Packit f0b94e
#include "mozilla/gfx/Point.h"
Packit f0b94e
#include "../layers/ImageTypes.h"
Packit f0b94e
Packit f0b94e
#ifdef XP_WIN
Packit f0b94e
#include <windows.h>
Packit f0b94e
#endif
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
Packit f0b94e
namespace layers {
Packit f0b94e
class D3D11YCbCrImage;
Packit f0b94e
class Image;
Packit f0b94e
class GPUVideoImage;
Packit f0b94e
class PlanarYCbCrImage;
Packit f0b94e
class SurfaceTextureImage;
Packit f0b94e
class MacIOSurfaceImage;
Packit f0b94e
class SurfaceDescriptorD3D10;
Packit f0b94e
class SurfaceDescriptorDXGIYCbCr;
Packit f0b94e
}  // namespace layers
Packit f0b94e
Packit f0b94e
namespace gl {
Packit f0b94e
Packit f0b94e
class BindAnglePlanes;
Packit f0b94e
class GLContext;
Packit f0b94e
class GLBlitHelper;
Packit f0b94e
Packit f0b94e
bool GuessDivisors(const gfx::IntSize& ySize, const gfx::IntSize& uvSize,
Packit f0b94e
                   gfx::IntSize* const out_divisors);
Packit f0b94e
Packit f0b94e
template <uint8_t N>
Packit f0b94e
struct Mat {
Packit f0b94e
  float m[N * N];  // column-major, for GL
Packit f0b94e
Packit f0b94e
  float& at(const uint8_t x, const uint8_t y) { return m[N * x + y]; }
Packit f0b94e
Packit f0b94e
  static Mat<N> Zero();
Packit f0b94e
  static Mat<N> I();
Packit f0b94e
Packit f0b94e
  Mat<N> operator*(const Mat<N>& r) const;
Packit f0b94e
};
Packit f0b94e
typedef Mat<3> Mat3;
Packit f0b94e
Packit f0b94e
Mat3 SubRectMat3(float x, float y, float w, float h);
Packit f0b94e
Mat3 SubRectMat3(const gfx::IntRect& subrect, const gfx::IntSize& size);
Packit f0b94e
Mat3 SubRectMat3(const gfx::IntRect& bigSubrect, const gfx::IntSize& smallSize,
Packit f0b94e
                 const gfx::IntSize& divisors);
Packit f0b94e
Packit f0b94e
class DrawBlitProg final {
Packit f0b94e
  const GLBlitHelper& mParent;
Packit f0b94e
  const GLuint mProg;
Packit f0b94e
  const GLint mLoc_uDestMatrix;
Packit f0b94e
  const GLint mLoc_uTexMatrix0;
Packit f0b94e
  const GLint mLoc_uTexMatrix1;
Packit f0b94e
  const GLint mLoc_uColorMatrix;
Packit f0b94e
  GLenum mType_uColorMatrix;
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  struct Key final {
Packit f0b94e
    const char* const fragHeader;
Packit f0b94e
    const char* const fragBody;
Packit f0b94e
Packit f0b94e
    bool operator<(const Key& x) const {
Packit f0b94e
      if (fragHeader != x.fragHeader) return fragHeader < x.fragHeader;
Packit f0b94e
      return fragBody < x.fragBody;
Packit f0b94e
    }
Packit f0b94e
  };
Packit f0b94e
Packit f0b94e
  DrawBlitProg(const GLBlitHelper* parent, GLuint prog);
Packit f0b94e
  ~DrawBlitProg();
Packit f0b94e
Packit f0b94e
  struct BaseArgs final {
Packit f0b94e
    Mat3 texMatrix0;
Packit f0b94e
    bool yFlip;
Packit f0b94e
    gfx::IntSize
Packit f0b94e
        destSize;  // Always needed for (at least) setting the viewport.
Packit f0b94e
    Maybe<gfx::IntRect> destRect;
Packit f0b94e
  };
Packit f0b94e
  struct YUVArgs final {
Packit f0b94e
    Mat3 texMatrix1;
Packit f0b94e
    YUVColorSpace colorSpace;
Packit f0b94e
  };
Packit f0b94e
Packit f0b94e
  void Draw(const BaseArgs& args, const YUVArgs* argsYUV = nullptr) const;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
class ScopedSaveMultiTex final {
Packit f0b94e
  GLContext& mGL;
Packit f0b94e
  const uint8_t mTexCount;
Packit f0b94e
  const GLenum mTexTarget;
Packit f0b94e
  const GLuint mOldTexUnit;
Packit f0b94e
  GLuint mOldTexSampler[3];
Packit f0b94e
  GLuint mOldTex[3];
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  ScopedSaveMultiTex(GLContext* gl, uint8_t texCount, GLenum texTarget);
Packit f0b94e
  ~ScopedSaveMultiTex();
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
/** Buffer blitting helper */
Packit f0b94e
class GLBlitHelper final {
Packit f0b94e
  friend class BindAnglePlanes;
Packit f0b94e
  friend class DrawBlitProg;
Packit f0b94e
  friend class GLContext;
Packit f0b94e
Packit f0b94e
  GLContext* const mGL;
Packit f0b94e
  mutable std::map<DrawBlitProg::Key, const DrawBlitProg*> mDrawBlitProgs;
Packit f0b94e
Packit f0b94e
  GLuint mQuadVAO;
Packit f0b94e
  GLuint mQuadVBO;
Packit f0b94e
  nsCString mDrawBlitProg_VersionLine;
Packit f0b94e
  const GLuint mDrawBlitProg_VertShader;
Packit f0b94e
Packit f0b94e
  GLuint mYuvUploads[3];
Packit f0b94e
  gfx::IntSize mYuvUploads_YSize;
Packit f0b94e
  gfx::IntSize mYuvUploads_UVSize;
Packit f0b94e
Packit f0b94e
#ifdef XP_WIN
Packit f0b94e
  mutable RefPtr<ID3D11Device> mD3D11;
Packit f0b94e
Packit f0b94e
  ID3D11Device* GetD3D11() const;
Packit f0b94e
#endif
Packit f0b94e
Packit f0b94e
  const DrawBlitProg* GetDrawBlitProg(const DrawBlitProg::Key& key) const;
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  const DrawBlitProg* CreateDrawBlitProg(const DrawBlitProg::Key& key) const;
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  bool BlitImage(layers::PlanarYCbCrImage* yuvImage,
Packit f0b94e
                 const gfx::IntSize& destSize, OriginPos destOrigin);
Packit f0b94e
#ifdef MOZ_WIDGET_ANDROID
Packit f0b94e
  // Blit onto the current FB.
Packit f0b94e
  bool BlitImage(layers::SurfaceTextureImage* stImage,
Packit f0b94e
                 const gfx::IntSize& destSize, OriginPos destOrigin) const;
Packit f0b94e
#endif
Packit f0b94e
#ifdef XP_MACOSX
Packit f0b94e
  bool BlitImage(layers::MacIOSurfaceImage* srcImage,
Packit f0b94e
                 const gfx::IntSize& destSize, OriginPos destOrigin) const;
Packit f0b94e
#endif
Packit f0b94e
Packit f0b94e
  explicit GLBlitHelper(GLContext* gl);
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  ~GLBlitHelper();
Packit f0b94e
Packit f0b94e
  void BlitFramebuffer(const gfx::IntSize& srcSize,
Packit f0b94e
                       const gfx::IntSize& destSize) const;
Packit f0b94e
  void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
Packit f0b94e
                                    const gfx::IntSize& srcSize,
Packit f0b94e
                                    const gfx::IntSize& destSize) const;
Packit f0b94e
  void BlitFramebufferToTexture(GLuint destTex, const gfx::IntSize& srcSize,
Packit f0b94e
                                const gfx::IntSize& destSize,
Packit f0b94e
                                GLenum destTarget = LOCAL_GL_TEXTURE_2D) const;
Packit f0b94e
  void BlitTextureToFramebuffer(GLuint srcTex, const gfx::IntSize& srcSize,
Packit f0b94e
                                const gfx::IntSize& destSize,
Packit f0b94e
                                GLenum srcTarget = LOCAL_GL_TEXTURE_2D) const;
Packit f0b94e
  void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
Packit f0b94e
                            const gfx::IntSize& srcSize,
Packit f0b94e
                            const gfx::IntSize& destSize,
Packit f0b94e
                            GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
Packit f0b94e
                            GLenum destTarget = LOCAL_GL_TEXTURE_2D) const;
Packit f0b94e
Packit f0b94e
  void DrawBlitTextureToFramebuffer(
Packit f0b94e
      GLuint srcTex, const gfx::IntSize& srcSize, const gfx::IntSize& destSize,
Packit f0b94e
      GLenum srcTarget = LOCAL_GL_TEXTURE_2D) const;
Packit f0b94e
Packit f0b94e
  bool BlitImageToFramebuffer(layers::Image* srcImage,
Packit f0b94e
                              const gfx::IntSize& destSize,
Packit f0b94e
                              OriginPos destOrigin);
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
#ifdef XP_WIN
Packit f0b94e
  // GLBlitHelperD3D.cpp:
Packit f0b94e
  bool BlitImage(layers::GPUVideoImage* srcImage, const gfx::IntSize& destSize,
Packit f0b94e
                 OriginPos destOrigin) const;
Packit f0b94e
  bool BlitImage(layers::D3D11YCbCrImage* srcImage,
Packit f0b94e
                 const gfx::IntSize& destSize, OriginPos destOrigin) const;
Packit f0b94e
Packit f0b94e
  bool BlitDescriptor(const layers::SurfaceDescriptorD3D10& desc,
Packit f0b94e
                      const gfx::IntSize& destSize, OriginPos destOrigin) const;
Packit f0b94e
Packit f0b94e
  bool BlitAngleYCbCr(const WindowsHandle (&handleList)[3],
Packit f0b94e
                      const gfx::IntRect& clipRect, const gfx::IntSize& ySize,
Packit f0b94e
                      const gfx::IntSize& uvSize,
Packit f0b94e
                      const YUVColorSpace colorSpace,
Packit f0b94e
                      const gfx::IntSize& destSize, OriginPos destOrigin) const;
Packit f0b94e
Packit f0b94e
  bool BlitAnglePlanes(uint8_t numPlanes,
Packit f0b94e
                       const RefPtr<ID3D11Texture2D>* texD3DList,
Packit f0b94e
                       const DrawBlitProg* prog,
Packit f0b94e
                       const DrawBlitProg::BaseArgs& baseArgs,
Packit f0b94e
                       const DrawBlitProg::YUVArgs* const yuvArgs) const;
Packit f0b94e
#endif
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
extern const char* const kFragHeader_Tex2D;
Packit f0b94e
extern const char* const kFragHeader_Tex2DRect;
Packit f0b94e
extern const char* const kFragHeader_TexExt;
Packit f0b94e
extern const char* const kFragBody_RGBA;
Packit f0b94e
extern const char* const kFragBody_CrYCb;
Packit f0b94e
extern const char* const kFragBody_NV12;
Packit f0b94e
extern const char* const kFragBody_PlanarYUV;
Packit f0b94e
Packit f0b94e
}  // namespace gl
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
#endif  // GLBLITHELPER_H_