DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef GLBLITHELPER_H_
#define GLBLITHELPER_H_

#include "GLContextTypes.h"
#include "GLConsts.h"
#include "nsSize.h"
#include "mozilla/Attributes.h"
#include "mozilla/gfx/Point.h"

namespace mozilla {

namespace layers {
class Image;
class PlanarYCbCrImage;
class GrallocImage;
class SurfaceTextureImage;
class EGLImageImage;
}

namespace gl {

class GLContext;

/**
 * Helper function that creates a 2D texture aSize.width x aSize.height with
 * storage type specified by aFormats. Returns GL texture object id.
 *
 * See mozilla::gl::CreateTexture.
 */
GLuint CreateTextureForOffscreen(GLContext* aGL, const GLFormats& aFormats,
                                 const gfx::IntSize& aSize);

/**
 * Helper function that creates a 2D texture aSize.width x aSize.height with
 * storage type aInternalFormat. Returns GL texture object id.
 *
 * Initialize textyre parameters to:
 *    GL_TEXTURE_MIN_FILTER = GL_LINEAR
 *    GL_TEXTURE_MAG_FILTER = GL_LINEAR
 *    GL_TEXTURE_WRAP_S = GL_CLAMP_TO_EDGE
 *    GL_TEXTURE_WRAP_T = GL_CLAMP_TO_EDGE
 */
GLuint CreateTexture(GLContext* aGL, GLenum aInternalFormat, GLenum aFormat,
                     GLenum aType, const gfx::IntSize& aSize, bool linear = true);

/**
 * Helper function to create, potentially, multisample render buffers suitable
 * for offscreen rendering. Buffers of size aSize.width x aSize.height with
 * storage specified by aFormat. returns GL render buffer object id.
 */
GLuint CreateRenderbuffer(GLContext* aGL, GLenum aFormat, GLsizei aSamples,
                          const gfx::IntSize& aSize);

/**
 * Helper function to create, potentially, multisample render buffers suitable
 * for offscreen rendering. Buffers of size aSize.width x aSize.height with
 * storage specified by aFormats. GL render buffer object ids are returned via
 * aColorMSRB, aDepthRB, and aStencilRB
 */
void CreateRenderbuffersForOffscreen(GLContext* aGL, const GLFormats& aFormats,
                                     const gfx::IntSize& aSize, bool aMultisample,
                                     GLuint* aColorMSRB, GLuint* aDepthRB,
                                     GLuint* aStencilRB);


/** Buffer blitting helper */
class GLBlitHelper final
{
    enum Channel
    {
        Channel_Y = 0,
        Channel_Cb,
        Channel_Cr,
        Channel_Max,
    };

    /**
     * BlitTex2D is used to copy blit the content of a GL_TEXTURE_2D object,
     * BlitTexRect is used to copy blit the content of a GL_TEXTURE_RECT object,
     * The difference between BlitTex2D and BlitTexRect is the texture type, which affect
     * the fragment shader a bit.
     *
     * ConvertGralloc is used to color convert copy blit the GrallocImage into a
     * normal RGB texture by egl_image_external extension
     * ConvertPlnarYcbCr is used to color convert copy blit the PlanarYCbCrImage
     * into a normal RGB texture by create textures of each color channel, and
     * convert it in GPU.
     * Convert type is created for canvas.
     */
    enum BlitType
    {
        BlitTex2D,
        BlitTexRect,
        ConvertGralloc,
        ConvertPlanarYCbCr,
        ConvertSurfaceTexture,
        ConvertEGLImage
    };
    // The GLContext is the sole owner of the GLBlitHelper.
    GLContext* mGL;

    GLuint mTexBlit_Buffer;
    GLuint mTexBlit_VertShader;
    GLuint mTex2DBlit_FragShader;
    GLuint mTex2DRectBlit_FragShader;
    GLuint mTex2DBlit_Program;
    GLuint mTex2DRectBlit_Program;

    GLint mYFlipLoc;

    GLint mTextureTransformLoc;

    // Data for image blit path
    GLuint mTexExternalBlit_FragShader;
    GLuint mTexYUVPlanarBlit_FragShader;
    GLuint mTexExternalBlit_Program;
    GLuint mTexYUVPlanarBlit_Program;
    GLuint mFBO;
    GLuint mSrcTexY;
    GLuint mSrcTexCb;
    GLuint mSrcTexCr;
    GLuint mSrcTexEGL;
    GLint mYTexScaleLoc;
    GLint mCbCrTexScaleLoc;
    int mTexWidth;
    int mTexHeight;

    // Cache some uniform values
    float mCurYScale;
    float mCurCbCrScale;

    void UseBlitProgram();
    void SetBlitFramebufferForDestTexture(GLuint aTexture);

    bool UseTexQuadProgram(BlitType target, const gfx::IntSize& srcSize);
    bool InitTexQuadProgram(BlitType target = BlitTex2D);
    void DeleteTexBlitProgram();
    void BindAndUploadYUVTexture(Channel which, uint32_t width, uint32_t height, void* data, bool allocation);
    void BindAndUploadEGLImage(EGLImage image, GLuint target);

#ifdef MOZ_WIDGET_GONK
    bool BlitGrallocImage(layers::GrallocImage* grallocImage, bool yflip);
#endif
    bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yflip);
#ifdef MOZ_WIDGET_ANDROID
    // Blit onto the current FB.
    bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yflip);
    bool BlitEGLImageImage(layers::EGLImageImage* eglImage, bool yflip);
#endif

public:

    explicit GLBlitHelper(GLContext* gl);
    ~GLBlitHelper();

    // If you don't have |srcFormats| for the 2nd definition,
    // then you'll need the framebuffer_blit extensions to use
    // the first BlitFramebufferToFramebuffer.
    void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
                                      const gfx::IntSize& srcSize,
                                      const gfx::IntSize& destSize,
                                      bool internalFBs = false);
    void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
                                      const gfx::IntSize& srcSize,
                                      const gfx::IntSize& destSize,
                                      const GLFormats& srcFormats,
                                      bool internalFBs = false);
    void BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
                                  const gfx::IntSize& srcSize,
                                  const gfx::IntSize& destSize,
                                  GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
                                  bool internalFBs = false);
    void BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
                                  const gfx::IntSize& srcSize,
                                  const gfx::IntSize& destSize,
                                  GLenum destTarget = LOCAL_GL_TEXTURE_2D,
                                  bool internalFBs = false);
    void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
                              const gfx::IntSize& srcSize,
                              const gfx::IntSize& destSize,
                              GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
                              GLenum destTarget = LOCAL_GL_TEXTURE_2D);
    bool BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize,
                                GLuint destFB, bool yflip = false, GLuint xoffset = 0,
                                GLuint yoffset = 0, GLuint width = 0, GLuint height = 0);
    bool BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize,
                            GLuint destTex, GLenum destTarget, bool yflip = false,
                            GLuint xoffset = 0, GLuint yoffset = 0, GLuint width = 0,
                            GLuint height = 0);
};

} // namespace gl
} // namespace mozilla

#endif // GLBLITHELPER_H_