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