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

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: Rebaseline 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..e9f188fa5d5a22508c33e02580be0dfb2849da65 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), is_color_managed_(false) {
state_stack_.push_back(CanvasRenderingContext2DState::Create());
+ is_color_managed_ =
fserb 2017/04/11 03:21:44 a RenderingContext is color managed even if it has
zakerinasab 2017/04/11 19:52:59 Done.
+ RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() &&
+ RuntimeEnabledFeatures::colorCorrectRenderingEnabled();
}
BaseRenderingContext2D::~BaseRenderingContext2D() {}
@@ -1506,10 +1509,38 @@ bool BaseRenderingContext2D::ComputeDirtyRect(
return true;
}
+bool BaseRenderingContext2D::ColorSettingsAsImageDataColorSettings(
+ ImageDataColorSettings& color_settings) const {
fserb 2017/04/11 03:21:44 maybe ImageDataColorSettings* ?
zakerinasab 2017/04/11 19:52:59 Rewritten.
+ if (!is_color_managed_)
+ return false;
+ color_settings.setColorSpace(ColorSpaceAsString());
+ switch (PixelFormat()) {
+ case kRGBA8CanvasPixelFormat:
+ color_settings.setStorageFormat(kUint8ClampedArrayStorageFormatName);
+ break;
+ case kF16CanvasPixelFormat:
+ color_settings.setStorageFormat(kFloat32ArrayStorageFormatName);
+ break;
+ case kRGB10A2CanvasPixelFormat:
+ case kRGBA12CanvasPixelFormat:
+ default:
+ NOTREACHED();
+ return false;
+ }
+ return true;
+}
+
ImageData* BaseRenderingContext2D::createImageData(
ImageData* image_data,
ExceptionState& exception_state) const {
- ImageData* result = ImageData::Create(image_data->size());
+ ImageData* result = nullptr;
+ if (is_color_managed_) {
+ ImageDataColorSettings color_settings;
+ if (ColorSettingsAsImageDataColorSettings(color_settings))
+ 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,8 +1558,15 @@ ImageData* BaseRenderingContext2D::createImageData(
}
IntSize size(abs(sw), abs(sh));
+ ImageData* result = nullptr;
+ if (is_color_managed_) {
+ ImageDataColorSettings color_settings;
+ if (ColorSettingsAsImageDataColorSettings(color_settings))
+ 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;
@@ -1594,10 +1632,21 @@ ImageData* BaseRenderingContext2D::getImageData(
timer.emplace(scoped_us_counter_cpu);
}
+ ImageDataColorSettings color_settings;
+ bool valid_color_settings = false;
+ if (is_color_managed_) {
+ valid_color_settings =
fserb 2017/04/11 03:21:44 just use is_color_managed_?
zakerinasab 2017/04/11 19:52:59 Done.
+ ColorSettingsAsImageDataColorSettings(color_settings);
+ }
IntRect image_data_rect(sx, sy, sw, sh);
+ DVLOG(1) << sx << ", " << sy << ", " << sw << ", " << sh;
fserb 2017/04/11 03:21:44 ^^^^
zakerinasab 2017/04/11 19:52:59 Removed, but it's funny that I don't remember putt
ImageBuffer* buffer = GetImageBuffer();
if (!buffer || isContextLost()) {
- ImageData* result = ImageData::Create(image_data_rect.size());
+ ImageData* result = nullptr;
+ if (valid_color_settings)
+ 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,7 +1660,39 @@ ImageData* BaseRenderingContext2D::getImageData(
NeedsFinalizeFrame();
- DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents);
+ DOMArrayBuffer* array_buffer = nullptr;
+ DOMArrayBufferView* array_buffer_view = nullptr;
+ DOMFloat32Array* data_array = nullptr;
+
+ if (is_color_managed_) {
+ ImageDataStorageFormat storage_format =
+ ImageData::GetImageDataStorageFormat(color_settings.storageFormat());
+ switch (storage_format) {
fserb 2017/04/11 03:21:44 this code is looking weird. I'm Assuming is_color_
zakerinasab 2017/04/11 19:52:59 Simplified.
+ case kUint8ClampedArrayStorageFormat:
+ array_buffer = DOMArrayBuffer::Create(contents);
+ return ImageData::Create(
+ image_data_rect.size(),
+ DOMUint8ClampedArray::Create(array_buffer, 0,
+ array_buffer->ByteLength()));
+ break;
+ case kUint16ArrayStorageFormat:
+ NOTREACHED();
+ break;
+ case kFloat32ArrayStorageFormat:
+ array_buffer_view = ImageData::
+ ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
+ contents, PixelFormat(), storage_format);
+ data_array = const_cast<DOMFloat32Array*>(
+ static_cast<const DOMFloat32Array*>(array_buffer_view));
+ return ImageData::Create(image_data_rect.size(), array_buffer_view,
+ &color_settings);
+ default:
+ NOTREACHED();
+ }
+ return nullptr;
+ }
+
+ array_buffer = DOMArrayBuffer::Create(contents);
return ImageData::Create(image_data_rect.size(),
DOMUint8ClampedArray::Create(
array_buffer, 0, array_buffer->ByteLength()));
@@ -1636,14 +1717,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 (is_color_managed_) {
fserb 2017/04/11 03:21:44 again, if this is an experimental flag thingy, I'd
zakerinasab 2017/04/11 19:52:59 You mean if(original_check) {something} else {chec
+ data_is_neutered =
+ (data->dataUnion().isUint8ClampedArray() &&
+ 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 +1790,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 (is_color_managed_) {
+ unsigned data_length = data->width() * data->height();
fserb 2017/04/11 03:21:44 name the type?
zakerinasab 2017/04/11 19:52:59 ?
+ 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