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

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: Layout test added 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 e7f9f3bfe590b13529a01cfe7c89a7f8c9b4eff0..ef14d6bd566625d46c4e7952b526f7bdf9422565 100644
--- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -1496,10 +1496,40 @@ bool BaseRenderingContext2D::computeDirtyRect(
return true;
}
+bool BaseRenderingContext2D::colorSettingsAsImageDataColorSettings(
+ ImageDataColorSettings& colorSettings) const {
+ if (!RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() ||
+ !RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
+ return false;
+ colorSettings.setColorSpace(renderingContext()->colorSpaceAsString());
+ switch (renderingContext()->pixelFormat()) {
+ case kRGBA8CanvasPixelFormat:
+ colorSettings.setStorageFormat(kUint8ClampedArrayStorageFormatName);
+ break;
+ case kF16CanvasPixelFormat:
+ colorSettings.setStorageFormat(kFloat32ArrayStorageFormatName);
+ break;
+ case kRGB10A2CanvasPixelFormat:
+ case kRGBA12CanvasPixelFormat:
+ default:
+ NOTREACHED();
+ return false;
+ }
+ return true;
+}
+
ImageData* BaseRenderingContext2D::createImageData(
ImageData* imageData,
ExceptionState& exceptionState) const {
- ImageData* result = ImageData::create(imageData->size());
+ ImageData* result = nullptr;
+ if (RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() &&
+ RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) {
+ ImageDataColorSettings colorSettings;
+ if (colorSettingsAsImageDataColorSettings(colorSettings))
+ result = ImageData::create(imageData->size(), &colorSettings);
+ } else {
+ result = ImageData::create(imageData->size());
+ }
if (!result)
exceptionState.throwRangeError("Out of memory at ImageData creation");
return result;
@@ -1517,8 +1547,15 @@ ImageData* BaseRenderingContext2D::createImageData(
}
IntSize size(abs(sw), abs(sh));
-
- ImageData* result = ImageData::create(size);
+ ImageData* result = nullptr;
+ if (RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() &&
+ RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) {
+ ImageDataColorSettings colorSettings;
+ if (colorSettingsAsImageDataColorSettings(colorSettings))
+ result = ImageData::create(size, &colorSettings);
+ } else {
+ result = ImageData::create(size);
+ }
if (!result)
exceptionState.throwRangeError("Out of memory at ImageData creation");
return result;
@@ -1573,11 +1610,21 @@ ImageData* BaseRenderingContext2D::getImageData(
timer.emplace(scopedUsCounterCPU);
}
+ ImageDataColorSettings colorSettings;
+ bool canvasIsColorManaged =
+ RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() &&
+ RuntimeEnabledFeatures::colorCorrectRenderingEnabled();
+ if (canvasIsColorManaged)
+ canvasIsColorManaged = colorSettingsAsImageDataColorSettings(colorSettings);
IntRect imageDataRect(sx, sy, sw, sh);
DVLOG(1) << sx << ", " << sy << ", " << sw << ", " << sh;
ImageBuffer* buffer = imageBuffer();
if (!buffer || isContextLost()) {
- ImageData* result = ImageData::create(imageDataRect.size());
+ ImageData* result = nullptr;
+ if (canvasIsColorManaged)
+ result = ImageData::create(imageDataRect.size(), &colorSettings);
+ else
+ result = ImageData::create(imageDataRect.size());
if (!result)
exceptionState.throwRangeError("Out of memory at ImageData creation");
return result;
@@ -1589,7 +1636,39 @@ ImageData* BaseRenderingContext2D::getImageData(
return nullptr;
}
- DOMArrayBuffer* arrayBuffer = DOMArrayBuffer::create(contents);
+ DOMArrayBuffer* arrayBuffer = nullptr;
+ DOMArrayBufferView* arrayBufferView = nullptr;
+ DOMFloat32Array* dataArray = nullptr;
+
+ if (canvasIsColorManaged) {
+ ImageDataStorageFormat storageFormat =
+ ImageData::imageDataStorageFormat(colorSettings.storageFormat());
+ switch (storageFormat) {
+ case kUint8ClampedArrayStorageFormat:
+ arrayBuffer = DOMArrayBuffer::create(contents);
+ return ImageData::create(
+ imageDataRect.size(),
+ DOMUint8ClampedArray::create(arrayBuffer, 0,
+ arrayBuffer->byteLength()));
+ break;
+ case kUint16ArrayStorageFormat:
+ NOTREACHED();
+ break;
+ case kFloat32ArrayStorageFormat:
+ arrayBufferView = ImageData::
+ convertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
+ contents, renderingContext()->pixelFormat(), storageFormat);
+ dataArray = const_cast<DOMFloat32Array*>(
+ static_cast<const DOMFloat32Array*>(arrayBufferView));
+ return ImageData::create(imageDataRect.size(), arrayBufferView,
+ &colorSettings);
+ default:
+ NOTREACHED();
+ }
+ return nullptr;
+ }
+
+ arrayBuffer = DOMArrayBuffer::create(contents);
return ImageData::create(
imageDataRect.size(),
DOMUint8ClampedArray::create(arrayBuffer, 0, arrayBuffer->byteLength()));
@@ -1613,11 +1692,32 @@ void BaseRenderingContext2D::putImageData(ImageData* data,
ExceptionState& exceptionState) {
m_usageCounters.numPutImageDataCalls++;
m_usageCounters.areaPutImageDataCalls += dirtyWidth * dirtyHeight;
- if (data->data()->bufferBase()->isNeutered()) {
+
+ bool canvasIsColorManaged =
+ RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() &&
+ RuntimeEnabledFeatures::colorCorrectRenderingEnabled();
Justin Novosad 2017/04/06 19:01:04 This check is copied in many placed, perhaps we co
zakerinasab 2017/04/11 19:52:59 Done.
+
+ bool dataIsNeutered = false;
+ if (canvasIsColorManaged) {
+ dataIsNeutered =
+ (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 {
+ dataIsNeutered = data->data()->bufferBase()->isNeutered();
+ }
+ if (dataIsNeutered) {
exceptionState.throwDOMException(InvalidStateError,
"The source data has been neutered.");
return;
}
+
ImageBuffer* buffer = imageBuffer();
if (!buffer)
return;
@@ -1667,10 +1767,23 @@ void BaseRenderingContext2D::putImageData(ImageData* data,
checkOverdraw(destRect, 0, CanvasRenderingContext2DState::NoImage,
UntransformedUnclippedFill);
- buffer->putByteArray(Unmultiplied, data->data()->data(),
- IntSize(data->width(), data->height()), sourceRect,
- IntPoint(destOffset));
-
+ if (RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() &&
+ RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) {
+ unsigned dataLength = data->width() * data->height();
+ if (renderingContext()->pixelFormat() == kF16CanvasPixelFormat)
+ dataLength *= 2;
+ std::unique_ptr<uint8_t[]> convertedPixels(new uint8_t[4 * dataLength]);
+ data->imageDataInCanvasColorSettings(renderingContext()->colorSpace(),
+ renderingContext()->pixelFormat(),
+ convertedPixels);
+ buffer->putByteArray(Unmultiplied, convertedPixels.get(),
+ IntSize(data->width(), data->height()), sourceRect,
+ IntPoint(destOffset));
+ } else {
+ buffer->putByteArray(Unmultiplied, data->data()->data(),
+ IntSize(data->width(), data->height()), sourceRect,
+ IntPoint(destOffset));
+ }
didDraw(destRect);
}

Powered by Google App Engine
This is Rietveld 408576698