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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp

Issue 2630563003: Fix ImageBitmap constructor from ImageData to consider the color space tags (Closed)
Patch Set: Rebaseline Created 3 years, 11 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
« no previous file with comments | « third_party/WebKit/Source/core/html/ImageData.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2008, Google Inc. All rights reserved. 2 * Copyright (c) 2008, Google Inc. All rights reserved.
3 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 3 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are 7 * modification, are permitted provided that the following conditions are
8 * met: 8 * met:
9 * 9 *
10 * * Redistributions of source code must retain the above copyright 10 * * Redistributions of source code must retain the above copyright
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 if (!surface->isValid()) 73 if (!surface->isValid())
74 return nullptr; 74 return nullptr;
75 return WTF::wrapUnique(new ImageBuffer(std::move(surface))); 75 return WTF::wrapUnique(new ImageBuffer(std::move(surface)));
76 } 76 }
77 77
78 std::unique_ptr<ImageBuffer> ImageBuffer::create( 78 std::unique_ptr<ImageBuffer> ImageBuffer::create(
79 const IntSize& size, 79 const IntSize& size,
80 OpacityMode opacityMode, 80 OpacityMode opacityMode,
81 ImageInitializationMode initializationMode, 81 ImageInitializationMode initializationMode,
82 sk_sp<SkColorSpace> colorSpace) { 82 sk_sp<SkColorSpace> colorSpace) {
83 std::unique_ptr<ImageBufferSurface> surface( 83 SkColorType colorType = kN32_SkColorType;
84 WTF::wrapUnique(new UnacceleratedImageBufferSurface( 84 if (colorSpace &&
85 size, opacityMode, initializationMode, std::move(colorSpace)))); 85 SkColorSpace::Equals(
86 colorSpace.get(),
87 SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named).get()))
88 colorType = kRGBA_F16_SkColorType;
89
90 std::unique_ptr<ImageBufferSurface> surface(WTF::wrapUnique(
91 new UnacceleratedImageBufferSurface(size, opacityMode, initializationMode,
92 std::move(colorSpace), colorType)));
93
86 if (!surface->isValid()) 94 if (!surface->isValid())
87 return nullptr; 95 return nullptr;
88 return WTF::wrapUnique(new ImageBuffer(std::move(surface))); 96 return WTF::wrapUnique(new ImageBuffer(std::move(surface)));
89 } 97 }
90 98
91 ImageBuffer::ImageBuffer(std::unique_ptr<ImageBufferSurface> surface) 99 ImageBuffer::ImageBuffer(std::unique_ptr<ImageBufferSurface> surface)
92 : m_weakPtrFactory(this), 100 : m_weakPtrFactory(this),
93 m_snapshotState(InitialSnapshotState), 101 m_snapshotState(InitialSnapshotState),
94 m_surface(std::move(surface)), 102 m_surface(std::move(surface)),
95 m_client(0), 103 m_client(0),
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 336
329 void ImageBuffer::flushGpu(FlushReason reason) { 337 void ImageBuffer::flushGpu(FlushReason reason) {
330 if (m_surface->canvas()) { 338 if (m_surface->canvas()) {
331 m_surface->flushGpu(reason); 339 m_surface->flushGpu(reason);
332 } 340 }
333 } 341 }
334 342
335 bool ImageBuffer::getImageData(Multiply multiplied, 343 bool ImageBuffer::getImageData(Multiply multiplied,
336 const IntRect& rect, 344 const IntRect& rect,
337 WTF::ArrayBufferContents& contents) const { 345 WTF::ArrayBufferContents& contents) const {
338 CheckedNumeric<int> dataSize = 4; 346 uint8_t bytesPerPixel = 4;
347 if (m_surface->colorSpace())
348 bytesPerPixel = SkColorTypeBytesPerPixel(m_surface->colorType());
349 CheckedNumeric<int> dataSize = bytesPerPixel;
339 dataSize *= rect.width(); 350 dataSize *= rect.width();
340 dataSize *= rect.height(); 351 dataSize *= rect.height();
341 if (!dataSize.IsValid()) 352 if (!dataSize.IsValid())
342 return false; 353 return false;
343 354
344 if (!isSurfaceValid()) { 355 if (!isSurfaceValid()) {
345 size_t allocSizeInBytes = rect.width() * rect.height() * 4; 356 size_t allocSizeInBytes = rect.width() * rect.height() * bytesPerPixel;
346 void* data; 357 void* data;
347 WTF::ArrayBufferContents::allocateMemoryOrNull( 358 WTF::ArrayBufferContents::allocateMemoryOrNull(
348 allocSizeInBytes, WTF::ArrayBufferContents::ZeroInitialize, data); 359 allocSizeInBytes, WTF::ArrayBufferContents::ZeroInitialize, data);
349 if (!data) 360 if (!data)
350 return false; 361 return false;
351 WTF::ArrayBufferContents result(data, allocSizeInBytes, 362 WTF::ArrayBufferContents result(data, allocSizeInBytes,
352 WTF::ArrayBufferContents::NotShared); 363 WTF::ArrayBufferContents::NotShared);
353 result.transfer(contents); 364 result.transfer(contents);
354 return true; 365 return true;
355 } 366 }
356 367
357 DCHECK(canvas()); 368 DCHECK(canvas());
358 369
359 if (ExpensiveCanvasHeuristicParameters::GetImageDataForcesNoAcceleration && 370 if (ExpensiveCanvasHeuristicParameters::GetImageDataForcesNoAcceleration &&
360 !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled()) { 371 !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled()) {
361 const_cast<ImageBuffer*>(this)->disableAcceleration(); 372 const_cast<ImageBuffer*>(this)->disableAcceleration();
362 } 373 }
363 374
364 sk_sp<SkImage> snapshot = m_surface->newImageSnapshot( 375 sk_sp<SkImage> snapshot = m_surface->newImageSnapshot(
365 PreferNoAcceleration, SnapshotReasonGetImageData); 376 PreferNoAcceleration, SnapshotReasonGetImageData);
366 if (!snapshot) 377 if (!snapshot)
367 return false; 378 return false;
368 379
369 const bool mayHaveStrayArea = 380 const bool mayHaveStrayArea =
370 m_surface->isAccelerated() // GPU readback may fail silently 381 m_surface->isAccelerated() // GPU readback may fail silently
371 || rect.x() < 0 || rect.y() < 0 || 382 || rect.x() < 0 || rect.y() < 0 ||
372 rect.maxX() > m_surface->size().width() || 383 rect.maxX() > m_surface->size().width() ||
373 rect.maxY() > m_surface->size().height(); 384 rect.maxY() > m_surface->size().height();
374 size_t allocSizeInBytes = rect.width() * rect.height() * 4; 385 size_t allocSizeInBytes = rect.width() * rect.height() * bytesPerPixel;
375 void* data; 386 void* data;
376 WTF::ArrayBufferContents::InitializationPolicy initializationPolicy = 387 WTF::ArrayBufferContents::InitializationPolicy initializationPolicy =
377 mayHaveStrayArea ? WTF::ArrayBufferContents::ZeroInitialize 388 mayHaveStrayArea ? WTF::ArrayBufferContents::ZeroInitialize
378 : WTF::ArrayBufferContents::DontInitialize; 389 : WTF::ArrayBufferContents::DontInitialize;
379 WTF::ArrayBufferContents::allocateMemoryOrNull(allocSizeInBytes, 390 WTF::ArrayBufferContents::allocateMemoryOrNull(allocSizeInBytes,
380 initializationPolicy, data); 391 initializationPolicy, data);
381 if (!data) 392 if (!data)
382 return false; 393 return false;
383 WTF::ArrayBufferContents result(data, allocSizeInBytes, 394 WTF::ArrayBufferContents result(data, allocSizeInBytes,
384 WTF::ArrayBufferContents::NotShared); 395 WTF::ArrayBufferContents::NotShared);
385 396
386 // Skia does not support unpremultiplied read with an F16 to 8888 conversion 397 // Skia does not support unpremultiplied read with an F16 to 8888 conversion
387 bool useF16Workaround = m_surface->colorType() == kRGBA_F16_SkColorType; 398 bool useF16Workaround = m_surface->colorType() == kRGBA_F16_SkColorType;
388 399
389 SkAlphaType alphaType = (multiplied == Premultiplied || useF16Workaround) 400 SkAlphaType alphaType = (multiplied == Premultiplied || useF16Workaround)
390 ? kPremul_SkAlphaType 401 ? kPremul_SkAlphaType
391 : kUnpremul_SkAlphaType; 402 : kUnpremul_SkAlphaType;
392 // The workaround path use a canvas draw under the hood, which can only 403 // The workaround path use a canvas draw under the hood, which can only
393 // use N32 at this time. 404 // use N32 at this time.
394 SkColorType colorType = 405 SkColorType colorType =
395 useF16Workaround ? kN32_SkColorType : kRGBA_8888_SkColorType; 406 useF16Workaround ? kN32_SkColorType : kRGBA_8888_SkColorType;
396 SkImageInfo info = 407 SkImageInfo info =
397 SkImageInfo::Make(rect.width(), rect.height(), colorType, alphaType, 408 SkImageInfo::Make(rect.width(), rect.height(), colorType, alphaType,
398 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); 409 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named));
399 410
400 snapshot->readPixels(info, result.data(), 4 * rect.width(), rect.x(), 411 snapshot->readPixels(info, result.data(), bytesPerPixel * rect.width(),
401 rect.y()); 412 rect.x(), rect.y());
402 413
403 if (useF16Workaround) { 414 if (useF16Workaround) {
404 uint32_t* pixel = (uint32_t*)result.data(); 415 uint32_t* pixel = (uint32_t*)result.data();
405 size_t pixelCount = allocSizeInBytes / sizeof(uint32_t); 416 size_t pixelCount = allocSizeInBytes / sizeof(uint32_t);
406 // TODO(skbug.com/5853): make readPixels support RGBA output so that we no 417 // TODO(skbug.com/5853): make readPixels support RGBA output so that we no
407 // longer 418 // longer
408 // have to do this. 419 // have to do this.
409 if (kN32_SkColorType == kBGRA_8888_SkColorType) { 420 if (kN32_SkColorType == kBGRA_8888_SkColorType) {
410 // Convert BGRA to RGBA if necessary on this platform. 421 // Convert BGRA to RGBA if necessary on this platform.
411 SkSwapRB(pixel, pixel, pixelCount); 422 SkSwapRB(pixel, pixel, pixelCount);
(...skipping 13 matching lines...) Expand all
425 return true; 436 return true;
426 } 437 }
427 438
428 void ImageBuffer::putByteArray(Multiply multiplied, 439 void ImageBuffer::putByteArray(Multiply multiplied,
429 const unsigned char* source, 440 const unsigned char* source,
430 const IntSize& sourceSize, 441 const IntSize& sourceSize,
431 const IntRect& sourceRect, 442 const IntRect& sourceRect,
432 const IntPoint& destPoint) { 443 const IntPoint& destPoint) {
433 if (!isSurfaceValid()) 444 if (!isSurfaceValid())
434 return; 445 return;
446 uint8_t bytesPerPixel = 4;
447 if (m_surface->colorSpace())
448 bytesPerPixel = SkColorTypeBytesPerPixel(m_surface->colorType());
435 449
436 DCHECK_GT(sourceRect.width(), 0); 450 DCHECK_GT(sourceRect.width(), 0);
437 DCHECK_GT(sourceRect.height(), 0); 451 DCHECK_GT(sourceRect.height(), 0);
438 452
439 int originX = sourceRect.x(); 453 int originX = sourceRect.x();
440 int destX = destPoint.x() + sourceRect.x(); 454 int destX = destPoint.x() + sourceRect.x();
441 DCHECK_GE(destX, 0); 455 DCHECK_GE(destX, 0);
442 DCHECK_LT(destX, m_surface->size().width()); 456 DCHECK_LT(destX, m_surface->size().width());
443 DCHECK_GE(originX, 0); 457 DCHECK_GE(originX, 0);
444 DCHECK_LT(originX, sourceRect.maxX()); 458 DCHECK_LT(originX, sourceRect.maxX());
445 459
446 int originY = sourceRect.y(); 460 int originY = sourceRect.y();
447 int destY = destPoint.y() + sourceRect.y(); 461 int destY = destPoint.y() + sourceRect.y();
448 DCHECK_GE(destY, 0); 462 DCHECK_GE(destY, 0);
449 DCHECK_LT(destY, m_surface->size().height()); 463 DCHECK_LT(destY, m_surface->size().height());
450 DCHECK_GE(originY, 0); 464 DCHECK_GE(originY, 0);
451 DCHECK_LT(originY, sourceRect.maxY()); 465 DCHECK_LT(originY, sourceRect.maxY());
452 466
453 const size_t srcBytesPerRow = 4 * sourceSize.width(); 467 const size_t srcBytesPerRow = bytesPerPixel * sourceSize.width();
454 const void* srcAddr = source + originY * srcBytesPerRow + originX * 4; 468 const void* srcAddr =
469 source + originY * srcBytesPerRow + originX * bytesPerPixel;
455 SkAlphaType alphaType = (multiplied == Premultiplied) ? kPremul_SkAlphaType 470 SkAlphaType alphaType = (multiplied == Premultiplied) ? kPremul_SkAlphaType
456 : kUnpremul_SkAlphaType; 471 : kUnpremul_SkAlphaType;
457 SkImageInfo info = SkImageInfo::Make( 472 SkImageInfo info;
458 sourceRect.width(), sourceRect.height(), kRGBA_8888_SkColorType, 473 if (m_surface->colorSpace()) {
459 alphaType, SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); 474 info = SkImageInfo::Make(sourceRect.width(), sourceRect.height(),
460 475 m_surface->colorType(), alphaType,
476 m_surface->colorSpace());
477 } else {
478 info = SkImageInfo::Make(
479 sourceRect.width(), sourceRect.height(), kRGBA_8888_SkColorType,
480 alphaType, SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named));
481 }
461 m_surface->writePixels(info, srcAddr, srcBytesPerRow, destX, destY); 482 m_surface->writePixels(info, srcAddr, srcBytesPerRow, destX, destY);
462 } 483 }
463 484
464 void ImageBuffer::updateGPUMemoryUsage() const { 485 void ImageBuffer::updateGPUMemoryUsage() const {
465 if (this->isAccelerated()) { 486 if (this->isAccelerated()) {
466 // If image buffer is accelerated, we should keep track of GPU memory usage. 487 // If image buffer is accelerated, we should keep track of GPU memory usage.
467 int gpuBufferCount = 2; 488 int gpuBufferCount = 2;
468 CheckedNumeric<intptr_t> checkedGPUUsage = 4 * gpuBufferCount; 489 CheckedNumeric<intptr_t> checkedGPUUsage =
490 SkColorTypeBytesPerPixel(m_surface->colorType()) * gpuBufferCount;
469 checkedGPUUsage *= this->size().width(); 491 checkedGPUUsage *= this->size().width();
470 checkedGPUUsage *= this->size().height(); 492 checkedGPUUsage *= this->size().height();
471 intptr_t gpuMemoryUsage = 493 intptr_t gpuMemoryUsage =
472 checkedGPUUsage.ValueOrDefault(std::numeric_limits<intptr_t>::max()); 494 checkedGPUUsage.ValueOrDefault(std::numeric_limits<intptr_t>::max());
473 495
474 if (!m_gpuMemoryUsage) // was not accelerated before 496 if (!m_gpuMemoryUsage) // was not accelerated before
475 s_globalAcceleratedImageBufferCount++; 497 s_globalAcceleratedImageBufferCount++;
476 498
477 s_globalGPUMemoryUsage += (gpuMemoryUsage - m_gpuMemoryUsage); 499 s_globalGPUMemoryUsage += (gpuMemoryUsage - m_gpuMemoryUsage);
478 m_gpuMemoryUsage = gpuMemoryUsage; 500 m_gpuMemoryUsage = gpuMemoryUsage;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 void ImageBuffer::disableAcceleration() { 534 void ImageBuffer::disableAcceleration() {
513 if (!isAccelerated()) 535 if (!isAccelerated())
514 return; 536 return;
515 537
516 // Create and configure a recording (unaccelerated) surface. 538 // Create and configure a recording (unaccelerated) surface.
517 std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> surfaceFactory = 539 std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> surfaceFactory =
518 WTF::makeUnique<UnacceleratedSurfaceFactory>(); 540 WTF::makeUnique<UnacceleratedSurfaceFactory>();
519 std::unique_ptr<ImageBufferSurface> surface = 541 std::unique_ptr<ImageBufferSurface> surface =
520 WTF::wrapUnique(new RecordingImageBufferSurface( 542 WTF::wrapUnique(new RecordingImageBufferSurface(
521 m_surface->size(), std::move(surfaceFactory), 543 m_surface->size(), std::move(surfaceFactory),
522 m_surface->getOpacityMode(), m_surface->colorSpace())); 544 m_surface->getOpacityMode(), m_surface->colorSpace(),
545 m_surface->colorType()));
523 setSurface(std::move(surface)); 546 setSurface(std::move(surface));
524 } 547 }
525 548
526 void ImageBuffer::setSurface(std::unique_ptr<ImageBufferSurface> surface) { 549 void ImageBuffer::setSurface(std::unique_ptr<ImageBufferSurface> surface) {
527 sk_sp<SkImage> image = 550 sk_sp<SkImage> image =
528 m_surface->newImageSnapshot(PreferNoAcceleration, SnapshotReasonPaint); 551 m_surface->newImageSnapshot(PreferNoAcceleration, SnapshotReasonPaint);
529 552
530 if (surface->isRecording()) { 553 if (surface->isRecording()) {
531 // Using a GPU-backed image with RecordingImageBufferSurface 554 // Using a GPU-backed image with RecordingImageBufferSurface
532 // will fail at playback time. 555 // will fail at playback time.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 DCHECK(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); 591 DCHECK(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
569 592
570 Vector<unsigned char> result; 593 Vector<unsigned char> result;
571 if (!encodeImage(mimeType, quality, &result)) 594 if (!encodeImage(mimeType, quality, &result))
572 return "data:,"; 595 return "data:,";
573 596
574 return "data:" + mimeType + ";base64," + base64Encode(result); 597 return "data:" + mimeType + ";base64," + base64Encode(result);
575 } 598 }
576 599
577 } // namespace blink 600 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/ImageData.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698