| OLD | NEW |
| 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 "content/browser/compositor/delegated_frame_host.h" | 5 #include "content/browser/compositor/delegated_frame_host.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "cc/output/compositor_frame.h" | 9 #include "cc/output/compositor_frame.h" |
| 10 #include "cc/output/compositor_frame_ack.h" | 10 #include "cc/output/compositor_frame_ack.h" |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 else | 136 else |
| 137 request->SendEmptyResult(); | 137 request->SendEmptyResult(); |
| 138 } else { | 138 } else { |
| 139 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); | 139 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); |
| 140 } | 140 } |
| 141 } | 141 } |
| 142 | 142 |
| 143 void DelegatedFrameHost::CopyFromCompositingSurface( | 143 void DelegatedFrameHost::CopyFromCompositingSurface( |
| 144 const gfx::Rect& src_subrect, | 144 const gfx::Rect& src_subrect, |
| 145 const gfx::Size& output_size, | 145 const gfx::Size& output_size, |
| 146 CopyFromCompositingSurfaceCallback& callback, | 146 ReadbackRequestCallback& callback, |
| 147 const SkColorType color_type) { | 147 const SkColorType color_type) { |
| 148 // Only ARGB888 and RGB565 supported as of now. | 148 // Only ARGB888 and RGB565 supported as of now. |
| 149 bool format_support = ((color_type == kAlpha_8_SkColorType) || | 149 bool format_support = ((color_type == kAlpha_8_SkColorType) || |
| 150 (color_type == kRGB_565_SkColorType) || | 150 (color_type == kRGB_565_SkColorType) || |
| 151 (color_type == kN32_SkColorType)); | 151 (color_type == kN32_SkColorType)); |
| 152 DCHECK(format_support); | 152 DCHECK(format_support); |
| 153 if (!CanCopyToBitmap()) { | 153 if (!CanCopyToBitmap()) { |
| 154 callback.Run(false, SkBitmap()); | 154 callback.Run(SkBitmap(), content::READBACK_SURFACE_UNAVAILABLE); |
| 155 return; | 155 return; |
| 156 } | 156 } |
| 157 | 157 |
| 158 scoped_ptr<cc::CopyOutputRequest> request = | 158 scoped_ptr<cc::CopyOutputRequest> request = |
| 159 cc::CopyOutputRequest::CreateRequest(base::Bind( | 159 cc::CopyOutputRequest::CreateRequest(base::Bind( |
| 160 &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, | 160 &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, |
| 161 output_size, | 161 output_size, |
| 162 color_type, | 162 color_type, |
| 163 callback)); | 163 callback)); |
| 164 request->set_area(src_subrect); | 164 request->set_area(src_subrect); |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 surface_factory_->Destroy(surface_id_); | 533 surface_factory_->Destroy(surface_id_); |
| 534 surface_id_ = cc::SurfaceId(); | 534 surface_id_ = cc::SurfaceId(); |
| 535 } | 535 } |
| 536 delegated_frame_evictor_->DiscardedFrame(); | 536 delegated_frame_evictor_->DiscardedFrame(); |
| 537 } | 537 } |
| 538 | 538 |
| 539 // static | 539 // static |
| 540 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( | 540 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( |
| 541 const gfx::Size& dst_size_in_pixel, | 541 const gfx::Size& dst_size_in_pixel, |
| 542 const SkColorType color_type, | 542 const SkColorType color_type, |
| 543 const base::Callback<void(bool, const SkBitmap&)>& callback, | 543 ReadbackRequestCallback& callback, |
| 544 scoped_ptr<cc::CopyOutputResult> result) { | 544 scoped_ptr<cc::CopyOutputResult> result) { |
| 545 if (result->IsEmpty() || result->size().IsEmpty()) { | 545 if (result->IsEmpty() || result->size().IsEmpty()) { |
| 546 callback.Run(false, SkBitmap()); | 546 callback.Run(SkBitmap(), content::READBACK_FAILED); |
| 547 return; | 547 return; |
| 548 } | 548 } |
| 549 | 549 |
| 550 if (result->HasTexture()) { | 550 if (result->HasTexture()) { |
| 551 // GPU-accelerated path | 551 // GPU-accelerated path |
| 552 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, | 552 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, |
| 553 callback, | 553 callback, |
| 554 result.Pass()); | 554 result.Pass()); |
| 555 return; | 555 return; |
| 556 } | 556 } |
| 557 | 557 |
| 558 DCHECK(result->HasBitmap()); | 558 DCHECK(result->HasBitmap()); |
| 559 // Software path | 559 // Software path |
| 560 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, | 560 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, |
| 561 result.Pass()); | 561 result.Pass()); |
| 562 } | 562 } |
| 563 | 563 |
| 564 static void CopyFromCompositingSurfaceFinished( | 564 static void CopyFromCompositingSurfaceFinished( |
| 565 const base::Callback<void(bool, const SkBitmap&)>& callback, | 565 ReadbackRequestCallback& callback, |
| 566 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 566 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
| 567 scoped_ptr<SkBitmap> bitmap, | 567 scoped_ptr<SkBitmap> bitmap, |
| 568 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, | 568 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, |
| 569 bool result) { | 569 bool result) { |
| 570 bitmap_pixels_lock.reset(); | 570 bitmap_pixels_lock.reset(); |
| 571 | 571 |
| 572 uint32 sync_point = 0; | 572 uint32 sync_point = 0; |
| 573 if (result) { | 573 if (result) { |
| 574 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); | 574 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); |
| 575 sync_point = gl_helper->InsertSyncPoint(); | 575 sync_point = gl_helper->InsertSyncPoint(); |
| 576 } | 576 } |
| 577 bool lost_resource = sync_point == 0; | 577 bool lost_resource = sync_point == 0; |
| 578 release_callback->Run(sync_point, lost_resource); | 578 release_callback->Run(sync_point, lost_resource); |
| 579 | 579 |
| 580 callback.Run(result, *bitmap); | 580 callback.Run(*bitmap, content::READBACK_SUCCESS); |
| 581 } | 581 } |
| 582 | 582 |
| 583 // static | 583 // static |
| 584 void DelegatedFrameHost::PrepareTextureCopyOutputResult( | 584 void DelegatedFrameHost::PrepareTextureCopyOutputResult( |
| 585 const gfx::Size& dst_size_in_pixel, | 585 const gfx::Size& dst_size_in_pixel, |
| 586 const SkColorType color_type, | 586 const SkColorType color_type, |
| 587 const base::Callback<void(bool, const SkBitmap&)>& callback, | 587 ReadbackRequestCallback& callback, |
| 588 scoped_ptr<cc::CopyOutputResult> result) { | 588 scoped_ptr<cc::CopyOutputResult> result) { |
| 589 DCHECK(result->HasTexture()); | 589 DCHECK(result->HasTexture()); |
| 590 base::ScopedClosureRunner scoped_callback_runner( | 590 base::ScopedClosureRunner scoped_callback_runner( |
| 591 base::Bind(callback, false, SkBitmap())); | 591 base::Bind(callback, SkBitmap(), content::READBACK_FAILED)); |
| 592 | 592 |
| 593 // TODO(sikugu): We should be able to validate the format here using | 593 // TODO(sikugu): We should be able to validate the format here using |
| 594 // GLHelper::IsReadbackConfigSupported before we processs the result. | 594 // GLHelper::IsReadbackConfigSupported before we processs the result. |
| 595 // See crbug.com/415682. | 595 // See crbug.com/415682. |
| 596 scoped_ptr<SkBitmap> bitmap(new SkBitmap); | 596 scoped_ptr<SkBitmap> bitmap(new SkBitmap); |
| 597 if (!bitmap->tryAllocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), | 597 if (!bitmap->tryAllocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), |
| 598 dst_size_in_pixel.height(), | 598 dst_size_in_pixel.height(), |
| 599 color_type, | 599 color_type, |
| 600 kOpaque_SkAlphaType))) | 600 kOpaque_SkAlphaType))) |
| 601 return; | 601 return; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 629 base::Passed(&release_callback), | 629 base::Passed(&release_callback), |
| 630 base::Passed(&bitmap), | 630 base::Passed(&bitmap), |
| 631 base::Passed(&bitmap_pixels_lock)), | 631 base::Passed(&bitmap_pixels_lock)), |
| 632 GLHelper::SCALER_QUALITY_FAST); | 632 GLHelper::SCALER_QUALITY_FAST); |
| 633 } | 633 } |
| 634 | 634 |
| 635 // static | 635 // static |
| 636 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( | 636 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( |
| 637 const gfx::Size& dst_size_in_pixel, | 637 const gfx::Size& dst_size_in_pixel, |
| 638 const SkColorType color_type, | 638 const SkColorType color_type, |
| 639 const base::Callback<void(bool, const SkBitmap&)>& callback, | 639 ReadbackRequestCallback& callback, |
| 640 scoped_ptr<cc::CopyOutputResult> result) { | 640 scoped_ptr<cc::CopyOutputResult> result) { |
| 641 if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) { | 641 if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) { |
| 642 NOTIMPLEMENTED(); | 642 NOTIMPLEMENTED(); |
| 643 callback.Run(false, SkBitmap()); | 643 callback.Run(SkBitmap(), READBACK_FORMAT_NOT_SUPPORTED); |
| 644 return; | 644 return; |
| 645 } | 645 } |
| 646 DCHECK(result->HasBitmap()); | 646 DCHECK(result->HasBitmap()); |
| 647 scoped_ptr<SkBitmap> source = result->TakeBitmap(); | 647 scoped_ptr<SkBitmap> source = result->TakeBitmap(); |
| 648 DCHECK(source); | 648 DCHECK(source); |
| 649 SkBitmap scaled_bitmap; | 649 SkBitmap scaled_bitmap; |
| 650 if (source->width() != dst_size_in_pixel.width() || | 650 if (source->width() != dst_size_in_pixel.width() || |
| 651 source->height() != dst_size_in_pixel.height()) { | 651 source->height() != dst_size_in_pixel.height()) { |
| 652 scaled_bitmap = | 652 scaled_bitmap = |
| 653 skia::ImageOperations::Resize(*source, | 653 skia::ImageOperations::Resize(*source, |
| 654 skia::ImageOperations::RESIZE_BEST, | 654 skia::ImageOperations::RESIZE_BEST, |
| 655 dst_size_in_pixel.width(), | 655 dst_size_in_pixel.width(), |
| 656 dst_size_in_pixel.height()); | 656 dst_size_in_pixel.height()); |
| 657 } else { | 657 } else { |
| 658 scaled_bitmap = *source; | 658 scaled_bitmap = *source; |
| 659 } | 659 } |
| 660 if (color_type == kN32_SkColorType) { | 660 if (color_type == kN32_SkColorType) { |
| 661 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); | 661 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); |
| 662 callback.Run(true, scaled_bitmap); | 662 callback.Run(scaled_bitmap, READBACK_SUCCESS); |
| 663 return; | 663 return; |
| 664 } | 664 } |
| 665 DCHECK_EQ(color_type, kAlpha_8_SkColorType); | 665 DCHECK_EQ(color_type, kAlpha_8_SkColorType); |
| 666 // The software path currently always returns N32 bitmap regardless of the | 666 // The software path currently always returns N32 bitmap regardless of the |
| 667 // |color_type| we ask for. | 667 // |color_type| we ask for. |
| 668 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); | 668 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); |
| 669 // Paint |scaledBitmap| to alpha-only |grayscale_bitmap|. | 669 // Paint |scaledBitmap| to alpha-only |grayscale_bitmap|. |
| 670 SkBitmap grayscale_bitmap; | 670 SkBitmap grayscale_bitmap; |
| 671 bool success = grayscale_bitmap.tryAllocPixels( | 671 bool success = grayscale_bitmap.tryAllocPixels( |
| 672 SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height())); | 672 SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height())); |
| 673 if (!success) { | 673 if (!success) { |
| 674 callback.Run(false, SkBitmap()); | 674 callback.Run(SkBitmap(), content::READBACK_MEMORY_ALLOCATION_FAILURE); |
| 675 return; | 675 return; |
| 676 } | 676 } |
| 677 SkCanvas canvas(grayscale_bitmap); | 677 SkCanvas canvas(grayscale_bitmap); |
| 678 SkPaint paint; | 678 SkPaint paint; |
| 679 skia::RefPtr<SkColorFilter> filter = | 679 skia::RefPtr<SkColorFilter> filter = |
| 680 skia::AdoptRef(SkLumaColorFilter::Create()); | 680 skia::AdoptRef(SkLumaColorFilter::Create()); |
| 681 paint.setColorFilter(filter.get()); | 681 paint.setColorFilter(filter.get()); |
| 682 canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); | 682 canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); |
| 683 callback.Run(true, grayscale_bitmap); | 683 callback.Run(grayscale_bitmap, READBACK_SUCCESS); |
| 684 } | 684 } |
| 685 | 685 |
| 686 // static | 686 // static |
| 687 void DelegatedFrameHost::ReturnSubscriberTexture( | 687 void DelegatedFrameHost::ReturnSubscriberTexture( |
| 688 base::WeakPtr<DelegatedFrameHost> dfh, | 688 base::WeakPtr<DelegatedFrameHost> dfh, |
| 689 scoped_refptr<OwnedMailbox> subscriber_texture, | 689 scoped_refptr<OwnedMailbox> subscriber_texture, |
| 690 uint32 sync_point) { | 690 uint32 sync_point) { |
| 691 if (!subscriber_texture.get()) | 691 if (!subscriber_texture.get()) |
| 692 return; | 692 return; |
| 693 if (!dfh) | 693 if (!dfh) |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 if (frame_provider_.get()) { | 996 if (frame_provider_.get()) { |
| 997 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 997 new_layer->SetShowDelegatedContent(frame_provider_.get(), |
| 998 current_frame_size_in_dip_); | 998 current_frame_size_in_dip_); |
| 999 } | 999 } |
| 1000 if (!surface_id_.is_null()) { | 1000 if (!surface_id_.is_null()) { |
| 1001 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); | 1001 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); |
| 1002 } | 1002 } |
| 1003 } | 1003 } |
| 1004 | 1004 |
| 1005 } // namespace content | 1005 } // namespace content |
| OLD | NEW |