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" |
11 #include "cc/output/copy_output_request.h" | 11 #include "cc/output/copy_output_request.h" |
12 #include "cc/resources/single_release_callback.h" | 12 #include "cc/resources/single_release_callback.h" |
13 #include "cc/resources/texture_mailbox.h" | 13 #include "cc/resources/texture_mailbox.h" |
14 #include "cc/surfaces/surface_factory.h" | 14 #include "cc/surfaces/surface_factory.h" |
15 #include "content/browser/compositor/resize_lock.h" | 15 #include "content/browser/compositor/resize_lock.h" |
16 #include "content/common/gpu/client/gl_helper.h" | 16 #include "content/common/gpu/client/gl_helper.h" |
17 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 17 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
18 #include "content/public/common/content_switches.h" | 18 #include "content/public/common/content_switches.h" |
19 #include "media/base/video_frame.h" | 19 #include "media/base/video_frame.h" |
20 #include "media/base/video_util.h" | 20 #include "media/base/video_util.h" |
21 #include "skia/ext/image_operations.h" | 21 #include "skia/ext/image_operations.h" |
| 22 #include "third_party/skia/include/core/SkCanvas.h" |
| 23 #include "third_party/skia/include/core/SkPaint.h" |
| 24 #include "third_party/skia/include/effects/SkLumaColorFilter.h" |
22 #include "ui/gfx/frame_time.h" | 25 #include "ui/gfx/frame_time.h" |
23 | 26 |
24 namespace content { | 27 namespace content { |
25 | 28 |
26 //////////////////////////////////////////////////////////////////////////////// | 29 //////////////////////////////////////////////////////////////////////////////// |
27 // DelegatedFrameHostClient | 30 // DelegatedFrameHostClient |
28 | 31 |
29 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { | 32 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { |
30 // On Windows and Linux, holding pointer moves will not help throttling | 33 // On Windows and Linux, holding pointer moves will not help throttling |
31 // resizes. | 34 // resizes. |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 scoped_ptr<cc::CopyOutputRequest> request) { | 132 scoped_ptr<cc::CopyOutputRequest> request) { |
130 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); | 133 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); |
131 } | 134 } |
132 | 135 |
133 void DelegatedFrameHost::CopyFromCompositingSurface( | 136 void DelegatedFrameHost::CopyFromCompositingSurface( |
134 const gfx::Rect& src_subrect, | 137 const gfx::Rect& src_subrect, |
135 const gfx::Size& output_size, | 138 const gfx::Size& output_size, |
136 const base::Callback<void(bool, const SkBitmap&)>& callback, | 139 const base::Callback<void(bool, const SkBitmap&)>& callback, |
137 const SkColorType color_type) { | 140 const SkColorType color_type) { |
138 // Only ARGB888 and RGB565 supported as of now. | 141 // Only ARGB888 and RGB565 supported as of now. |
139 bool format_support = ((color_type == kRGB_565_SkColorType) || | 142 bool format_support = ((color_type == kAlpha_8_SkColorType) || |
| 143 (color_type == kRGB_565_SkColorType) || |
140 (color_type == kN32_SkColorType)); | 144 (color_type == kN32_SkColorType)); |
141 DCHECK(format_support); | 145 DCHECK(format_support); |
142 if (!CanCopyToBitmap()) { | 146 if (!CanCopyToBitmap()) { |
143 callback.Run(false, SkBitmap()); | 147 callback.Run(false, SkBitmap()); |
144 return; | 148 return; |
145 } | 149 } |
146 | 150 |
147 scoped_ptr<cc::CopyOutputRequest> request = | 151 scoped_ptr<cc::CopyOutputRequest> request = |
148 cc::CopyOutputRequest::CreateRequest(base::Bind( | 152 cc::CopyOutputRequest::CreateRequest(base::Bind( |
149 &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, | 153 &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 const gfx::Size& dst_size_in_pixel, | 503 const gfx::Size& dst_size_in_pixel, |
500 const SkColorType color_type, | 504 const SkColorType color_type, |
501 const base::Callback<void(bool, const SkBitmap&)>& callback, | 505 const base::Callback<void(bool, const SkBitmap&)>& callback, |
502 scoped_ptr<cc::CopyOutputResult> result) { | 506 scoped_ptr<cc::CopyOutputResult> result) { |
503 if (result->IsEmpty() || result->size().IsEmpty()) { | 507 if (result->IsEmpty() || result->size().IsEmpty()) { |
504 callback.Run(false, SkBitmap()); | 508 callback.Run(false, SkBitmap()); |
505 return; | 509 return; |
506 } | 510 } |
507 | 511 |
508 if (result->HasTexture()) { | 512 if (result->HasTexture()) { |
| 513 // GPU-accelerated path |
509 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, | 514 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, |
510 callback, | 515 callback, |
511 result.Pass()); | 516 result.Pass()); |
512 return; | 517 return; |
513 } | 518 } |
514 | 519 |
515 DCHECK(result->HasBitmap()); | 520 DCHECK(result->HasBitmap()); |
| 521 // Software path |
516 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, | 522 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, |
517 result.Pass()); | 523 result.Pass()); |
518 } | 524 } |
519 | 525 |
520 static void CopyFromCompositingSurfaceFinished( | 526 static void CopyFromCompositingSurfaceFinished( |
521 const base::Callback<void(bool, const SkBitmap&)>& callback, | 527 const base::Callback<void(bool, const SkBitmap&)>& callback, |
522 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 528 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
523 scoped_ptr<SkBitmap> bitmap, | 529 scoped_ptr<SkBitmap> bitmap, |
524 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, | 530 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, |
525 bool result) { | 531 bool result) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 base::Passed(&bitmap_pixels_lock)), | 590 base::Passed(&bitmap_pixels_lock)), |
585 GLHelper::SCALER_QUALITY_FAST); | 591 GLHelper::SCALER_QUALITY_FAST); |
586 } | 592 } |
587 | 593 |
588 // static | 594 // static |
589 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( | 595 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( |
590 const gfx::Size& dst_size_in_pixel, | 596 const gfx::Size& dst_size_in_pixel, |
591 const SkColorType color_type, | 597 const SkColorType color_type, |
592 const base::Callback<void(bool, const SkBitmap&)>& callback, | 598 const base::Callback<void(bool, const SkBitmap&)>& callback, |
593 scoped_ptr<cc::CopyOutputResult> result) { | 599 scoped_ptr<cc::CopyOutputResult> result) { |
594 if (color_type != kN32_SkColorType) { | 600 if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) { |
595 NOTIMPLEMENTED(); | 601 NOTIMPLEMENTED(); |
596 callback.Run(false, SkBitmap()); | 602 callback.Run(false, SkBitmap()); |
597 return; | 603 return; |
598 } | 604 } |
599 DCHECK(result->HasBitmap()); | 605 DCHECK(result->HasBitmap()); |
600 scoped_ptr<SkBitmap> source = result->TakeBitmap(); | 606 scoped_ptr<SkBitmap> source = result->TakeBitmap(); |
601 DCHECK(source); | 607 DCHECK(source); |
602 SkBitmap bitmap = skia::ImageOperations::Resize( | 608 SkBitmap scaled_bitmap; |
603 *source, | 609 if (source->width() != dst_size_in_pixel.width() || |
604 skia::ImageOperations::RESIZE_BEST, | 610 source->height() != dst_size_in_pixel.height()) { |
605 dst_size_in_pixel.width(), | 611 scaled_bitmap = |
606 dst_size_in_pixel.height()); | 612 skia::ImageOperations::Resize(*source, |
607 callback.Run(true, bitmap); | 613 skia::ImageOperations::RESIZE_BEST, |
| 614 dst_size_in_pixel.width(), |
| 615 dst_size_in_pixel.height()); |
| 616 } else { |
| 617 scaled_bitmap = *source; |
| 618 } |
| 619 if (color_type == kN32_SkColorType) { |
| 620 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); |
| 621 callback.Run(true, scaled_bitmap); |
| 622 return; |
| 623 } |
| 624 DCHECK_EQ(color_type, kAlpha_8_SkColorType); |
| 625 // The software path currently always returns N32 bitmap regardless of the |
| 626 // |color_type| we ask for. |
| 627 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); |
| 628 // Paint |scaledBitmap| to alpha-only |grayscale_bitmap|. |
| 629 SkBitmap grayscale_bitmap; |
| 630 bool success = grayscale_bitmap.allocPixels( |
| 631 SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height())); |
| 632 if (!success) { |
| 633 callback.Run(false, SkBitmap()); |
| 634 return; |
| 635 } |
| 636 SkCanvas canvas(grayscale_bitmap); |
| 637 SkPaint paint; |
| 638 skia::RefPtr<SkColorFilter> filter = |
| 639 skia::AdoptRef(SkLumaColorFilter::Create()); |
| 640 paint.setColorFilter(filter.get()); |
| 641 canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); |
| 642 callback.Run(true, grayscale_bitmap); |
608 } | 643 } |
609 | 644 |
610 // static | 645 // static |
611 void DelegatedFrameHost::ReturnSubscriberTexture( | 646 void DelegatedFrameHost::ReturnSubscriberTexture( |
612 base::WeakPtr<DelegatedFrameHost> dfh, | 647 base::WeakPtr<DelegatedFrameHost> dfh, |
613 scoped_refptr<OwnedMailbox> subscriber_texture, | 648 scoped_refptr<OwnedMailbox> subscriber_texture, |
614 uint32 sync_point) { | 649 uint32 sync_point) { |
615 if (!subscriber_texture.get()) | 650 if (!subscriber_texture.get()) |
616 return; | 651 return; |
617 if (!dfh) | 652 if (!dfh) |
618 return; | 653 return; |
619 | 654 |
620 subscriber_texture->UpdateSyncPoint(sync_point); | 655 subscriber_texture->UpdateSyncPoint(sync_point); |
621 | 656 |
622 if (dfh->frame_subscriber_ && subscriber_texture->texture_id()) | 657 if (dfh->frame_subscriber_ && subscriber_texture->texture_id()) |
623 dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture); | 658 dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture); |
624 } | 659 } |
625 | 660 |
| 661 // static |
626 void DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo( | 662 void DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo( |
627 base::WeakPtr<DelegatedFrameHost> dfh, | 663 base::WeakPtr<DelegatedFrameHost> dfh, |
628 const base::Callback<void(bool)>& callback, | 664 const base::Callback<void(bool)>& callback, |
629 scoped_refptr<OwnedMailbox> subscriber_texture, | 665 scoped_refptr<OwnedMailbox> subscriber_texture, |
630 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 666 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
631 bool result) { | 667 bool result) { |
632 callback.Run(result); | 668 callback.Run(result); |
633 | 669 |
634 uint32 sync_point = 0; | 670 uint32 sync_point = 0; |
635 if (result) { | 671 if (result) { |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 if (frame_provider_.get()) { | 954 if (frame_provider_.get()) { |
919 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 955 new_layer->SetShowDelegatedContent(frame_provider_.get(), |
920 current_frame_size_in_dip_); | 956 current_frame_size_in_dip_); |
921 } | 957 } |
922 if (!surface_id_.is_null()) { | 958 if (!surface_id_.is_null()) { |
923 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); | 959 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); |
924 } | 960 } |
925 } | 961 } |
926 | 962 |
927 } // namespace content | 963 } // namespace content |
OLD | NEW |