Index: third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp |
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp |
index 4a5d14a049e9da575d69bd1de99f585e5c692fe9..a827029668893e88519a163b8ca2b5dccdb3aa8c 100644 |
--- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp |
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp |
@@ -38,8 +38,11 @@ |
namespace blink { |
BaseRenderingContext2D::BaseRenderingContext2D() |
- : clip_antialiasing_(kNotAntiAliased) { |
+ : clip_antialiasing_(kNotAntiAliased), color_management_enabled_(false) { |
state_stack_.push_back(CanvasRenderingContext2DState::Create()); |
+ color_management_enabled_ = |
+ RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() && |
+ RuntimeEnabledFeatures::colorCorrectRenderingEnabled(); |
} |
BaseRenderingContext2D::~BaseRenderingContext2D() {} |
@@ -1508,10 +1511,26 @@ bool BaseRenderingContext2D::ComputeDirtyRect( |
return true; |
} |
+ImageDataColorSettings |
+BaseRenderingContext2D::GetColorSettingsAsImageDataColorSettings() const { |
+ ImageDataColorSettings color_settings; |
+ color_settings.setColorSpace(ColorSpaceAsString()); |
+ if (PixelFormat() == kF16CanvasPixelFormat) |
+ color_settings.setStorageFormat(kFloat32ArrayStorageFormatName); |
+ return color_settings; |
+} |
+ |
ImageData* BaseRenderingContext2D::createImageData( |
ImageData* image_data, |
ExceptionState& exception_state) const { |
- ImageData* result = ImageData::Create(image_data->Size()); |
+ ImageData* result = nullptr; |
+ if (color_management_enabled_) { |
+ ImageDataColorSettings color_settings = |
+ GetColorSettingsAsImageDataColorSettings(); |
+ result = ImageData::Create(image_data->Size(), &color_settings); |
+ } else { |
+ result = ImageData::Create(image_data->Size()); |
+ } |
if (!result) |
exception_state.ThrowRangeError("Out of memory at ImageData creation"); |
return result; |
@@ -1529,13 +1548,49 @@ ImageData* BaseRenderingContext2D::createImageData( |
} |
IntSize size(abs(sw), abs(sh)); |
+ ImageData* result = nullptr; |
+ if (color_management_enabled_) { |
+ ImageDataColorSettings color_settings = |
+ GetColorSettingsAsImageDataColorSettings(); |
+ result = ImageData::Create(size, &color_settings); |
+ } else { |
+ result = ImageData::Create(size); |
+ } |
- ImageData* result = ImageData::Create(size); |
if (!result) |
exception_state.ThrowRangeError("Out of memory at ImageData creation"); |
return result; |
} |
+ImageData* BaseRenderingContext2D::createImageData( |
+ unsigned width, |
+ unsigned height, |
+ ImageDataColorSettings& color_settings, |
+ ExceptionState& exception_state) const { |
+ return ImageData::CreateImageData(width, height, color_settings, |
+ exception_state); |
+} |
+ |
+ImageData* BaseRenderingContext2D::createImageData( |
+ ImageDataArray& data_array, |
+ unsigned width, |
+ unsigned height, |
+ ExceptionState& exception_state) const { |
+ ImageDataColorSettings color_settings; |
+ return ImageData::CreateImageData(data_array, width, height, color_settings, |
+ exception_state); |
+} |
+ |
+ImageData* BaseRenderingContext2D::createImageData( |
+ ImageDataArray& data_array, |
+ unsigned width, |
+ unsigned height, |
+ ImageDataColorSettings& color_settings, |
+ ExceptionState& exception_state) const { |
+ return ImageData::CreateImageData(data_array, width, height, color_settings, |
+ exception_state); |
+} |
+ |
ImageData* BaseRenderingContext2D::getImageData( |
int sx, |
int sy, |
@@ -1598,8 +1653,14 @@ ImageData* BaseRenderingContext2D::getImageData( |
IntRect image_data_rect(sx, sy, sw, sh); |
ImageBuffer* buffer = GetImageBuffer(); |
+ ImageDataColorSettings color_settings = |
+ GetColorSettingsAsImageDataColorSettings(); |
if (!buffer || isContextLost()) { |
- ImageData* result = ImageData::Create(image_data_rect.Size()); |
+ ImageData* result = nullptr; |
+ if (color_management_enabled_) |
+ result = ImageData::Create(image_data_rect.Size(), &color_settings); |
+ else |
+ result = ImageData::Create(image_data_rect.Size()); |
if (!result) |
exception_state.ThrowRangeError("Out of memory at ImageData creation"); |
return result; |
@@ -1613,11 +1674,22 @@ ImageData* BaseRenderingContext2D::getImageData( |
NeedsFinalizeFrame(); |
- DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents); |
- return ImageData::Create( |
- image_data_rect.Size(), |
- NotShared<DOMUint8ClampedArray>(DOMUint8ClampedArray::Create( |
- array_buffer, 0, array_buffer->ByteLength()))); |
+ if (!color_management_enabled_) { |
+ DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents); |
+ return ImageData::Create( |
+ image_data_rect.Size(), |
+ NotShared<DOMUint8ClampedArray>(DOMUint8ClampedArray::Create( |
+ array_buffer, 0, array_buffer->ByteLength()))); |
+ } |
+ |
+ ImageDataStorageFormat storage_format = |
+ ImageData::GetImageDataStorageFormat(color_settings.storageFormat()); |
+ DOMArrayBufferView* array_buffer_view = |
+ ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( |
+ contents, PixelFormat(), storage_format); |
+ return ImageData::Create(image_data_rect.Size(), |
+ NotShared<DOMArrayBufferView>(array_buffer_view), |
+ &color_settings); |
} |
void BaseRenderingContext2D::putImageData(ImageData* data, |
@@ -1639,14 +1711,15 @@ void BaseRenderingContext2D::putImageData(ImageData* data, |
if (!WTF::CheckMul(dirty_width, dirty_height).IsValid<int>()) { |
return; |
} |
- |
usage_counters_.num_put_image_data_calls++; |
usage_counters_.area_put_image_data_calls += dirty_width * dirty_height; |
- if (data->data()->BufferBase()->IsNeutered()) { |
+ |
+ if (data->BufferBase()->IsNeutered()) { |
exception_state.ThrowDOMException(kInvalidStateError, |
"The source data has been neutered."); |
return; |
} |
+ |
ImageBuffer* buffer = GetImageBuffer(); |
if (!buffer) |
return; |
@@ -1696,10 +1769,22 @@ void BaseRenderingContext2D::putImageData(ImageData* data, |
CheckOverdraw(dest_rect, 0, CanvasRenderingContext2DState::kNoImage, |
kUntransformedUnclippedFill); |
- buffer->PutByteArray(kUnmultiplied, data->data()->Data(), |
- IntSize(data->width(), data->height()), source_rect, |
- IntPoint(dest_offset)); |
- |
+ if (color_management_enabled_) { |
+ unsigned data_length = data->width() * data->height() * 4; |
+ if (PixelFormat() == kF16CanvasPixelFormat) |
+ data_length *= 2; |
+ std::unique_ptr<uint8_t[]> converted_pixels(new uint8_t[data_length]); |
+ data->ImageDataInCanvasColorSettings(ColorSpace(), PixelFormat(), |
+ converted_pixels); |
+ |
+ buffer->PutByteArray(kUnmultiplied, converted_pixels.get(), |
+ IntSize(data->width(), data->height()), source_rect, |
+ IntPoint(dest_offset)); |
+ } else { |
+ buffer->PutByteArray(kUnmultiplied, data->data()->Data(), |
+ IntSize(data->width(), data->height()), source_rect, |
+ IntPoint(dest_offset)); |
+ } |
DidDraw(dest_rect); |
} |