| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |