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" |
| 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 "content/browser/compositor/resize_lock.h" | 14 #include "content/browser/compositor/resize_lock.h" |
| 15 #include "content/common/gpu/client/gl_helper.h" | 15 #include "content/common/gpu/client/gl_helper.h" |
| 16 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 16 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
| 17 #include "content/public/common/content_switches.h" | 17 #include "content/public/common/content_switches.h" |
| 18 #include "media/base/video_frame.h" | 18 #include "media/base/video_frame.h" |
| 19 #include "media/base/video_util.h" | 19 #include "media/base/video_util.h" |
| 20 #include "skia/ext/image_operations.h" | 20 #include "skia/ext/image_operations.h" |
| 21 #include "third_party/skia/include/core/SkCanvas.h" | |
| 22 #include "third_party/skia/include/core/SkPaint.h" | |
| 23 #include "third_party/skia/include/effects/SkLumaColorFilter.h" | |
| 21 | 24 |
| 22 namespace content { | 25 namespace content { |
| 23 | 26 |
| 24 //////////////////////////////////////////////////////////////////////////////// | 27 //////////////////////////////////////////////////////////////////////////////// |
| 25 // DelegatedFrameHostClient | 28 // DelegatedFrameHostClient |
| 26 | 29 |
| 27 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { | 30 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { |
| 28 // On Windows and Linux, holding pointer moves will not help throttling | 31 // On Windows and Linux, holding pointer moves will not help throttling |
| 29 // resizes. | 32 // resizes. |
| 30 // TODO(piman): on Windows we need to block (nested message loop?) the | 33 // TODO(piman): on Windows we need to block (nested message loop?) the |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 void DelegatedFrameHost::RequestCopyOfOutput( | 117 void DelegatedFrameHost::RequestCopyOfOutput( |
| 115 scoped_ptr<cc::CopyOutputRequest> request) { | 118 scoped_ptr<cc::CopyOutputRequest> request) { |
| 116 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); | 119 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); |
| 117 } | 120 } |
| 118 | 121 |
| 119 void DelegatedFrameHost::CopyFromCompositingSurface( | 122 void DelegatedFrameHost::CopyFromCompositingSurface( |
| 120 const gfx::Rect& src_subrect, | 123 const gfx::Rect& src_subrect, |
| 121 const gfx::Size& dst_size, | 124 const gfx::Size& dst_size, |
| 122 const base::Callback<void(bool, const SkBitmap&)>& callback, | 125 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 123 const SkColorType color_type) { | 126 const SkColorType color_type) { |
| 124 // Only ARGB888 and RGB565 supported as of now. | 127 // Only ARGB888 and RGB565 supported as of now. |
|
mfomitchev
2014/07/11 20:34:22
Comment needs updating.
Would be nice to use a gl_
| |
| 125 bool format_support = ((color_type == kRGB_565_SkColorType) || | 128 bool format_support = ((color_type == kAlpha_8_SkColorType) || |
| 129 (color_type == kRGB_565_SkColorType) || | |
| 126 (color_type == kN32_SkColorType)); | 130 (color_type == kN32_SkColorType)); |
| 127 DCHECK(format_support); | 131 DCHECK(format_support); |
| 128 if (!CanCopyToBitmap()) { | 132 if (!CanCopyToBitmap()) { |
| 129 callback.Run(false, SkBitmap()); | 133 callback.Run(false, SkBitmap()); |
| 130 return; | 134 return; |
| 131 } | 135 } |
| 132 | 136 |
| 133 const gfx::Size& dst_size_in_pixel = | 137 const gfx::Size& dst_size_in_pixel = |
| 134 client_->ConvertViewSizeToPixel(dst_size); | 138 client_->ConvertViewSizeToPixel(dst_size); |
| 135 scoped_ptr<cc::CopyOutputRequest> request = | 139 scoped_ptr<cc::CopyOutputRequest> request = |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 const gfx::Size& dst_size_in_pixel, | 435 const gfx::Size& dst_size_in_pixel, |
| 432 const SkColorType color_type, | 436 const SkColorType color_type, |
| 433 const base::Callback<void(bool, const SkBitmap&)>& callback, | 437 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 434 scoped_ptr<cc::CopyOutputResult> result) { | 438 scoped_ptr<cc::CopyOutputResult> result) { |
| 435 if (result->IsEmpty() || result->size().IsEmpty()) { | 439 if (result->IsEmpty() || result->size().IsEmpty()) { |
| 436 callback.Run(false, SkBitmap()); | 440 callback.Run(false, SkBitmap()); |
| 437 return; | 441 return; |
| 438 } | 442 } |
| 439 | 443 |
| 440 if (result->HasTexture()) { | 444 if (result->HasTexture()) { |
| 445 LOG(ERROR) << "result->HasTexture()"; | |
| 441 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, | 446 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, |
| 442 callback, | 447 callback, |
| 443 result.Pass()); | 448 result.Pass()); |
| 444 return; | 449 return; |
| 445 } | 450 } |
| 446 | 451 |
| 447 DCHECK(result->HasBitmap()); | 452 DCHECK(result->HasBitmap()); |
| 453 LOG(ERROR) << "result->HasBitmap()"; | |
| 448 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, | 454 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, |
| 449 result.Pass()); | 455 result.Pass()); |
| 450 } | 456 } |
| 451 | 457 |
| 452 static void CopyFromCompositingSurfaceFinished( | 458 static void CopyFromCompositingSurfaceFinished( |
| 453 const base::Callback<void(bool, const SkBitmap&)>& callback, | 459 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 454 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 460 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
| 455 scoped_ptr<SkBitmap> bitmap, | 461 scoped_ptr<SkBitmap> bitmap, |
| 456 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, | 462 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, |
| 457 bool result) { | 463 bool result) { |
| 464 LOG(ERROR) << "CopyFromCompositingSurfaceFinished"; | |
| 458 bitmap_pixels_lock.reset(); | 465 bitmap_pixels_lock.reset(); |
| 459 | 466 |
| 460 uint32 sync_point = 0; | 467 uint32 sync_point = 0; |
| 461 if (result) { | 468 if (result) { |
| 462 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); | 469 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); |
| 463 sync_point = gl_helper->InsertSyncPoint(); | 470 sync_point = gl_helper->InsertSyncPoint(); |
| 464 } | 471 } |
| 465 bool lost_resource = sync_point == 0; | 472 bool lost_resource = sync_point == 0; |
| 466 release_callback->Run(sync_point, lost_resource); | 473 release_callback->Run(sync_point, lost_resource); |
| 467 | 474 |
| 468 callback.Run(result, *bitmap); | 475 callback.Run(result, *bitmap); |
| 476 LOG(ERROR) << "=== CopyFromCompositingSurfaceFinished EXITING"; | |
| 469 } | 477 } |
| 470 | 478 |
| 471 // static | 479 // static |
| 472 void DelegatedFrameHost::PrepareTextureCopyOutputResult( | 480 void DelegatedFrameHost::PrepareTextureCopyOutputResult( |
| 473 const gfx::Size& dst_size_in_pixel, | 481 const gfx::Size& dst_size_in_pixel, |
| 474 const SkColorType color_type, | 482 const SkColorType color_type, |
| 475 const base::Callback<void(bool, const SkBitmap&)>& callback, | 483 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 476 scoped_ptr<cc::CopyOutputResult> result) { | 484 scoped_ptr<cc::CopyOutputResult> result) { |
| 485 LOG(ERROR) << "DelegatedFrameHost::PrepareTextureCopyOutputResult" | |
| 486 << ", bitmap color_type=" << color_type; | |
| 487 | |
| 477 DCHECK(result->HasTexture()); | 488 DCHECK(result->HasTexture()); |
| 478 base::ScopedClosureRunner scoped_callback_runner( | 489 base::ScopedClosureRunner scoped_callback_runner( |
| 479 base::Bind(callback, false, SkBitmap())); | 490 base::Bind(callback, false, SkBitmap())); |
| 480 | 491 |
| 481 scoped_ptr<SkBitmap> bitmap(new SkBitmap); | 492 scoped_ptr<SkBitmap> bitmap(new SkBitmap); |
| 482 if (!bitmap->allocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), | 493 if (!bitmap->allocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), |
| 483 dst_size_in_pixel.height(), | 494 dst_size_in_pixel.height(), |
| 484 color_type, | 495 color_type, |
| 485 kOpaque_SkAlphaType))) | 496 kOpaque_SkAlphaType))) |
| 486 return; | 497 return; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 516 base::Passed(&bitmap_pixels_lock)), | 527 base::Passed(&bitmap_pixels_lock)), |
| 517 GLHelper::SCALER_QUALITY_FAST); | 528 GLHelper::SCALER_QUALITY_FAST); |
| 518 } | 529 } |
| 519 | 530 |
| 520 // static | 531 // static |
| 521 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( | 532 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( |
| 522 const gfx::Size& dst_size_in_pixel, | 533 const gfx::Size& dst_size_in_pixel, |
| 523 const SkColorType color_type, | 534 const SkColorType color_type, |
| 524 const base::Callback<void(bool, const SkBitmap&)>& callback, | 535 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 525 scoped_ptr<cc::CopyOutputResult> result) { | 536 scoped_ptr<cc::CopyOutputResult> result) { |
| 526 if (color_type != kN32_SkColorType) { | 537 if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) { |
| 527 NOTIMPLEMENTED(); | 538 NOTIMPLEMENTED(); |
| 528 callback.Run(false, SkBitmap()); | 539 callback.Run(false, SkBitmap()); |
| 529 return; | 540 return; |
| 530 } | 541 } |
| 531 DCHECK(result->HasBitmap()); | 542 DCHECK(result->HasBitmap()); |
| 532 scoped_ptr<SkBitmap> source = result->TakeBitmap(); | 543 scoped_ptr<SkBitmap> source = result->TakeBitmap(); |
| 533 DCHECK(source); | 544 DCHECK(source); |
| 534 SkBitmap bitmap = skia::ImageOperations::Resize( | 545 SkBitmap scaled_bitmap; |
| 535 *source, | 546 if (source->width() != dst_size_in_pixel.width() || |
| 536 skia::ImageOperations::RESIZE_BEST, | 547 source->height() != dst_size_in_pixel.height()) { |
| 537 dst_size_in_pixel.width(), | 548 scaled_bitmap = |
| 538 dst_size_in_pixel.height()); | 549 skia::ImageOperations::Resize(*source, |
| 539 callback.Run(true, bitmap); | 550 skia::ImageOperations::RESIZE_BEST, |
| 551 dst_size_in_pixel.width(), | |
| 552 dst_size_in_pixel.height()); | |
| 553 } else { | |
| 554 scaled_bitmap = *source; | |
| 555 } | |
| 556 if (color_type == kN32_SkColorType) { | |
| 557 callback.Run(true, scaled_bitmap); | |
| 558 return; | |
| 559 } | |
| 560 DCHECK_EQ(color_type, kAlpha_8_SkColorType); | |
| 561 // Paint |scaledBitmap| to alpha-only |a8Bitmap|. | |
| 562 SkBitmap grayscale_bitmap; | |
| 563 grayscale_bitmap.allocPixels( | |
|
mfomitchev
2014/07/11 21:20:13
We should first check the color type of the return
mfomitchev
2014/08/25 20:57:47
Done.
| |
| 564 SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height())); | |
| 565 // TODO (mfomitchev): should handle allocPixels failing here. | |
| 566 SkCanvas canvas(grayscale_bitmap); | |
| 567 SkPaint paint; | |
| 568 skia::RefPtr<SkColorFilter> filter = | |
| 569 skia::AdoptRef(SkLumaColorFilter::Create()); | |
| 570 paint.setColorFilter(filter.get()); | |
| 571 canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); | |
| 572 callback.Run(true, grayscale_bitmap); | |
| 540 } | 573 } |
| 541 | 574 |
| 542 // static | 575 // static |
| 543 void DelegatedFrameHost::ReturnSubscriberTexture( | 576 void DelegatedFrameHost::ReturnSubscriberTexture( |
| 544 base::WeakPtr<DelegatedFrameHost> dfh, | 577 base::WeakPtr<DelegatedFrameHost> dfh, |
| 545 scoped_refptr<OwnedMailbox> subscriber_texture, | 578 scoped_refptr<OwnedMailbox> subscriber_texture, |
| 546 uint32 sync_point) { | 579 uint32 sync_point) { |
| 547 if (!subscriber_texture.get()) | 580 if (!subscriber_texture.get()) |
| 548 return; | 581 return; |
| 549 if (!dfh) | 582 if (!dfh) |
| 550 return; | 583 return; |
| 551 | 584 |
| 552 subscriber_texture->UpdateSyncPoint(sync_point); | 585 subscriber_texture->UpdateSyncPoint(sync_point); |
| 553 | 586 |
| 554 if (dfh->frame_subscriber_ && subscriber_texture->texture_id()) | 587 if (dfh->frame_subscriber_ && subscriber_texture->texture_id()) |
| 555 dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture); | 588 dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture); |
| 556 } | 589 } |
| 557 | 590 |
| 591 // static | |
| 558 void DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo( | 592 void DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo( |
| 559 base::WeakPtr<DelegatedFrameHost> dfh, | 593 base::WeakPtr<DelegatedFrameHost> dfh, |
| 560 const base::Callback<void(bool)>& callback, | 594 const base::Callback<void(bool)>& callback, |
| 561 scoped_refptr<OwnedMailbox> subscriber_texture, | 595 scoped_refptr<OwnedMailbox> subscriber_texture, |
| 562 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 596 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
| 563 bool result) { | 597 bool result) { |
| 564 callback.Run(result); | 598 callback.Run(result); |
| 565 | 599 |
| 566 uint32 sync_point = 0; | 600 uint32 sync_point = 0; |
| 567 if (result) { | 601 if (result) { |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 843 // that should keep our frame. old_layer will be returned to the | 877 // that should keep our frame. old_layer will be returned to the |
| 844 // RecreateLayer caller, and should have a copy. | 878 // RecreateLayer caller, and should have a copy. |
| 845 if (frame_provider_.get()) { | 879 if (frame_provider_.get()) { |
| 846 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 880 new_layer->SetShowDelegatedContent(frame_provider_.get(), |
| 847 current_frame_size_in_dip_); | 881 current_frame_size_in_dip_); |
| 848 } | 882 } |
| 849 } | 883 } |
| 850 | 884 |
| 851 } // namespace content | 885 } // namespace content |
| 852 | 886 |
| OLD | NEW |