1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set ts=8 sts=4 et sw=4 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 "GLContextTypes.h"
11 #include "GLConsts.h"
12 #include "nsSize.h"
13 #include "mozilla/Attributes.h"
14 #include "mozilla/gfx/Point.h"
15 
16 namespace mozilla {
17 
18 namespace layers {
19 class Image;
20 class PlanarYCbCrImage;
21 class GrallocImage;
22 class SurfaceTextureImage;
23 class MacIOSurfaceImage;
24 class EGLImageImage;
25 } // namespace layers
26 
27 namespace gl {
28 
29 class GLContext;
30 
31 /** Buffer blitting helper */
32 class GLBlitHelper final
33 {
34     enum Channel
35     {
36         Channel_Y = 0,
37         Channel_Cb,
38         Channel_Cr,
39         Channel_Max,
40     };
41 
42     /**
43      * BlitTex2D is used to copy blit the content of a GL_TEXTURE_2D object,
44      * BlitTexRect is used to copy blit the content of a GL_TEXTURE_RECT object,
45      * The difference between BlitTex2D and BlitTexRect is the texture type, which affect
46      * the fragment shader a bit.
47      *
48      * ConvertGralloc is used to color convert copy blit the GrallocImage into a
49      * normal RGB texture by egl_image_external extension
50      * ConvertPlnarYcbCr is used to color convert copy blit the PlanarYCbCrImage
51      * into a normal RGB texture by create textures of each color channel, and
52      * convert it in GPU.
53      * Convert type is created for canvas.
54      */
55     enum BlitType
56     {
57         BlitTex2D,
58         BlitTexRect,
59         ConvertGralloc,
60         ConvertPlanarYCbCr,
61         ConvertSurfaceTexture,
62         ConvertEGLImage,
63         ConvertMacIOSurfaceImage
64     };
65     // The GLContext is the sole owner of the GLBlitHelper.
66     GLContext* mGL;
67 
68     GLuint mTexBlit_Buffer;
69     GLuint mTexBlit_VertShader;
70     GLuint mTex2DBlit_FragShader;
71     GLuint mTex2DRectBlit_FragShader;
72     GLuint mTex2DBlit_Program;
73     GLuint mTex2DRectBlit_Program;
74 
75     GLint mYFlipLoc;
76 
77     GLint mTextureTransformLoc;
78 
79     // Data for image blit path
80     GLuint mTexExternalBlit_FragShader;
81     GLuint mTexYUVPlanarBlit_FragShader;
82     GLuint mTexNV12PlanarBlit_FragShader;
83     GLuint mTexExternalBlit_Program;
84     GLuint mTexYUVPlanarBlit_Program;
85     GLuint mTexNV12PlanarBlit_Program;
86     GLuint mFBO;
87     GLuint mSrcTexY;
88     GLuint mSrcTexCb;
89     GLuint mSrcTexCr;
90     GLuint mSrcTexEGL;
91     GLint mYTexScaleLoc;
92     GLint mCbCrTexScaleLoc;
93     GLint mYuvColorMatrixLoc;
94     int mTexWidth;
95     int mTexHeight;
96 
97     // Cache some uniform values
98     float mCurYScale;
99     float mCurCbCrScale;
100 
101     void UseBlitProgram();
102     void SetBlitFramebufferForDestTexture(GLuint aTexture);
103 
104     bool UseTexQuadProgram(BlitType target, const gfx::IntSize& srcSize);
105     bool InitTexQuadProgram(BlitType target = BlitTex2D);
106     void DeleteTexBlitProgram();
107     void BindAndUploadYUVTexture(Channel which, uint32_t width, uint32_t height, void* data, bool allocation);
108     void BindAndUploadEGLImage(EGLImage image, GLuint target);
109 
110     bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage);
111 #ifdef MOZ_WIDGET_ANDROID
112     // Blit onto the current FB.
113     bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage);
114     bool BlitEGLImageImage(layers::EGLImageImage* eglImage);
115 #endif
116 #ifdef XP_MACOSX
117     bool BlitMacIOSurfaceImage(layers::MacIOSurfaceImage* ioImage);
118 #endif
119 
120     explicit GLBlitHelper(GLContext* gl);
121 
122     friend class GLContext;
123 
124 public:
125     ~GLBlitHelper();
126 
127     // If you don't have |srcFormats| for the 2nd definition,
128     // then you'll need the framebuffer_blit extensions to use
129     // the first BlitFramebufferToFramebuffer.
130     void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
131                                       const gfx::IntSize& srcSize,
132                                       const gfx::IntSize& destSize,
133                                       bool internalFBs = false);
134     void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
135                                       const gfx::IntSize& srcSize,
136                                       const gfx::IntSize& destSize,
137                                       const GLFormats& srcFormats,
138                                       bool internalFBs = false);
139     void BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
140                                   const gfx::IntSize& srcSize,
141                                   const gfx::IntSize& destSize,
142                                   GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
143                                   bool internalFBs = false);
144     void DrawBlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
145                                       const gfx::IntSize& srcSize,
146                                       const gfx::IntSize& destSize,
147                                       GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
148                                       bool internalFBs = false);
149     void BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
150                                   const gfx::IntSize& srcSize,
151                                   const gfx::IntSize& destSize,
152                                   GLenum destTarget = LOCAL_GL_TEXTURE_2D,
153                                   bool internalFBs = false);
154     void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
155                               const gfx::IntSize& srcSize,
156                               const gfx::IntSize& destSize,
157                               GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
158                               GLenum destTarget = LOCAL_GL_TEXTURE_2D);
159     bool BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize,
160                                 GLuint destFB, OriginPos destOrigin);
161     bool BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize,
162                             GLuint destTex, GLenum destTarget, OriginPos destOrigin);
163 };
164 
165 } // namespace gl
166 } // namespace mozilla
167 
168 #endif // GLBLITHELPER_H_
169