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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 CopyFromCompositingSurfaceCallback& 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(false, 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 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 surface_factory_->Destroy(surface_id_); | 517 surface_factory_->Destroy(surface_id_); |
518 surface_id_ = cc::SurfaceId(); | 518 surface_id_ = cc::SurfaceId(); |
519 } | 519 } |
520 delegated_frame_evictor_->DiscardedFrame(); | 520 delegated_frame_evictor_->DiscardedFrame(); |
521 } | 521 } |
522 | 522 |
523 // static | 523 // static |
524 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( | 524 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( |
525 const gfx::Size& dst_size_in_pixel, | 525 const gfx::Size& dst_size_in_pixel, |
526 const SkColorType color_type, | 526 const SkColorType color_type, |
527 const base::Callback<void(bool, const SkBitmap&)>& callback, | 527 CopyFromCompositingSurfaceCallback& callback, |
528 scoped_ptr<cc::CopyOutputResult> result) { | 528 scoped_ptr<cc::CopyOutputResult> result) { |
529 if (result->IsEmpty() || result->size().IsEmpty()) { | 529 if (result->IsEmpty() || result->size().IsEmpty()) { |
530 callback.Run(false, SkBitmap()); | 530 callback.Run(false, SkBitmap(), content::READBACK_RESULT_EMPTY); |
531 return; | 531 return; |
532 } | 532 } |
533 | 533 |
534 if (result->HasTexture()) { | 534 if (result->HasTexture()) { |
535 // GPU-accelerated path | 535 // GPU-accelerated path |
536 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, | 536 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, |
537 callback, | 537 callback, |
538 result.Pass()); | 538 result.Pass()); |
539 return; | 539 return; |
540 } | 540 } |
541 | 541 |
542 DCHECK(result->HasBitmap()); | 542 DCHECK(result->HasBitmap()); |
543 // Software path | 543 // Software path |
544 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, | 544 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, |
545 result.Pass()); | 545 result.Pass()); |
546 } | 546 } |
547 | 547 |
548 static void CopyFromCompositingSurfaceFinished( | 548 static void CopyFromCompositingSurfaceFinished( |
549 const base::Callback<void(bool, const SkBitmap&)>& callback, | 549 CopyFromCompositingSurfaceCallback& callback, |
550 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 550 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
551 scoped_ptr<SkBitmap> bitmap, | 551 scoped_ptr<SkBitmap> bitmap, |
552 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, | 552 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, |
553 bool result) { | 553 bool result) { |
554 bitmap_pixels_lock.reset(); | 554 bitmap_pixels_lock.reset(); |
555 | 555 |
556 uint32 sync_point = 0; | 556 uint32 sync_point = 0; |
557 if (result) { | 557 if (result) { |
558 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); | 558 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); |
559 sync_point = gl_helper->InsertSyncPoint(); | 559 sync_point = gl_helper->InsertSyncPoint(); |
560 } | 560 } |
561 bool lost_resource = sync_point == 0; | 561 bool lost_resource = sync_point == 0; |
562 release_callback->Run(sync_point, lost_resource); | 562 release_callback->Run(sync_point, lost_resource); |
563 | 563 |
564 callback.Run(result, *bitmap); | 564 callback.Run(result, *bitmap, content::READBACK_SUCCESS); |
565 } | 565 } |
566 | 566 |
567 // static | 567 // static |
568 void DelegatedFrameHost::PrepareTextureCopyOutputResult( | 568 void DelegatedFrameHost::PrepareTextureCopyOutputResult( |
569 const gfx::Size& dst_size_in_pixel, | 569 const gfx::Size& dst_size_in_pixel, |
570 const SkColorType color_type, | 570 const SkColorType color_type, |
571 const base::Callback<void(bool, const SkBitmap&)>& callback, | 571 CopyFromCompositingSurfaceCallback& callback, |
572 scoped_ptr<cc::CopyOutputResult> result) { | 572 scoped_ptr<cc::CopyOutputResult> result) { |
573 DCHECK(result->HasTexture()); | 573 DCHECK(result->HasTexture()); |
574 base::ScopedClosureRunner scoped_callback_runner( | 574 base::ScopedClosureRunner scoped_callback_runner( |
575 base::Bind(callback, false, SkBitmap())); | 575 base::Bind(callback, false, SkBitmap(), content::READBACK_RESULT_EMPTY)); |
576 | 576 |
577 // TODO(sikugu): We should be able to validate the format here using | 577 // TODO(sikugu): We should be able to validate the format here using |
578 // GLHelper::IsReadbackConfigSupported before we processs the result. | 578 // GLHelper::IsReadbackConfigSupported before we processs the result. |
579 // See crbug.com/415682. | 579 // See crbug.com/415682. |
580 scoped_ptr<SkBitmap> bitmap(new SkBitmap); | 580 scoped_ptr<SkBitmap> bitmap(new SkBitmap); |
581 if (!bitmap->tryAllocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), | 581 if (!bitmap->tryAllocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), |
582 dst_size_in_pixel.height(), | 582 dst_size_in_pixel.height(), |
583 color_type, | 583 color_type, |
584 kOpaque_SkAlphaType))) | 584 kOpaque_SkAlphaType))) |
585 return; | 585 return; |
(...skipping 27 matching lines...) Expand all Loading... |
613 base::Passed(&release_callback), | 613 base::Passed(&release_callback), |
614 base::Passed(&bitmap), | 614 base::Passed(&bitmap), |
615 base::Passed(&bitmap_pixels_lock)), | 615 base::Passed(&bitmap_pixels_lock)), |
616 GLHelper::SCALER_QUALITY_FAST); | 616 GLHelper::SCALER_QUALITY_FAST); |
617 } | 617 } |
618 | 618 |
619 // static | 619 // static |
620 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( | 620 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( |
621 const gfx::Size& dst_size_in_pixel, | 621 const gfx::Size& dst_size_in_pixel, |
622 const SkColorType color_type, | 622 const SkColorType color_type, |
623 const base::Callback<void(bool, const SkBitmap&)>& callback, | 623 CopyFromCompositingSurfaceCallback& callback, |
624 scoped_ptr<cc::CopyOutputResult> result) { | 624 scoped_ptr<cc::CopyOutputResult> result) { |
625 if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) { | 625 if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) { |
626 NOTIMPLEMENTED(); | 626 NOTIMPLEMENTED(); |
627 callback.Run(false, SkBitmap()); | 627 callback.Run(false, SkBitmap(), READBACK_FORMAT_NOT_SUPPORTED); |
628 return; | 628 return; |
629 } | 629 } |
630 DCHECK(result->HasBitmap()); | 630 DCHECK(result->HasBitmap()); |
631 scoped_ptr<SkBitmap> source = result->TakeBitmap(); | 631 scoped_ptr<SkBitmap> source = result->TakeBitmap(); |
632 DCHECK(source); | 632 DCHECK(source); |
633 SkBitmap scaled_bitmap; | 633 SkBitmap scaled_bitmap; |
634 if (source->width() != dst_size_in_pixel.width() || | 634 if (source->width() != dst_size_in_pixel.width() || |
635 source->height() != dst_size_in_pixel.height()) { | 635 source->height() != dst_size_in_pixel.height()) { |
636 scaled_bitmap = | 636 scaled_bitmap = |
637 skia::ImageOperations::Resize(*source, | 637 skia::ImageOperations::Resize(*source, |
638 skia::ImageOperations::RESIZE_BEST, | 638 skia::ImageOperations::RESIZE_BEST, |
639 dst_size_in_pixel.width(), | 639 dst_size_in_pixel.width(), |
640 dst_size_in_pixel.height()); | 640 dst_size_in_pixel.height()); |
641 } else { | 641 } else { |
642 scaled_bitmap = *source; | 642 scaled_bitmap = *source; |
643 } | 643 } |
644 if (color_type == kN32_SkColorType) { | 644 if (color_type == kN32_SkColorType) { |
645 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); | 645 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); |
646 callback.Run(true, scaled_bitmap); | 646 callback.Run(true, scaled_bitmap, READBACK_SUCCESS); |
647 return; | 647 return; |
648 } | 648 } |
649 DCHECK_EQ(color_type, kAlpha_8_SkColorType); | 649 DCHECK_EQ(color_type, kAlpha_8_SkColorType); |
650 // The software path currently always returns N32 bitmap regardless of the | 650 // The software path currently always returns N32 bitmap regardless of the |
651 // |color_type| we ask for. | 651 // |color_type| we ask for. |
652 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); | 652 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); |
653 // Paint |scaledBitmap| to alpha-only |grayscale_bitmap|. | 653 // Paint |scaledBitmap| to alpha-only |grayscale_bitmap|. |
654 SkBitmap grayscale_bitmap; | 654 SkBitmap grayscale_bitmap; |
655 bool success = grayscale_bitmap.tryAllocPixels( | 655 bool success = grayscale_bitmap.tryAllocPixels( |
656 SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height())); | 656 SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height())); |
657 if (!success) { | 657 if (!success) { |
658 callback.Run(false, SkBitmap()); | 658 callback.Run( |
| 659 false, SkBitmap(), content::READBACK_MEMORY_ALLOCATION_FAILURE); |
659 return; | 660 return; |
660 } | 661 } |
661 SkCanvas canvas(grayscale_bitmap); | 662 SkCanvas canvas(grayscale_bitmap); |
662 SkPaint paint; | 663 SkPaint paint; |
663 skia::RefPtr<SkColorFilter> filter = | 664 skia::RefPtr<SkColorFilter> filter = |
664 skia::AdoptRef(SkLumaColorFilter::Create()); | 665 skia::AdoptRef(SkLumaColorFilter::Create()); |
665 paint.setColorFilter(filter.get()); | 666 paint.setColorFilter(filter.get()); |
666 canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); | 667 canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); |
667 callback.Run(true, grayscale_bitmap); | 668 callback.Run(true, grayscale_bitmap, READBACK_SUCCESS); |
668 } | 669 } |
669 | 670 |
670 // static | 671 // static |
671 void DelegatedFrameHost::ReturnSubscriberTexture( | 672 void DelegatedFrameHost::ReturnSubscriberTexture( |
672 base::WeakPtr<DelegatedFrameHost> dfh, | 673 base::WeakPtr<DelegatedFrameHost> dfh, |
673 scoped_refptr<OwnedMailbox> subscriber_texture, | 674 scoped_refptr<OwnedMailbox> subscriber_texture, |
674 uint32 sync_point) { | 675 uint32 sync_point) { |
675 if (!subscriber_texture.get()) | 676 if (!subscriber_texture.get()) |
676 return; | 677 return; |
677 if (!dfh) | 678 if (!dfh) |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 if (frame_provider_.get()) { | 980 if (frame_provider_.get()) { |
980 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 981 new_layer->SetShowDelegatedContent(frame_provider_.get(), |
981 current_frame_size_in_dip_); | 982 current_frame_size_in_dip_); |
982 } | 983 } |
983 if (!surface_id_.is_null()) { | 984 if (!surface_id_.is_null()) { |
984 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); | 985 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); |
985 } | 986 } |
986 } | 987 } |
987 | 988 |
988 } // namespace content | 989 } // namespace content |
OLD | NEW |