blob: a83d74b8be24c2ecafd2633557033b5db7982292 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKY_ENGINE_PLATFORM_GRAPHICS_GPU_WEBGLIMAGECONVERSION_H_
#define SKY_ENGINE_PLATFORM_GRAPHICS_GPU_WEBGLIMAGECONVERSION_H_
#include "sky/engine/platform/PlatformExport.h"
#include "sky/engine/platform/graphics/Image.h"
#include "sky/engine/wtf/RefPtr.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
namespace blink {
class Image;
class IntSize;
// Helper functions for texture uploading and pixel readback.
class PLATFORM_EXPORT WebGLImageConversion {
public:
// Attempt to enumerate all possible native image formats to
// reduce the amount of temporary allocations during texture
// uploading. This enum must be public because it is accessed
// by non-member functions.
enum DataFormat {
DataFormatRGBA8 = 0,
DataFormatRGBA16F,
DataFormatRGBA32F,
DataFormatRGB8,
DataFormatRGB16F,
DataFormatRGB32F,
DataFormatBGR8,
DataFormatBGRA8,
DataFormatARGB8,
DataFormatABGR8,
DataFormatRGBA5551,
DataFormatRGBA4444,
DataFormatRGB565,
DataFormatR8,
DataFormatR16F,
DataFormatR32F,
DataFormatRA8,
DataFormatRA16F,
DataFormatRA32F,
DataFormatAR8,
DataFormatA8,
DataFormatA16F,
DataFormatA32F,
DataFormatNumFormats
};
enum ChannelBits {
ChannelRed = 1,
ChannelGreen = 2,
ChannelBlue = 4,
ChannelAlpha = 8,
ChannelDepth = 16,
ChannelStencil = 32,
ChannelRGB = ChannelRed | ChannelGreen | ChannelBlue,
ChannelRGBA = ChannelRGB | ChannelAlpha,
};
// Possible alpha operations that may need to occur during
// pixel packing. FIXME: kAlphaDoUnmultiply is lossy and must
// be removed.
enum AlphaOp {
AlphaDoNothing = 0,
AlphaDoPremultiply = 1,
AlphaDoUnmultiply = 2
};
enum ImageHtmlDomSource {
HtmlDomImage = 0,
HtmlDomCanvas = 1,
HtmlDomVideo = 2,
HtmlDomNone = 3
};
class PLATFORM_EXPORT ImageExtractor {
public:
ImageExtractor(Image*, ImageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
~ImageExtractor();
bool extractSucceeded() { return m_extractSucceeded; }
const void* imagePixelData() { return m_imagePixelData; }
unsigned imageWidth() { return m_imageWidth; }
unsigned imageHeight() { return m_imageHeight; }
DataFormat imageSourceFormat() { return m_imageSourceFormat; }
AlphaOp imageAlphaOp() { return m_alphaOp; }
unsigned imageSourceUnpackAlignment() { return m_imageSourceUnpackAlignment; }
ImageHtmlDomSource imageHtmlDomSource() { return m_imageHtmlDomSource; }
private:
// Extract the image and keeps track of its status, such as width, height, Source Alignment, format and AlphaOp etc.
// This needs to lock the resources or relevant data if needed and return true upon success
bool extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
RefPtr<NativeImageSkia> m_nativeImage;
RefPtr<NativeImageSkia> m_skiaImage;
Image* m_image;
ImageHtmlDomSource m_imageHtmlDomSource;
bool m_extractSucceeded;
const void* m_imagePixelData;
unsigned m_imageWidth;
unsigned m_imageHeight;
DataFormat m_imageSourceFormat;
AlphaOp m_alphaOp;
unsigned m_imageSourceUnpackAlignment;
};
// Computes the components per pixel and bytes per component
// for the given format and type combination. Returns false if
// either was an invalid enum.
static bool computeFormatAndTypeParameters(GLenum format, GLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent);
// Computes the image size in bytes. If paddingInBytes is not null, padding
// is also calculated in return. Returns NO_ERROR if succeed, otherwise
// return the suggested GL error indicating the cause of the failure:
// INVALID_VALUE if width/height is negative or overflow happens.
// INVALID_ENUM if format/type is illegal.
static GLenum computeImageSizeInBytes(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, unsigned* imageSizeInBytes, unsigned* paddingInBytes);
// Check if the format is one of the formats from the ImageData or DOM elements.
// The formats from ImageData is always RGBA8.
// The formats from DOM elements vary with Graphics ports. It can only be RGBA8 or BGRA8.
static ALWAYS_INLINE bool srcFormatComeFromDOMElementOrImageData(DataFormat SrcFormat)
{
return SrcFormat == DataFormatBGRA8 || SrcFormat == DataFormatRGBA8;
}
static unsigned getClearBitsByFormat(GLenum);
static unsigned getChannelBitsByFormat(GLenum);
// The Following functions are implemented in GraphicsContext3DImagePacking.cpp
// Packs the contents of the given Image which is passed in |pixels| into the passed Vector
// according to the given format and type, and obeying the flipY and AlphaOp flags.
// Returns true upon success.
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);
// Extracts the contents of the given ImageData into the passed Vector,
// packing the pixel data according to the given format and type,
// and obeying the flipY and premultiplyAlpha flags. Returns true
// upon success.
static bool extractImageData(const uint8_t*, const IntSize&, GLenum format, GLenum type, bool flipY, bool premultiplyAlpha, Vector<uint8_t>& data);
// Helper function which extracts the user-supplied texture
// data, applying the flipY and premultiplyAlpha parameters.
// If the data is not tightly packed according to the passed
// unpackAlignment, the output data will be tightly packed.
// Returns true if successful, false if any error occurred.
static bool extractTextureData(unsigned width, unsigned height, GLenum format, GLenum type, unsigned unpackAlignment, bool flipY, bool premultiplyAlpha, const void* pixels, Vector<uint8_t>& data);
// End GraphicsContext3DImagePacking.cpp functions
private:
// Helper for packImageData/extractImageData/extractTextureData which implement packing of pixel
// data into the specified OpenGL destination format and type.
// A sourceUnpackAlignment of zero indicates that the source
// data is tightly packed. Non-zero values may take a slow path.
// Destination data will have no gaps between rows.
// Implemented in GraphicsContext3DImagePacking.cpp
static bool packPixels(const uint8_t* sourceData, DataFormat sourceDataFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, unsigned destinationFormat, unsigned destinationType, AlphaOp, void* destinationData, bool flipY);
};
} // namespace blink
#endif // SKY_ENGINE_PLATFORM_GRAPHICS_GPU_WEBGLIMAGECONVERSION_H_