Commit 07dd9ea7 authored by Kenneth Russell's avatar Kenneth Russell Committed by Commit Bot

Support uploading linear gamma profile ImageBitmaps to WebGL textures.

These are converted to RGBA16F format, which WebGLImageConversion
didn't handle, and the calling code didn't detect that failure.

In WebGLImageConversion, handle unpacking half-float data to 32-bit
floating-point, as well as all packing conversions to the supported
texture upload formats. Expand comments describing the needed
conversions and remove old incorrect FIXMEs.

Tested thoroughly with the enhanced image_bitmap_from_blob WebGL
conformance tests in https://github.com/KhronosGroup/WebGL/pull/3100 .
All versions of the test (2D/3D, all texture upload formats) pass in
Chromium with this fix.

Bug: 1058160
Change-Id: I6bf4e5b9370cbd471e02030858ca1e93c7b88af3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2253372
Commit-Queue: Kenneth Russell <kbr@chromium.org>
Reviewed-by: default avatarShrek Shao <shrekshao@google.com>
Reviewed-by: default avatarJames Darpinian <jdarpinian@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781140}
parent d4b7a2fd
...@@ -5907,21 +5907,32 @@ void WebGLRenderingContextBase::TexImageHelperImageBitmap( ...@@ -5907,21 +5907,32 @@ void WebGLRenderingContextBase::TexImageHelperImageBitmap(
// The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
type = GL_FLOAT; type = GL_FLOAT;
} }
WebGLImageConversion::DataFormat data_format;
if (is_pixel_data_rgba) {
data_format = WebGLImageConversion::DataFormat::kDataFormatRGBA8;
} else {
switch (pixmap.colorType()) {
case SkColorType::kBGRA_8888_SkColorType:
data_format = WebGLImageConversion::DataFormat::kDataFormatBGRA8;
break;
case SkColorType::kRGBA_F16_SkColorType:
// Used in ImageBitmap's ApplyColorSpaceConversion.
data_format = WebGLImageConversion::DataFormat::kDataFormatRGBA16F;
break;
default:
// Can not handle this ImageBitmap's format.
SynthesizeGLError(GL_INVALID_VALUE, func_name,
"unsupported color type / space in ImageBitmap");
return;
}
}
// In the case of ImageBitmap, we do not need to apply flipY or // In the case of ImageBitmap, we do not need to apply flipY or
// premultiplyAlpha. // premultiplyAlpha.
bool is_pixel_data_bgra = if (!WebGLImageConversion::ExtractImageData(
pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType; pixel_data_ptr, data_format, bitmap->Size(), source_sub_rect, depth,
if ((is_pixel_data_bgra && unpack_image_height, format, type, false, false, data)) {
!WebGLImageConversion::ExtractImageData( SynthesizeGLError(GL_INVALID_VALUE, func_name,
pixel_data_ptr, WebGLImageConversion::DataFormat::kDataFormatBGRA8, "error extracting data from ImageBitmap");
bitmap->Size(), source_sub_rect, depth, unpack_image_height,
format, type, false, false, data)) ||
(is_pixel_data_rgba &&
!WebGLImageConversion::ExtractImageData(
pixel_data_ptr, WebGLImageConversion::DataFormat::kDataFormatRGBA8,
bitmap->Size(), source_sub_rect, depth, unpack_image_height,
format, type, false, false, data))) {
SynthesizeGLError(GL_INVALID_VALUE, func_name, "bad image data");
return; return;
} }
} }
......
...@@ -194,12 +194,14 @@ class PLATFORM_EXPORT WebGLImageConversion final { ...@@ -194,12 +194,14 @@ class PLATFORM_EXPORT WebGLImageConversion final {
unsigned* padding_in_bytes, unsigned* padding_in_bytes,
unsigned* skip_size_in_bytes); unsigned* skip_size_in_bytes);
// Check if the format is one of the formats from the ImageData or DOM // Check if the format is one of the formats from ImageData DOM elements, or
// elements. The format from ImageData is always RGBA8. The formats from DOM // ImageBitmap. The format from ImageData is always RGBA8. The formats from
// elements vary with Graphics ports, but can only be RGBA8 or BGRA8. // DOM elements vary with Graphics ports, but can only be RGBA8 or BGRA8.
static ALWAYS_INLINE bool SrcFormatComeFromDOMElementOrImageData( // ImageBitmap can use RGBA16F when colorspace conversion is performed.
static ALWAYS_INLINE bool SrcFormatComesFromDOMElementOrImageData(
DataFormat src_format) { DataFormat src_format) {
return src_format == kDataFormatBGRA8 || src_format == kDataFormatRGBA8; return src_format == kDataFormatBGRA8 || src_format == kDataFormatRGBA8 ||
src_format == kDataFormatRGBA16F;
} }
// The input can be either format or internalformat. // The input can be either format or internalformat.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment