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 |