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

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

Issue 2825183002: Plumb CanvasColorParams to canvas image classes (Closed)
Patch Set: Require both runtime flags 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 /* 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 std::unique_ptr<ImageBufferSurface> surface) { 73 std::unique_ptr<ImageBufferSurface> surface) {
74 if (!surface->IsValid()) 74 if (!surface->IsValid())
75 return nullptr; 75 return nullptr;
76 return WTF::WrapUnique(new ImageBuffer(std::move(surface))); 76 return WTF::WrapUnique(new ImageBuffer(std::move(surface)));
77 } 77 }
78 78
79 std::unique_ptr<ImageBuffer> ImageBuffer::Create( 79 std::unique_ptr<ImageBuffer> ImageBuffer::Create(
80 const IntSize& size, 80 const IntSize& size,
81 OpacityMode opacity_mode, 81 OpacityMode opacity_mode,
82 ImageInitializationMode initialization_mode, 82 ImageInitializationMode initialization_mode,
83 sk_sp<SkColorSpace> color_space) { 83 const CanvasColorParams& color_params) {
84 SkColorType color_type = kN32_SkColorType;
85 if (color_space && SkColorSpace::Equals(color_space.get(),
86 SkColorSpace::MakeSRGBLinear().get()))
87 color_type = kRGBA_F16_SkColorType;
88
89 std::unique_ptr<ImageBufferSurface> surface( 84 std::unique_ptr<ImageBufferSurface> surface(
90 WTF::WrapUnique(new UnacceleratedImageBufferSurface( 85 WTF::WrapUnique(new UnacceleratedImageBufferSurface(
91 size, opacity_mode, initialization_mode, std::move(color_space), 86 size, opacity_mode, initialization_mode, color_params)));
92 color_type)));
93 87
94 if (!surface->IsValid()) 88 if (!surface->IsValid())
95 return nullptr; 89 return nullptr;
96 return WTF::WrapUnique(new ImageBuffer(std::move(surface))); 90 return WTF::WrapUnique(new ImageBuffer(std::move(surface)));
97 } 91 }
98 92
99 ImageBuffer::ImageBuffer(std::unique_ptr<ImageBufferSurface> surface) 93 ImageBuffer::ImageBuffer(std::unique_ptr<ImageBufferSurface> surface)
100 : weak_ptr_factory_(this), 94 : weak_ptr_factory_(this),
101 snapshot_state_(kInitialSnapshotState), 95 snapshot_state_(kInitialSnapshotState),
102 surface_(std::move(surface)), 96 surface_(std::move(surface)),
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 341
348 void ImageBuffer::FlushGpu(FlushReason reason) { 342 void ImageBuffer::FlushGpu(FlushReason reason) {
349 if (surface_->Canvas()) { 343 if (surface_->Canvas()) {
350 surface_->FlushGpu(reason); 344 surface_->FlushGpu(reason);
351 } 345 }
352 } 346 }
353 347
354 bool ImageBuffer::GetImageData(Multiply multiplied, 348 bool ImageBuffer::GetImageData(Multiply multiplied,
355 const IntRect& rect, 349 const IntRect& rect,
356 WTF::ArrayBufferContents& contents) const { 350 WTF::ArrayBufferContents& contents) const {
357 uint8_t bytes_per_pixel = 4; 351 uint8_t bytes_per_pixel = surface_->color_params().BytesPerPixel();
358 if (surface_->ColorSpace())
359 bytes_per_pixel = SkColorTypeBytesPerPixel(surface_->ColorType());
360 CheckedNumeric<int> data_size = bytes_per_pixel; 352 CheckedNumeric<int> data_size = bytes_per_pixel;
361 data_size *= rect.Width(); 353 data_size *= rect.Width();
362 data_size *= rect.Height(); 354 data_size *= rect.Height();
363 if (!data_size.IsValid()) 355 if (!data_size.IsValid())
364 return false; 356 return false;
365 357
366 if (!IsSurfaceValid()) { 358 if (!IsSurfaceValid()) {
367 size_t alloc_size_in_bytes = rect.Width() * rect.Height() * bytes_per_pixel; 359 size_t alloc_size_in_bytes = rect.Width() * rect.Height() * bytes_per_pixel;
368 auto data = WTF::ArrayBufferContents::CreateDataHandle( 360 auto data = WTF::ArrayBufferContents::CreateDataHandle(
369 alloc_size_in_bytes, WTF::ArrayBufferContents::kZeroInitialize); 361 alloc_size_in_bytes, WTF::ArrayBufferContents::kZeroInitialize);
(...skipping 22 matching lines...) Expand all
392 may_have_stray_area ? WTF::ArrayBufferContents::kZeroInitialize 384 may_have_stray_area ? WTF::ArrayBufferContents::kZeroInitialize
393 : WTF::ArrayBufferContents::kDontInitialize; 385 : WTF::ArrayBufferContents::kDontInitialize;
394 auto data = WTF::ArrayBufferContents::CreateDataHandle(alloc_size_in_bytes, 386 auto data = WTF::ArrayBufferContents::CreateDataHandle(alloc_size_in_bytes,
395 initialization_policy); 387 initialization_policy);
396 if (!data) 388 if (!data)
397 return false; 389 return false;
398 WTF::ArrayBufferContents result(std::move(data), alloc_size_in_bytes, 390 WTF::ArrayBufferContents result(std::move(data), alloc_size_in_bytes,
399 WTF::ArrayBufferContents::kNotShared); 391 WTF::ArrayBufferContents::kNotShared);
400 392
401 // Skia does not support unpremultiplied read with an F16 to 8888 conversion 393 // Skia does not support unpremultiplied read with an F16 to 8888 conversion
402 bool use_f16_workaround = surface_->ColorType() == kRGBA_F16_SkColorType; 394 bool use_f16_workaround =
395 surface_->color_params().GetSkColorType() == kRGBA_F16_SkColorType;
403 396
404 SkAlphaType alpha_type = (multiplied == kPremultiplied || use_f16_workaround) 397 SkAlphaType alpha_type = (multiplied == kPremultiplied || use_f16_workaround)
405 ? kPremul_SkAlphaType 398 ? kPremul_SkAlphaType
406 : kUnpremul_SkAlphaType; 399 : kUnpremul_SkAlphaType;
407 // The workaround path use a canvas draw under the hood, which can only 400 // The workaround path use a canvas draw under the hood, which can only
408 // use N32 at this time. 401 // use N32 at this time.
409 SkColorType color_type = 402 SkColorType color_type =
410 use_f16_workaround ? kN32_SkColorType : kRGBA_8888_SkColorType; 403 use_f16_workaround ? kN32_SkColorType : kRGBA_8888_SkColorType;
411 404
412 // Only use sRGB when the surface has a color space. Converting untagged 405 // Only use sRGB when the surface has a color space. Converting untagged
413 // pixels to a particular color space is not well-defined in Skia. 406 // pixels to a particular color space is not well-defined in Skia.
414 sk_sp<SkColorSpace> color_space = nullptr; 407 sk_sp<SkColorSpace> color_space =
415 if (surface_->ColorSpace()) { 408 surface_->color_params().GetSkColorSpaceForSkSurfaces();
416 color_space = SkColorSpace::MakeSRGB();
417 }
418 409
419 SkImageInfo info = SkImageInfo::Make(rect.Width(), rect.Height(), color_type, 410 SkImageInfo info = SkImageInfo::Make(rect.Width(), rect.Height(), color_type,
420 alpha_type, std::move(color_space)); 411 alpha_type, std::move(color_space));
421 412
422 snapshot->readPixels(info, result.Data(), bytes_per_pixel * rect.Width(), 413 snapshot->readPixels(info, result.Data(), bytes_per_pixel * rect.Width(),
423 rect.X(), rect.Y()); 414 rect.X(), rect.Y());
424 gpu_readback_invoked_in_current_frame_ = true; 415 gpu_readback_invoked_in_current_frame_ = true;
425 416
426 if (use_f16_workaround) { 417 if (use_f16_workaround) {
427 uint32_t* pixel = (uint32_t*)result.Data(); 418 uint32_t* pixel = (uint32_t*)result.Data();
(...skipping 20 matching lines...) Expand all
448 return true; 439 return true;
449 } 440 }
450 441
451 void ImageBuffer::PutByteArray(Multiply multiplied, 442 void ImageBuffer::PutByteArray(Multiply multiplied,
452 const unsigned char* source, 443 const unsigned char* source,
453 const IntSize& source_size, 444 const IntSize& source_size,
454 const IntRect& source_rect, 445 const IntRect& source_rect,
455 const IntPoint& dest_point) { 446 const IntPoint& dest_point) {
456 if (!IsSurfaceValid()) 447 if (!IsSurfaceValid())
457 return; 448 return;
458 uint8_t bytes_per_pixel = 4; 449 uint8_t bytes_per_pixel = surface_->color_params().BytesPerPixel();
459 if (surface_->ColorSpace())
460 bytes_per_pixel = SkColorTypeBytesPerPixel(surface_->ColorType());
461 450
462 DCHECK_GT(source_rect.Width(), 0); 451 DCHECK_GT(source_rect.Width(), 0);
463 DCHECK_GT(source_rect.Height(), 0); 452 DCHECK_GT(source_rect.Height(), 0);
464 453
465 int origin_x = source_rect.X(); 454 int origin_x = source_rect.X();
466 int dest_x = dest_point.X() + source_rect.X(); 455 int dest_x = dest_point.X() + source_rect.X();
467 DCHECK_GE(dest_x, 0); 456 DCHECK_GE(dest_x, 0);
468 DCHECK_LT(dest_x, surface_->size().Width()); 457 DCHECK_LT(dest_x, surface_->size().Width());
469 DCHECK_GE(origin_x, 0); 458 DCHECK_GE(origin_x, 0);
470 DCHECK_LT(origin_x, source_rect.MaxX()); 459 DCHECK_LT(origin_x, source_rect.MaxX());
(...skipping 16 matching lines...) Expand all
487 // Skia. There is some discussion about whether it should be 476 // Skia. There is some discussion about whether it should be
488 // defined in skbug.com/6157. For now, we can get the desired 477 // defined in skbug.com/6157. For now, we can get the desired
489 // behavior (memcpy) by pretending the write is opaque. 478 // behavior (memcpy) by pretending the write is opaque.
490 alpha_type = kOpaque_SkAlphaType; 479 alpha_type = kOpaque_SkAlphaType;
491 } else { 480 } else {
492 alpha_type = (multiplied == kPremultiplied) ? kPremul_SkAlphaType 481 alpha_type = (multiplied == kPremultiplied) ? kPremul_SkAlphaType
493 : kUnpremul_SkAlphaType; 482 : kUnpremul_SkAlphaType;
494 } 483 }
495 484
496 SkImageInfo info; 485 SkImageInfo info;
497 if (surface_->ColorSpace()) { 486 if (surface_->color_params().GetSkColorSpaceForSkSurfaces()) {
498 info = SkImageInfo::Make(source_rect.Width(), source_rect.Height(), 487 info = SkImageInfo::Make(
499 surface_->ColorType(), alpha_type, 488 source_rect.Width(), source_rect.Height(),
500 surface_->ColorSpace()); 489 surface_->color_params().GetSkColorType(), alpha_type,
490 surface_->color_params().GetSkColorSpaceForSkSurfaces());
501 } else { 491 } else {
502 info = SkImageInfo::Make(source_rect.Width(), source_rect.Height(), 492 info = SkImageInfo::Make(source_rect.Width(), source_rect.Height(),
503 kRGBA_8888_SkColorType, alpha_type, 493 kRGBA_8888_SkColorType, alpha_type,
504 SkColorSpace::MakeSRGB()); 494 SkColorSpace::MakeSRGB());
505 } 495 }
506 surface_->WritePixels(info, src_addr, src_bytes_per_row, dest_x, dest_y); 496 surface_->WritePixels(info, src_addr, src_bytes_per_row, dest_x, dest_y);
507 } 497 }
508 498
509 void ImageBuffer::UpdateGPUMemoryUsage() const { 499 void ImageBuffer::UpdateGPUMemoryUsage() const {
510 if (this->IsAccelerated()) { 500 if (this->IsAccelerated()) {
511 // If image buffer is accelerated, we should keep track of GPU memory usage. 501 // If image buffer is accelerated, we should keep track of GPU memory usage.
512 int gpu_buffer_count = 2; 502 int gpu_buffer_count = 2;
513 CheckedNumeric<intptr_t> checked_gpu_usage = 503 CheckedNumeric<intptr_t> checked_gpu_usage =
514 SkColorTypeBytesPerPixel(surface_->ColorType()) * gpu_buffer_count; 504 surface_->color_params().BytesPerPixel() * gpu_buffer_count;
515 checked_gpu_usage *= this->size().Width(); 505 checked_gpu_usage *= this->size().Width();
516 checked_gpu_usage *= this->size().Height(); 506 checked_gpu_usage *= this->size().Height();
517 intptr_t gpu_memory_usage = 507 intptr_t gpu_memory_usage =
518 checked_gpu_usage.ValueOrDefault(std::numeric_limits<intptr_t>::max()); 508 checked_gpu_usage.ValueOrDefault(std::numeric_limits<intptr_t>::max());
519 509
520 if (!gpu_memory_usage_) // was not accelerated before 510 if (!gpu_memory_usage_) // was not accelerated before
521 global_accelerated_image_buffer_count_++; 511 global_accelerated_image_buffer_count_++;
522 512
523 global_gpu_memory_usage_ += (gpu_memory_usage - gpu_memory_usage_); 513 global_gpu_memory_usage_ += (gpu_memory_usage - gpu_memory_usage_);
524 gpu_memory_usage_ = gpu_memory_usage; 514 gpu_memory_usage_ = gpu_memory_usage;
(...skipping 11 matching lines...) Expand all
536 } 526 }
537 527
538 namespace { 528 namespace {
539 529
540 class UnacceleratedSurfaceFactory 530 class UnacceleratedSurfaceFactory
541 : public RecordingImageBufferFallbackSurfaceFactory { 531 : public RecordingImageBufferFallbackSurfaceFactory {
542 public: 532 public:
543 virtual std::unique_ptr<ImageBufferSurface> CreateSurface( 533 virtual std::unique_ptr<ImageBufferSurface> CreateSurface(
544 const IntSize& size, 534 const IntSize& size,
545 OpacityMode opacity_mode, 535 OpacityMode opacity_mode,
546 sk_sp<SkColorSpace> color_space, 536 const CanvasColorParams& color_params) {
547 SkColorType color_type) {
548 return WTF::WrapUnique(new UnacceleratedImageBufferSurface( 537 return WTF::WrapUnique(new UnacceleratedImageBufferSurface(
549 size, opacity_mode, kInitializeImagePixels, std::move(color_space), 538 size, opacity_mode, kInitializeImagePixels, color_params));
550 color_type));
551 } 539 }
552 540
553 virtual ~UnacceleratedSurfaceFactory() {} 541 virtual ~UnacceleratedSurfaceFactory() {}
554 }; 542 };
555 543
556 } // namespace 544 } // namespace
557 545
558 void ImageBuffer::DisableAcceleration() { 546 void ImageBuffer::DisableAcceleration() {
559 if (!IsAccelerated()) 547 if (!IsAccelerated())
560 return; 548 return;
561 549
562 // Create and configure a recording (unaccelerated) surface. 550 // Create and configure a recording (unaccelerated) surface.
563 std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> surface_factory = 551 std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> surface_factory =
564 WTF::MakeUnique<UnacceleratedSurfaceFactory>(); 552 WTF::MakeUnique<UnacceleratedSurfaceFactory>();
565 std::unique_ptr<ImageBufferSurface> surface = 553 std::unique_ptr<ImageBufferSurface> surface =
566 WTF::WrapUnique(new RecordingImageBufferSurface( 554 WTF::WrapUnique(new RecordingImageBufferSurface(
567 surface_->size(), std::move(surface_factory), 555 surface_->size(), std::move(surface_factory),
568 surface_->GetOpacityMode(), surface_->ColorSpace(), 556 surface_->GetOpacityMode(), surface_->color_params()));
569 surface_->ColorType()));
570 SetSurface(std::move(surface)); 557 SetSurface(std::move(surface));
571 } 558 }
572 559
573 void ImageBuffer::SetSurface(std::unique_ptr<ImageBufferSurface> surface) { 560 void ImageBuffer::SetSurface(std::unique_ptr<ImageBufferSurface> surface) {
574 sk_sp<SkImage> image = 561 sk_sp<SkImage> image =
575 surface_->NewImageSnapshot(kPreferNoAcceleration, kSnapshotReasonPaint); 562 surface_->NewImageSnapshot(kPreferNoAcceleration, kSnapshotReasonPaint);
576 563
577 // image can be null if alloaction failed in which case we should just 564 // image can be null if alloaction failed in which case we should just
578 // abort the surface switch to reatain the old surface which is still 565 // abort the surface switch to reatain the old surface which is still
579 // functional. 566 // functional.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 DCHECK(MIMETypeRegistry::IsSupportedImageMIMETypeForEncoding(mime_type)); 612 DCHECK(MIMETypeRegistry::IsSupportedImageMIMETypeForEncoding(mime_type));
626 613
627 Vector<unsigned char> result; 614 Vector<unsigned char> result;
628 if (!EncodeImage(mime_type, quality, &result)) 615 if (!EncodeImage(mime_type, quality, &result))
629 return "data:,"; 616 return "data:,";
630 617
631 return "data:" + mime_type + ";base64," + Base64Encode(result); 618 return "data:" + mime_type + ";base64," + Base64Encode(result);
632 } 619 }
633 620
634 } // namespace blink 621 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698