Home | History | Annotate | Download | only in gpu
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef WebGLImageConversion_h
      6 #define WebGLImageConversion_h
      7 
      8 #include "platform/PlatformExport.h"
      9 #include "platform/graphics/Image.h"
     10 #include "third_party/khronos/GLES2/gl2.h"
     11 #include "third_party/khronos/GLES2/gl2ext.h"
     12 #include "wtf/RefPtr.h"
     13 
     14 namespace blink {
     15 class Image;
     16 class IntSize;
     17 
     18 // Helper functions for texture uploading and pixel readback.
     19 class PLATFORM_EXPORT WebGLImageConversion {
     20 public:
     21     // Attempt to enumerate all possible native image formats to
     22     // reduce the amount of temporary allocations during texture
     23     // uploading. This enum must be public because it is accessed
     24     // by non-member functions.
     25     enum DataFormat {
     26         DataFormatRGBA8 = 0,
     27         DataFormatRGBA16F,
     28         DataFormatRGBA32F,
     29         DataFormatRGB8,
     30         DataFormatRGB16F,
     31         DataFormatRGB32F,
     32         DataFormatBGR8,
     33         DataFormatBGRA8,
     34         DataFormatARGB8,
     35         DataFormatABGR8,
     36         DataFormatRGBA5551,
     37         DataFormatRGBA4444,
     38         DataFormatRGB565,
     39         DataFormatR8,
     40         DataFormatR16F,
     41         DataFormatR32F,
     42         DataFormatRA8,
     43         DataFormatRA16F,
     44         DataFormatRA32F,
     45         DataFormatAR8,
     46         DataFormatA8,
     47         DataFormatA16F,
     48         DataFormatA32F,
     49         DataFormatNumFormats
     50     };
     51 
     52     enum ChannelBits {
     53         ChannelRed = 1,
     54         ChannelGreen = 2,
     55         ChannelBlue = 4,
     56         ChannelAlpha = 8,
     57         ChannelDepth = 16,
     58         ChannelStencil = 32,
     59         ChannelRGB = ChannelRed | ChannelGreen | ChannelBlue,
     60         ChannelRGBA = ChannelRGB | ChannelAlpha,
     61     };
     62 
     63     // Possible alpha operations that may need to occur during
     64     // pixel packing. FIXME: kAlphaDoUnmultiply is lossy and must
     65     // be removed.
     66     enum AlphaOp {
     67         AlphaDoNothing = 0,
     68         AlphaDoPremultiply = 1,
     69         AlphaDoUnmultiply = 2
     70     };
     71 
     72     enum ImageHtmlDomSource {
     73         HtmlDomImage = 0,
     74         HtmlDomCanvas = 1,
     75         HtmlDomVideo = 2,
     76         HtmlDomNone = 3
     77     };
     78 
     79     class PLATFORM_EXPORT ImageExtractor {
     80     public:
     81         ImageExtractor(Image*, ImageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
     82 
     83         ~ImageExtractor();
     84 
     85         bool extractSucceeded() { return m_extractSucceeded; }
     86         const void* imagePixelData() { return m_imagePixelData; }
     87         unsigned imageWidth() { return m_imageWidth; }
     88         unsigned imageHeight() { return m_imageHeight; }
     89         DataFormat imageSourceFormat() { return m_imageSourceFormat; }
     90         AlphaOp imageAlphaOp() { return m_alphaOp; }
     91         unsigned imageSourceUnpackAlignment() { return m_imageSourceUnpackAlignment; }
     92         ImageHtmlDomSource imageHtmlDomSource() { return m_imageHtmlDomSource; }
     93     private:
     94         // Extract the image and keeps track of its status, such as width, height, Source Alignment, format and AlphaOp etc.
     95         // This needs to lock the resources or relevant data if needed and return true upon success
     96         bool extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
     97 
     98         RefPtr<NativeImageSkia> m_nativeImage;
     99         RefPtr<NativeImageSkia> m_skiaImage;
    100         Image* m_image;
    101         ImageHtmlDomSource m_imageHtmlDomSource;
    102         bool m_extractSucceeded;
    103         const void* m_imagePixelData;
    104         unsigned m_imageWidth;
    105         unsigned m_imageHeight;
    106         DataFormat m_imageSourceFormat;
    107         AlphaOp m_alphaOp;
    108         unsigned m_imageSourceUnpackAlignment;
    109     };
    110 
    111     // Computes the components per pixel and bytes per component
    112     // for the given format and type combination. Returns false if
    113     // either was an invalid enum.
    114     static bool computeFormatAndTypeParameters(GLenum format, GLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent);
    115 
    116     // Computes the image size in bytes. If paddingInBytes is not null, padding
    117     // is also calculated in return. Returns NO_ERROR if succeed, otherwise
    118     // return the suggested GL error indicating the cause of the failure:
    119     //   INVALID_VALUE if width/height is negative or overflow happens.
    120     //   INVALID_ENUM if format/type is illegal.
    121     static GLenum computeImageSizeInBytes(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, unsigned* imageSizeInBytes, unsigned* paddingInBytes);
    122 
    123     // Check if the format is one of the formats from the ImageData or DOM elements.
    124     // The formats from ImageData is always RGBA8.
    125     // The formats from DOM elements vary with Graphics ports. It can only be RGBA8 or BGRA8.
    126     static ALWAYS_INLINE bool srcFormatComeFromDOMElementOrImageData(DataFormat SrcFormat)
    127     {
    128         return SrcFormat == DataFormatBGRA8 || SrcFormat == DataFormatRGBA8;
    129     }
    130 
    131     static unsigned getClearBitsByFormat(GLenum);
    132     static unsigned getChannelBitsByFormat(GLenum);
    133 
    134     // The Following functions are implemented in GraphicsContext3DImagePacking.cpp
    135 
    136     // Packs the contents of the given Image which is passed in |pixels| into the passed Vector
    137     // according to the given format and type, and obeying the flipY and AlphaOp flags.
    138     // Returns true upon success.
    139     static bool packImageData(Image*, const void* pixels, GLenum format, GLenum type, bool flipY, AlphaOp, DataFormat sourceFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, Vector<uint8_t>& data);
    140 
    141     // Extracts the contents of the given ImageData into the passed Vector,
    142     // packing the pixel data according to the given format and type,
    143     // and obeying the flipY and premultiplyAlpha flags. Returns true
    144     // upon success.
    145     static bool extractImageData(const uint8_t*, const IntSize&, GLenum format, GLenum type, bool flipY, bool premultiplyAlpha, Vector<uint8_t>& data);
    146 
    147     // Helper function which extracts the user-supplied texture
    148     // data, applying the flipY and premultiplyAlpha parameters.
    149     // If the data is not tightly packed according to the passed
    150     // unpackAlignment, the output data will be tightly packed.
    151     // Returns true if successful, false if any error occurred.
    152     static bool extractTextureData(unsigned width, unsigned height, GLenum format, GLenum type, unsigned unpackAlignment, bool flipY, bool premultiplyAlpha, const void* pixels, Vector<uint8_t>& data);
    153 
    154     // End GraphicsContext3DImagePacking.cpp functions
    155 
    156 private:
    157     // Helper for packImageData/extractImageData/extractTextureData which implement packing of pixel
    158     // data into the specified OpenGL destination format and type.
    159     // A sourceUnpackAlignment of zero indicates that the source
    160     // data is tightly packed. Non-zero values may take a slow path.
    161     // Destination data will have no gaps between rows.
    162     // Implemented in GraphicsContext3DImagePacking.cpp
    163     static bool packPixels(const uint8_t* sourceData, DataFormat sourceDataFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, unsigned destinationFormat, unsigned destinationType, AlphaOp, void* destinationData, bool flipY);
    164 };
    165 
    166 } // namespace blink
    167 
    168 #endif // WebGLImageConversion_h
    169