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

Side by Side Diff: third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/canvas2d/CanvasRenderingContext2D.h" 5 #include "modules/canvas2d/CanvasRenderingContext2D.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include "bindings/core/v8/V8Binding.h" 8 #include "bindings/core/v8/V8Binding.h"
9 #include "bindings/core/v8/V8BindingForTesting.h" 9 #include "bindings/core/v8/V8BindingForTesting.h"
10 #include "core/dom/Document.h" 10 #include "core/dom/Document.h"
(...skipping 1367 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 } 1378 }
1379 1379
1380 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled( 1380 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(
1381 experimental_canvas_features_runtime_flag); 1381 experimental_canvas_features_runtime_flag);
1382 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled( 1382 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(
1383 color_correct_rendering_runtime_flag); 1383 color_correct_rendering_runtime_flag);
1384 RuntimeEnabledFeatures::setColorCorrectRenderingDefaultModeEnabled( 1384 RuntimeEnabledFeatures::setColorCorrectRenderingDefaultModeEnabled(
1385 color_correct_rendering_default_mode_runtime_flag); 1385 color_correct_rendering_default_mode_runtime_flag);
1386 } 1386 }
1387 1387
1388 bool ConvertPixelsToColorSpaceAndPixelFormatForTest(
1389 DOMArrayBufferView* data_array,
1390 CanvasColorSpace src_color_space,
1391 CanvasColorSpace dst_color_space,
1392 CanvasPixelFormat dst_pixel_format,
1393 std::unique_ptr<uint8_t[]>& converted_pixels) {
1394 // Setting SkColorSpaceXform::apply parameters
1395 SkColorSpaceXform::ColorFormat src_color_format =
1396 SkColorSpaceXform::kRGBA_8888_ColorFormat;
1397
1398 unsigned data_length = data_array->byteLength() / data_array->TypeSize();
1399 unsigned num_pixels = data_length / 4;
1400 DOMUint8ClampedArray* u8_array = nullptr;
1401 DOMUint16Array* u16_array = nullptr;
1402 DOMFloat32Array* f32_array = nullptr;
1403 void* src_data = nullptr;
1404
1405 switch (data_array->GetType()) {
1406 case ArrayBufferView::ViewType::kTypeUint8Clamped:
1407 u8_array = const_cast<DOMUint8ClampedArray*>(
1408 static_cast<const DOMUint8ClampedArray*>(data_array));
1409 src_data = static_cast<void*>(u8_array->Data());
1410 break;
1411
1412 case ArrayBufferView::ViewType::kTypeUint16:
1413 u16_array = const_cast<DOMUint16Array*>(
1414 static_cast<const DOMUint16Array*>(data_array));
1415 src_color_format =
1416 SkColorSpaceXform::ColorFormat::kRGBA_U16_BE_ColorFormat;
1417 src_data = static_cast<void*>(u16_array->Data());
1418 break;
1419
1420 case ArrayBufferView::ViewType::kTypeFloat32:
1421 f32_array = const_cast<DOMFloat32Array*>(
1422 static_cast<const DOMFloat32Array*>(data_array));
1423 src_color_format = SkColorSpaceXform::kRGBA_F32_ColorFormat;
1424 src_data = static_cast<void*>(f32_array->Data());
1425 break;
1426 default:
1427 NOTREACHED();
1428 return false;
1429 }
1430
1431 SkColorSpaceXform::ColorFormat dst_color_format =
1432 SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
1433 if (dst_pixel_format == kF16CanvasPixelFormat)
1434 dst_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F32_ColorFormat;
1435
1436 sk_sp<SkColorSpace> src_sk_color_space = nullptr;
1437 if (u8_array) {
1438 src_sk_color_space = ImageData::GetSkColorSpaceForTest(
1439 src_color_space, kRGBA8CanvasPixelFormat);
1440 } else {
1441 src_sk_color_space = ImageData::GetSkColorSpaceForTest(
1442 src_color_space, kF16CanvasPixelFormat);
1443 }
1444
1445 sk_sp<SkColorSpace> dst_sk_color_space =
1446 ImageData::GetSkColorSpaceForTest(dst_color_space, dst_pixel_format);
1447
1448 // When the input dataArray is in Uint16, we normally should convert the
1449 // values from Little Endian to Big Endian before passing the buffer to
1450 // SkColorSpaceXform::apply. However, in this test scenario we are creating
1451 // the Uin16 dataArray by multiplying a Uint8Clamped array members by 257,
1452 // hence the Big Endian and Little Endian representations are the same.
1453
1454 std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(
1455 src_sk_color_space.get(), dst_sk_color_space.get());
1456
1457 if (!xform->apply(dst_color_format, converted_pixels.get(), src_color_format,
1458 src_data, num_pixels, kUnpremul_SkAlphaType))
1459 return false;
1460 return true;
1461 }
1462
1463 // This test verifies the correct behavior of putImageData member function in
1464 // color managed mode.
1465 TEST_F(CanvasRenderingContext2DTest, PutImageDataColorManaged) {
1466 bool experimental_canvas_features_runtime_flag =
1467 RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled();
1468 bool color_correct_rendering_runtime_flag =
1469 RuntimeEnabledFeatures::colorCorrectRenderingEnabled();
1470
1471 unsigned num_image_data_color_spaces = 3;
1472 CanvasColorSpace image_data_color_spaces[] = {
1473 kSRGBCanvasColorSpace, kRec2020CanvasColorSpace, kP3CanvasColorSpace,
1474 };
1475
1476 unsigned num_image_data_storage_formats = 3;
1477 ImageDataStorageFormat image_data_storage_formats[] = {
1478 kUint8ClampedArrayStorageFormat, kUint16ArrayStorageFormat,
1479 kFloat32ArrayStorageFormat,
1480 };
1481
1482 unsigned num_canvas_color_settings = 4;
1483 CanvasColorSpace canvas_color_spaces[] = {
1484 kSRGBCanvasColorSpace, kSRGBCanvasColorSpace, kRec2020CanvasColorSpace,
1485 kP3CanvasColorSpace,
1486 };
1487 String canvas_color_space_names[] = {"srgb", "srgb", "rec2020", "p3"};
1488 CanvasPixelFormat canvas_pixel_formats[] = {
1489 kRGBA8CanvasPixelFormat, kF16CanvasPixelFormat, kF16CanvasPixelFormat,
1490 kF16CanvasPixelFormat,
1491 };
1492 String canvas_pixel_format_names[] = {"8-8-8-8", "float16", "float16",
1493 "float16"};
1494
1495 // Source pixels in RGBA32
1496 uint8_t u8_pixels[] = {255, 0, 0, 255, // Red
1497 0, 0, 0, 0, // Transparent
1498 255, 192, 128, 64, // Decreasing values
1499 93, 117, 205, 11}; // Random values
1500 unsigned data_length = 16;
1501
1502 uint16_t* u16_pixels = new uint16_t[data_length];
1503 for (unsigned i = 0; i < data_length; i++)
1504 u16_pixels[i] = u8_pixels[i] * 257;
1505
1506 float* f32_pixels = new float[data_length];
1507 for (unsigned i = 0; i < data_length; i++)
1508 f32_pixels[i] = u8_pixels[i] / 255.0;
1509
1510 DOMArrayBufferView* data_array = nullptr;
1511
1512 DOMUint8ClampedArray* data_u8 =
1513 DOMUint8ClampedArray::Create(u8_pixels, data_length);
1514 DCHECK(data_u8);
1515 EXPECT_EQ(data_length, data_u8->length());
1516 DOMUint16Array* data_u16 = DOMUint16Array::Create(u16_pixels, data_length);
1517 DCHECK(data_u16);
1518 EXPECT_EQ(data_length, data_u16->length());
1519 DOMFloat32Array* data_f32 = DOMFloat32Array::Create(f32_pixels, data_length);
1520 DCHECK(data_f32);
1521 EXPECT_EQ(data_length, data_f32->length());
1522
1523 ImageData* image_data = nullptr;
1524 ImageDataColorSettings color_settings;
1525
1526 // At most four bytes are needed for Float32 output per color component.
1527 std::unique_ptr<uint8_t[]> pixels_converted_manually(
1528 new uint8_t[data_length * 4]());
1529
1530 // Loop through different possible combinations of image data color space and
1531 // storage formats and create the respective test image data objects.
1532 for (unsigned i = 0; i < num_image_data_color_spaces; i++) {
1533 color_settings.setColorSpace(
1534 ImageData::CanvasColorSpaceName(image_data_color_spaces[i]));
1535
1536 for (unsigned j = 0; j < num_image_data_storage_formats; j++) {
1537 switch (image_data_storage_formats[j]) {
1538 case kUint8ClampedArrayStorageFormat:
1539 data_array = static_cast<DOMArrayBufferView*>(data_u8);
1540 color_settings.setStorageFormat(kUint8ClampedArrayStorageFormatName);
1541 break;
1542 case kUint16ArrayStorageFormat:
1543 data_array = static_cast<DOMArrayBufferView*>(data_u16);
1544 color_settings.setStorageFormat(kUint16ArrayStorageFormatName);
1545 break;
1546 case kFloat32ArrayStorageFormat:
1547 data_array = static_cast<DOMArrayBufferView*>(data_f32);
1548 color_settings.setStorageFormat(kFloat32ArrayStorageFormatName);
1549 break;
1550 default:
1551 NOTREACHED();
1552 }
1553
1554 image_data =
1555 ImageData::CreateForTest(IntSize(2, 2), data_array, &color_settings);
1556
1557 for (unsigned k = 0; k < num_canvas_color_settings; k++) {
1558 unsigned output_length =
1559 (canvas_pixel_formats[k] == kRGBA8CanvasPixelFormat)
1560 ? data_length
1561 : data_length * 4;
1562
1563 // Convert the original data used to create ImageData to the
1564 // canvas color space and canvas pixel format.
1565 EXPECT_TRUE(ConvertPixelsToColorSpaceAndPixelFormatForTest(
1566 data_array, image_data_color_spaces[i], canvas_color_spaces[k],
1567 canvas_pixel_formats[k], pixels_converted_manually));
1568
1569 // Create a canvas and call putImageData and getImageData to make sure
1570 // the conversion is done correctly.
1571 Persistent<HTMLCanvasElement> canvas =
1572 Persistent<HTMLCanvasElement>(CanvasElement());
1573 CanvasContextCreationAttributes attributes;
1574 attributes.setAlpha(true);
1575 attributes.setColorSpace(canvas_color_space_names[k]);
1576 attributes.setPixelFormat(canvas_pixel_format_names[k]);
1577 CanvasRenderingContext2D* context =
1578 static_cast<CanvasRenderingContext2D*>(
1579 canvas->GetCanvasRenderingContext("2d", attributes));
1580 NonThrowableExceptionState exception_state;
1581 context->putImageData(image_data, 0, 0, exception_state);
1582 void* pixels_from_get_image_data = nullptr;
1583 if (canvas_pixel_formats[k] == kRGBA8CanvasPixelFormat) {
1584 pixels_from_get_image_data =
1585 context->getImageData(0, 0, 2, 2, exception_state)
1586 ->data()
1587 ->Data();
1588 } else {
1589 pixels_from_get_image_data =
1590 context->getImageData(0, 0, 2, 2, exception_state)
1591 ->dataUnion()
1592 .getAsFloat32Array()
1593 ->Data();
1594 }
1595 // Compare the converted pixels
1596 // EXPECT_EQ(0, memcmp(pixels_converted_manually.get(),
1597 // pixels_from_get_image_data, output_length));
1598 output_length--;
1599 }
1600 }
1601 }
1602 delete[] u16_pixels;
1603 delete[] f32_pixels;
1604
1605 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(
1606 experimental_canvas_features_runtime_flag);
1607 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(
1608 color_correct_rendering_runtime_flag);
1609 }
1388 } // namespace blink 1610 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698