Chromium Code Reviews| 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 } | 153 } |
| 154 | 154 |
| 155 void DelegatedFrameHost::RequestCopyOfOutput( | 155 void DelegatedFrameHost::RequestCopyOfOutput( |
| 156 scoped_ptr<cc::CopyOutputRequest> request) { | 156 scoped_ptr<cc::CopyOutputRequest> request) { |
| 157 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); | 157 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); |
| 158 } | 158 } |
| 159 | 159 |
| 160 void DelegatedFrameHost::CopyFromCompositingSurface( | 160 void DelegatedFrameHost::CopyFromCompositingSurface( |
| 161 const gfx::Rect& src_subrect, | 161 const gfx::Rect& src_subrect, |
| 162 const gfx::Size& output_size, | 162 const gfx::Size& output_size, |
| 163 CopyFromCompositingSurfaceCallback& callback, | 163 ReadbackRequestCallback& callback, |
| 164 const SkColorType color_type) { | 164 const SkColorType color_type) { |
| 165 // Only ARGB888 and RGB565 supported as of now. | 165 // Only ARGB888 and RGB565 supported as of now. |
| 166 bool format_support = ((color_type == kAlpha_8_SkColorType) || | 166 bool format_support = ((color_type == kAlpha_8_SkColorType) || |
| 167 (color_type == kRGB_565_SkColorType) || | 167 (color_type == kRGB_565_SkColorType) || |
| 168 (color_type == kN32_SkColorType)); | 168 (color_type == kN32_SkColorType)); |
| 169 DCHECK(format_support); | 169 DCHECK(format_support); |
| 170 if (!CanCopyToBitmap()) { | 170 if (!CanCopyToBitmap()) { |
| 171 callback.Run(false, SkBitmap()); | 171 callback.Run(SkBitmap(), content::READBACK_SURFACE_UNAVAILABLE); |
| 172 return; | 172 return; |
| 173 } | 173 } |
| 174 | 174 |
| 175 scoped_ptr<cc::CopyOutputRequest> request = | 175 scoped_ptr<cc::CopyOutputRequest> request = |
| 176 cc::CopyOutputRequest::CreateRequest(base::Bind( | 176 cc::CopyOutputRequest::CreateRequest(base::Bind( |
| 177 &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, | 177 &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, |
| 178 output_size, | 178 output_size, |
| 179 color_type, | 179 color_type, |
| 180 callback)); | 180 callback)); |
| 181 request->set_area(src_subrect); | 181 request->set_area(src_subrect); |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 544 surface_factory_->Destroy(surface_id_); | 544 surface_factory_->Destroy(surface_id_); |
| 545 surface_id_ = cc::SurfaceId(); | 545 surface_id_ = cc::SurfaceId(); |
| 546 } | 546 } |
| 547 delegated_frame_evictor_->DiscardedFrame(); | 547 delegated_frame_evictor_->DiscardedFrame(); |
| 548 } | 548 } |
| 549 | 549 |
| 550 // static | 550 // static |
| 551 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( | 551 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( |
| 552 const gfx::Size& dst_size_in_pixel, | 552 const gfx::Size& dst_size_in_pixel, |
| 553 const SkColorType color_type, | 553 const SkColorType color_type, |
| 554 const base::Callback<void(bool, const SkBitmap&)>& callback, | 554 ReadbackRequestCallback& callback, |
| 555 scoped_ptr<cc::CopyOutputResult> result) { | 555 scoped_ptr<cc::CopyOutputResult> result) { |
| 556 if (result->IsEmpty() || result->size().IsEmpty()) { | 556 if (result->IsEmpty() || result->size().IsEmpty()) { |
| 557 callback.Run(false, SkBitmap()); | 557 callback.Run(SkBitmap(), content::READBACK_FAILED); |
| 558 return; | 558 return; |
| 559 } | 559 } |
| 560 | 560 |
| 561 if (result->HasTexture()) { | 561 if (result->HasTexture()) { |
| 562 // GPU-accelerated path | 562 // GPU-accelerated path |
| 563 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, | 563 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, |
| 564 callback, | 564 callback, |
| 565 result.Pass()); | 565 result.Pass()); |
| 566 return; | 566 return; |
| 567 } | 567 } |
| 568 | 568 |
| 569 DCHECK(result->HasBitmap()); | 569 DCHECK(result->HasBitmap()); |
| 570 // Software path | 570 // Software path |
| 571 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, | 571 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, |
| 572 result.Pass()); | 572 result.Pass()); |
| 573 } | 573 } |
| 574 | 574 |
| 575 static void CopyFromCompositingSurfaceFinished( | 575 static void CopyFromCompositingSurfaceFinished( |
| 576 const base::Callback<void(bool, const SkBitmap&)>& callback, | 576 ReadbackRequestCallback& callback, |
| 577 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 577 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
| 578 scoped_ptr<SkBitmap> bitmap, | 578 scoped_ptr<SkBitmap> bitmap, |
| 579 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, | 579 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, |
| 580 bool result) { | 580 bool result) { |
| 581 bitmap_pixels_lock.reset(); | 581 bitmap_pixels_lock.reset(); |
| 582 | 582 |
| 583 uint32 sync_point = 0; | 583 uint32 sync_point = 0; |
| 584 if (result) { | 584 if (result) { |
| 585 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); | 585 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); |
| 586 sync_point = gl_helper->InsertSyncPoint(); | 586 sync_point = gl_helper->InsertSyncPoint(); |
| 587 } | 587 } |
| 588 bool lost_resource = sync_point == 0; | 588 bool lost_resource = sync_point == 0; |
| 589 release_callback->Run(sync_point, lost_resource); | 589 release_callback->Run(sync_point, lost_resource); |
| 590 | 590 |
| 591 callback.Run(result, *bitmap); | 591 callback.Run(*bitmap, content::READBACK_SUCCESS); |
|
Jeffrey Yasskin
2014/11/15 01:26:43
This line is incorrect if 'result' is false. I bel
| |
| 592 } | 592 } |
| 593 | 593 |
| 594 // static | 594 // static |
| 595 void DelegatedFrameHost::PrepareTextureCopyOutputResult( | 595 void DelegatedFrameHost::PrepareTextureCopyOutputResult( |
| 596 const gfx::Size& dst_size_in_pixel, | 596 const gfx::Size& dst_size_in_pixel, |
| 597 const SkColorType color_type, | 597 const SkColorType color_type, |
| 598 const base::Callback<void(bool, const SkBitmap&)>& callback, | 598 ReadbackRequestCallback& callback, |
| 599 scoped_ptr<cc::CopyOutputResult> result) { | 599 scoped_ptr<cc::CopyOutputResult> result) { |
| 600 DCHECK(result->HasTexture()); | 600 DCHECK(result->HasTexture()); |
| 601 base::ScopedClosureRunner scoped_callback_runner( | 601 base::ScopedClosureRunner scoped_callback_runner( |
| 602 base::Bind(callback, false, SkBitmap())); | 602 base::Bind(callback, SkBitmap(), content::READBACK_FAILED)); |
| 603 | 603 |
| 604 // TODO(sikugu): We should be able to validate the format here using | 604 // TODO(sikugu): We should be able to validate the format here using |
| 605 // GLHelper::IsReadbackConfigSupported before we processs the result. | 605 // GLHelper::IsReadbackConfigSupported before we processs the result. |
| 606 // See crbug.com/415682. | 606 // See crbug.com/415682. |
| 607 scoped_ptr<SkBitmap> bitmap(new SkBitmap); | 607 scoped_ptr<SkBitmap> bitmap(new SkBitmap); |
| 608 if (!bitmap->tryAllocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), | 608 if (!bitmap->tryAllocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), |
| 609 dst_size_in_pixel.height(), | 609 dst_size_in_pixel.height(), |
| 610 color_type, | 610 color_type, |
| 611 kOpaque_SkAlphaType))) | 611 kOpaque_SkAlphaType))) |
| 612 return; | 612 return; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 640 base::Passed(&release_callback), | 640 base::Passed(&release_callback), |
| 641 base::Passed(&bitmap), | 641 base::Passed(&bitmap), |
| 642 base::Passed(&bitmap_pixels_lock)), | 642 base::Passed(&bitmap_pixels_lock)), |
| 643 GLHelper::SCALER_QUALITY_FAST); | 643 GLHelper::SCALER_QUALITY_FAST); |
| 644 } | 644 } |
| 645 | 645 |
| 646 // static | 646 // static |
| 647 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( | 647 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( |
| 648 const gfx::Size& dst_size_in_pixel, | 648 const gfx::Size& dst_size_in_pixel, |
| 649 const SkColorType color_type, | 649 const SkColorType color_type, |
| 650 const base::Callback<void(bool, const SkBitmap&)>& callback, | 650 ReadbackRequestCallback& callback, |
| 651 scoped_ptr<cc::CopyOutputResult> result) { | 651 scoped_ptr<cc::CopyOutputResult> result) { |
| 652 if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) { | 652 if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) { |
| 653 NOTIMPLEMENTED(); | 653 NOTIMPLEMENTED(); |
| 654 callback.Run(false, SkBitmap()); | 654 callback.Run(SkBitmap(), READBACK_FORMAT_NOT_SUPPORTED); |
| 655 return; | 655 return; |
| 656 } | 656 } |
| 657 DCHECK(result->HasBitmap()); | 657 DCHECK(result->HasBitmap()); |
| 658 scoped_ptr<SkBitmap> source = result->TakeBitmap(); | 658 scoped_ptr<SkBitmap> source = result->TakeBitmap(); |
| 659 DCHECK(source); | 659 DCHECK(source); |
| 660 SkBitmap scaled_bitmap; | 660 SkBitmap scaled_bitmap; |
| 661 if (source->width() != dst_size_in_pixel.width() || | 661 if (source->width() != dst_size_in_pixel.width() || |
| 662 source->height() != dst_size_in_pixel.height()) { | 662 source->height() != dst_size_in_pixel.height()) { |
| 663 scaled_bitmap = | 663 scaled_bitmap = |
| 664 skia::ImageOperations::Resize(*source, | 664 skia::ImageOperations::Resize(*source, |
| 665 skia::ImageOperations::RESIZE_BEST, | 665 skia::ImageOperations::RESIZE_BEST, |
| 666 dst_size_in_pixel.width(), | 666 dst_size_in_pixel.width(), |
| 667 dst_size_in_pixel.height()); | 667 dst_size_in_pixel.height()); |
| 668 } else { | 668 } else { |
| 669 scaled_bitmap = *source; | 669 scaled_bitmap = *source; |
| 670 } | 670 } |
| 671 if (color_type == kN32_SkColorType) { | 671 if (color_type == kN32_SkColorType) { |
| 672 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); | 672 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); |
| 673 callback.Run(true, scaled_bitmap); | 673 callback.Run(scaled_bitmap, READBACK_SUCCESS); |
| 674 return; | 674 return; |
| 675 } | 675 } |
| 676 DCHECK_EQ(color_type, kAlpha_8_SkColorType); | 676 DCHECK_EQ(color_type, kAlpha_8_SkColorType); |
| 677 // The software path currently always returns N32 bitmap regardless of the | 677 // The software path currently always returns N32 bitmap regardless of the |
| 678 // |color_type| we ask for. | 678 // |color_type| we ask for. |
| 679 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); | 679 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); |
| 680 // Paint |scaledBitmap| to alpha-only |grayscale_bitmap|. | 680 // Paint |scaledBitmap| to alpha-only |grayscale_bitmap|. |
| 681 SkBitmap grayscale_bitmap; | 681 SkBitmap grayscale_bitmap; |
| 682 bool success = grayscale_bitmap.tryAllocPixels( | 682 bool success = grayscale_bitmap.tryAllocPixels( |
| 683 SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height())); | 683 SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height())); |
| 684 if (!success) { | 684 if (!success) { |
| 685 callback.Run(false, SkBitmap()); | 685 callback.Run(SkBitmap(), content::READBACK_MEMORY_ALLOCATION_FAILURE); |
| 686 return; | 686 return; |
| 687 } | 687 } |
| 688 SkCanvas canvas(grayscale_bitmap); | 688 SkCanvas canvas(grayscale_bitmap); |
| 689 SkPaint paint; | 689 SkPaint paint; |
| 690 skia::RefPtr<SkColorFilter> filter = | 690 skia::RefPtr<SkColorFilter> filter = |
| 691 skia::AdoptRef(SkLumaColorFilter::Create()); | 691 skia::AdoptRef(SkLumaColorFilter::Create()); |
| 692 paint.setColorFilter(filter.get()); | 692 paint.setColorFilter(filter.get()); |
| 693 canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); | 693 canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); |
| 694 callback.Run(true, grayscale_bitmap); | 694 callback.Run(grayscale_bitmap, READBACK_SUCCESS); |
| 695 } | 695 } |
| 696 | 696 |
| 697 // static | 697 // static |
| 698 void DelegatedFrameHost::ReturnSubscriberTexture( | 698 void DelegatedFrameHost::ReturnSubscriberTexture( |
| 699 base::WeakPtr<DelegatedFrameHost> dfh, | 699 base::WeakPtr<DelegatedFrameHost> dfh, |
| 700 scoped_refptr<OwnedMailbox> subscriber_texture, | 700 scoped_refptr<OwnedMailbox> subscriber_texture, |
| 701 uint32 sync_point) { | 701 uint32 sync_point) { |
| 702 if (!subscriber_texture.get()) | 702 if (!subscriber_texture.get()) |
| 703 return; | 703 return; |
| 704 if (!dfh) | 704 if (!dfh) |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1012 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 1012 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
| 1013 cc::SurfaceManager* manager = factory->GetSurfaceManager(); | 1013 cc::SurfaceManager* manager = factory->GetSurfaceManager(); |
| 1014 new_layer->SetShowSurface( | 1014 new_layer->SetShowSurface( |
| 1015 surface_id_, base::Bind(&SatisfyCallback, base::Unretained(manager)), | 1015 surface_id_, base::Bind(&SatisfyCallback, base::Unretained(manager)), |
| 1016 base::Bind(&RequireCallback, base::Unretained(manager)), | 1016 base::Bind(&RequireCallback, base::Unretained(manager)), |
| 1017 current_surface_size_, current_frame_size_in_dip_); | 1017 current_surface_size_, current_frame_size_in_dip_); |
| 1018 } | 1018 } |
| 1019 } | 1019 } |
| 1020 | 1020 |
| 1021 } // namespace content | 1021 } // namespace content |
| OLD | NEW |