| 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 |