Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Unified Diff: third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp

Issue 2797213002: Fix BaseRenderingContext2D create/put/get-ImageData() for color managed canvas (Closed)
Patch Set: Fixing more interface listings fails Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 9653160eccf6da95850252b47b4b17683b287e83..efe91b9f0e761ed79b3a0cf083c89c6b967d6cbf 100644
--- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -36,8 +36,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() {}
@@ -1506,10 +1509,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;
@@ -1527,13 +1546,39 @@ 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,
+ 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,
@@ -1596,8 +1641,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;
@@ -1611,10 +1662,20 @@ ImageData* BaseRenderingContext2D::getImageData(
NeedsFinalizeFrame();
- DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents);
- return ImageData::Create(image_data_rect.size(),
- DOMUint8ClampedArray::Create(
- array_buffer, 0, array_buffer->ByteLength()));
+ if (!color_management_enabled_ ||
+ ImageData::GetImageDataStorageFormat(color_settings.storageFormat()) ==
+ kUint8ClampedArrayStorageFormat) {
+ DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents);
+ return ImageData::Create(image_data_rect.size(),
+ DOMUint8ClampedArray::Create(
+ array_buffer, 0, array_buffer->ByteLength()));
+ }
+
+ DOMArrayBufferView* array_buffer_view =
+ ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
+ contents, PixelFormat(), kFloat32ArrayStorageFormat);
+ return ImageData::Create(image_data_rect.size(), array_buffer_view,
+ &color_settings);
}
void BaseRenderingContext2D::putImageData(ImageData* data,
@@ -1636,14 +1697,30 @@ 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()) {
+
+ bool data_is_neutered = false;
+ if (color_management_enabled_) {
+ data_is_neutered =
+ (data->dataUnion().isUint8ClampedArray() &&
Justin Novosad 2017/04/11 21:28:05 This block of code is not fun to read. Let's hide
zakerinasab 2017/04/15 07:04:42 Done.
+ data->dataUnion()
+ .getAsUint8ClampedArray()
+ ->BufferBase()
+ ->IsNeutered()) ||
+ (data->dataUnion().isUint16Array() &&
+ data->dataUnion().getAsUint16Array()->BufferBase()->IsNeutered()) ||
+ (data->dataUnion().isFloat32Array() &&
+ data->dataUnion().getAsFloat32Array()->BufferBase()->IsNeutered());
+ } else {
+ data_is_neutered = data->data()->BufferBase()->IsNeutered();
+ }
+ if (data_is_neutered) {
exception_state.ThrowDOMException(kInvalidStateError,
"The source data has been neutered.");
return;
}
+
ImageBuffer* buffer = GetImageBuffer();
if (!buffer)
return;
@@ -1693,10 +1770,21 @@ 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();
+ if (PixelFormat() == kF16CanvasPixelFormat)
+ data_length *= 2;
+ std::unique_ptr<uint8_t[]> converted_pixels(new uint8_t[4 * 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);
}

Powered by Google App Engine
This is Rietveld 408576698