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 "cc/surfaces/surface_factory.h" | 14 #include "cc/surfaces/surface_factory.h" |
| 15 #include "cc/surfaces/surface_manager.h" | |
| 15 #include "content/browser/compositor/resize_lock.h" | 16 #include "content/browser/compositor/resize_lock.h" |
| 16 #include "content/browser/gpu/compositor_util.h" | 17 #include "content/browser/gpu/compositor_util.h" |
| 17 #include "content/common/gpu/client/gl_helper.h" | 18 #include "content/common/gpu/client/gl_helper.h" |
| 18 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 19 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
| 19 #include "content/public/common/content_switches.h" | 20 #include "content/public/common/content_switches.h" |
| 20 #include "media/base/video_frame.h" | 21 #include "media/base/video_frame.h" |
| 21 #include "media/base/video_util.h" | 22 #include "media/base/video_util.h" |
| 22 #include "skia/ext/image_operations.h" | 23 #include "skia/ext/image_operations.h" |
| 23 #include "third_party/skia/include/core/SkCanvas.h" | 24 #include "third_party/skia/include/core/SkCanvas.h" |
| 24 #include "third_party/skia/include/core/SkPaint.h" | 25 #include "third_party/skia/include/core/SkPaint.h" |
| 25 #include "third_party/skia/include/effects/SkLumaColorFilter.h" | 26 #include "third_party/skia/include/effects/SkLumaColorFilter.h" |
| 26 #include "ui/gfx/frame_time.h" | 27 #include "ui/gfx/frame_time.h" |
| 27 | 28 |
| 28 namespace content { | 29 namespace content { |
| 29 | 30 |
| 31 namespace { | |
| 32 | |
| 33 void SatisfyCallback(cc::SurfaceManager* manager, | |
| 34 cc::SurfaceSequence sequence) { | |
| 35 std::vector<uint32_t> sequences; | |
| 36 sequences.push_back(sequence.sequence); | |
| 37 manager->DidSatisfySequences(sequence.id_namespace, &sequences); | |
| 38 } | |
| 39 | |
| 40 } // namespace | |
| 41 | |
| 30 //////////////////////////////////////////////////////////////////////////////// | 42 //////////////////////////////////////////////////////////////////////////////// |
| 31 // DelegatedFrameHostClient | 43 // DelegatedFrameHostClient |
| 32 | 44 |
| 33 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { | 45 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { |
| 34 // On Windows and Linux, holding pointer moves will not help throttling | 46 // On Windows and Linux, holding pointer moves will not help throttling |
| 35 // resizes. | 47 // resizes. |
| 36 // TODO(piman): on Windows we need to block (nested message loop?) the | 48 // TODO(piman): on Windows we need to block (nested message loop?) the |
| 37 // WM_SIZE event. On Linux we need to throttle at the WM level using | 49 // WM_SIZE event. On Linux we need to throttle at the WM level using |
| 38 // _NET_WM_SYNC_REQUEST. | 50 // _NET_WM_SYNC_REQUEST. |
| 39 // TODO(ccameron): Mac browser window resizing is incompletely implemented. | 51 // TODO(ccameron): Mac browser window resizing is incompletely implemented. |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 resource_collection_ = NULL; | 376 resource_collection_ = NULL; |
| 365 } | 377 } |
| 366 last_output_surface_id_ = output_surface_id; | 378 last_output_surface_id_ = output_surface_id; |
| 367 } | 379 } |
| 368 ui::Compositor* compositor = client_->GetCompositor(); | 380 ui::Compositor* compositor = client_->GetCompositor(); |
| 369 if (frame_size.IsEmpty()) { | 381 if (frame_size.IsEmpty()) { |
| 370 DCHECK(frame_data->resource_list.empty()); | 382 DCHECK(frame_data->resource_list.empty()); |
| 371 EvictDelegatedFrame(); | 383 EvictDelegatedFrame(); |
| 372 } else { | 384 } else { |
| 373 if (use_surfaces_) { | 385 if (use_surfaces_) { |
| 386 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | |
| 387 cc::SurfaceManager* manager = factory->GetSurfaceManager(); | |
| 374 if (!surface_factory_) { | 388 if (!surface_factory_) { |
| 375 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | |
| 376 cc::SurfaceManager* manager = factory->GetSurfaceManager(); | |
| 377 id_allocator_ = | 389 id_allocator_ = |
| 378 factory->GetContextFactory()->CreateSurfaceIdAllocator(); | 390 factory->GetContextFactory()->CreateSurfaceIdAllocator(); |
| 379 surface_factory_ = | 391 surface_factory_ = |
| 380 make_scoped_ptr(new cc::SurfaceFactory(manager, this)); | 392 make_scoped_ptr(new cc::SurfaceFactory(manager, this)); |
| 381 } | 393 } |
| 382 if (surface_id_.is_null() || frame_size != current_surface_size_ || | 394 if (surface_id_.is_null() || frame_size != current_surface_size_ || |
| 383 frame_size_in_dip != current_frame_size_in_dip_) { | 395 frame_size_in_dip != current_frame_size_in_dip_) { |
| 384 if (!surface_id_.is_null()) { | 396 if (!surface_id_.is_null()) { |
| 385 if (compositor) { | 397 std::set<cc::SurfaceSequence> seq; |
| 386 std::set<cc::SurfaceSequence> seq; | 398 surface_holder_->GetSequenceSet(&seq); |
| 387 seq.insert(compositor->InsertSurfaceSequenceForNextFrame()); | 399 |
| 388 // Destruction of this surface needs to wait for compositors that | 400 // Destruction of this surface needs to wait for compositors that |
| 389 // have drawn using it to swap frames that don't reference it. | 401 // have drawn using it to swap frames that don't reference it. |
| 390 // TODO(jbauman): Handle cases where the compositor has been | 402 surface_factory_->DestroyOnSequence(surface_id_, seq); |
| 391 // changed since the last draw. | |
| 392 surface_factory_->DestroyOnSequence(surface_id_, seq); | |
| 393 } else { | |
| 394 surface_factory_->Destroy(surface_id_); | |
| 395 } | |
| 396 } | 403 } |
| 397 surface_id_ = id_allocator_->GenerateId(); | 404 surface_id_ = id_allocator_->GenerateId(); |
| 405 surface_holder_ = make_scoped_refptr(new cc::SurfaceHolder( | |
|
piman
2014/11/03 23:49:26
nit: no need for make_scoped_refptr
| |
| 406 surface_id_, | |
| 407 base::Bind(&SatisfyCallback, base::Unretained(manager)))); | |
|
piman
2014/11/03 23:49:26
Why is Unretained safe? Can you add comments? In p
| |
| 398 surface_factory_->Create(surface_id_, frame_size); | 408 surface_factory_->Create(surface_id_, frame_size); |
| 399 client_->GetLayer()->SetShowSurface(surface_id_, frame_size_in_dip); | 409 client_->GetLayer()->SetShowSurface(surface_holder_, frame_size_in_dip); |
| 400 current_surface_size_ = frame_size; | 410 current_surface_size_ = frame_size; |
| 401 } | 411 } |
| 402 scoped_ptr<cc::CompositorFrame> compositor_frame = | 412 scoped_ptr<cc::CompositorFrame> compositor_frame = |
| 403 make_scoped_ptr(new cc::CompositorFrame()); | 413 make_scoped_ptr(new cc::CompositorFrame()); |
| 404 compositor_frame->delegated_frame_data = frame_data.Pass(); | 414 compositor_frame->delegated_frame_data = frame_data.Pass(); |
| 405 | 415 |
| 406 compositor_frame->metadata.latency_info.swap(skipped_latency_info_list_); | 416 compositor_frame->metadata.latency_info.swap(skipped_latency_info_list_); |
| 407 compositor_frame->metadata.latency_info.insert( | 417 compositor_frame->metadata.latency_info.insert( |
| 408 compositor_frame->metadata.latency_info.end(), | 418 compositor_frame->metadata.latency_info.end(), |
| 409 latency_info.begin(), | 419 latency_info.begin(), |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 523 resources.end(), | 533 resources.end(), |
| 524 std::back_inserter(surface_returned_resources_)); | 534 std::back_inserter(surface_returned_resources_)); |
| 525 if (!pending_delegated_ack_count_) | 535 if (!pending_delegated_ack_count_) |
| 526 SendReturnedDelegatedResources(last_output_surface_id_); | 536 SendReturnedDelegatedResources(last_output_surface_id_); |
| 527 } | 537 } |
| 528 | 538 |
| 529 void DelegatedFrameHost::EvictDelegatedFrame() { | 539 void DelegatedFrameHost::EvictDelegatedFrame() { |
| 530 client_->GetLayer()->SetShowSolidColorContent(); | 540 client_->GetLayer()->SetShowSolidColorContent(); |
| 531 frame_provider_ = NULL; | 541 frame_provider_ = NULL; |
| 532 if (!surface_id_.is_null()) { | 542 if (!surface_id_.is_null()) { |
| 533 surface_factory_->Destroy(surface_id_); | 543 std::set<cc::SurfaceSequence> seq; |
| 544 surface_holder_->GetSequenceSet(&seq); | |
| 545 surface_factory_->DestroyOnSequence(surface_id_, seq); | |
| 546 surface_holder_ = nullptr; | |
| 534 surface_id_ = cc::SurfaceId(); | 547 surface_id_ = cc::SurfaceId(); |
| 535 } | 548 } |
| 536 delegated_frame_evictor_->DiscardedFrame(); | 549 delegated_frame_evictor_->DiscardedFrame(); |
| 537 } | 550 } |
| 538 | 551 |
| 539 // static | 552 // static |
| 540 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( | 553 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( |
| 541 const gfx::Size& dst_size_in_pixel, | 554 const gfx::Size& dst_size_in_pixel, |
| 542 const SkColorType color_type, | 555 const SkColorType color_type, |
| 543 const base::Callback<void(bool, const SkBitmap&)>& callback, | 556 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 915 | 928 |
| 916 host->ScheduleComposite(); | 929 host->ScheduleComposite(); |
| 917 } | 930 } |
| 918 | 931 |
| 919 //////////////////////////////////////////////////////////////////////////////// | 932 //////////////////////////////////////////////////////////////////////////////// |
| 920 // DelegatedFrameHost, private: | 933 // DelegatedFrameHost, private: |
| 921 | 934 |
| 922 DelegatedFrameHost::~DelegatedFrameHost() { | 935 DelegatedFrameHost::~DelegatedFrameHost() { |
| 923 ImageTransportFactory::GetInstance()->RemoveObserver(this); | 936 ImageTransportFactory::GetInstance()->RemoveObserver(this); |
| 924 | 937 |
| 925 if (!surface_id_.is_null()) | 938 if (!surface_id_.is_null()) { |
| 926 surface_factory_->Destroy(surface_id_); | 939 std::set<cc::SurfaceSequence> seq; |
| 940 surface_holder_->GetSequenceSet(&seq); | |
| 941 surface_factory_->DestroyOnSequence(surface_id_, seq); | |
| 942 surface_holder_ = nullptr; | |
| 943 } | |
| 927 if (resource_collection_.get()) | 944 if (resource_collection_.get()) |
| 928 resource_collection_->SetClient(NULL); | 945 resource_collection_->SetClient(NULL); |
| 929 | 946 |
| 930 DCHECK(!vsync_manager_.get()); | 947 DCHECK(!vsync_manager_.get()); |
| 931 } | 948 } |
| 932 | 949 |
| 933 void DelegatedFrameHost::RunOnCommitCallbacks() { | 950 void DelegatedFrameHost::RunOnCommitCallbacks() { |
| 934 for (std::vector<base::Closure>::const_iterator | 951 for (std::vector<base::Closure>::const_iterator |
| 935 it = on_compositing_did_commit_callbacks_.begin(); | 952 it = on_compositing_did_commit_callbacks_.begin(); |
| 936 it != on_compositing_did_commit_callbacks_.end(); ++it) { | 953 it != on_compositing_did_commit_callbacks_.end(); ++it) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 991 void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer, | 1008 void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer, |
| 992 ui::Layer* new_layer) { | 1009 ui::Layer* new_layer) { |
| 993 // The new_layer is the one that will be used by our Window, so that's the one | 1010 // The new_layer is the one that will be used by our Window, so that's the one |
| 994 // that should keep our frame. old_layer will be returned to the | 1011 // that should keep our frame. old_layer will be returned to the |
| 995 // RecreateLayer caller, and should have a copy. | 1012 // RecreateLayer caller, and should have a copy. |
| 996 if (frame_provider_.get()) { | 1013 if (frame_provider_.get()) { |
| 997 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 1014 new_layer->SetShowDelegatedContent(frame_provider_.get(), |
| 998 current_frame_size_in_dip_); | 1015 current_frame_size_in_dip_); |
| 999 } | 1016 } |
| 1000 if (!surface_id_.is_null()) { | 1017 if (!surface_id_.is_null()) { |
| 1001 new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); | 1018 new_layer->SetShowSurface(surface_holder_, current_frame_size_in_dip_); |
| 1002 } | 1019 } |
| 1003 } | 1020 } |
| 1004 | 1021 |
| 1005 } // namespace content | 1022 } // namespace content |
| OLD | NEW |