Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/renderer_host/compositor_impl_android.h" | 5 #include "content/browser/renderer_host/compositor_impl_android.h" |
| 6 | 6 |
| 7 #include <android/bitmap.h> | 7 #include <android/bitmap.h> |
| 8 #include <android/native_window_jni.h> | 8 #include <android/native_window_jni.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 #include <unordered_set> | 10 #include <unordered_set> |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 // -1. | 131 // -1. |
| 132 attributes.alpha_size = 0; | 132 attributes.alpha_size = 0; |
| 133 attributes.red_size = 5; | 133 attributes.red_size = 5; |
| 134 attributes.green_size = 6; | 134 attributes.green_size = 6; |
| 135 attributes.blue_size = 5; | 135 attributes.blue_size = 5; |
| 136 } | 136 } |
| 137 | 137 |
| 138 return attributes; | 138 return attributes; |
| 139 } | 139 } |
| 140 | 140 |
| 141 class ExternalBeginFrameSource : public cc::BeginFrameSource, | |
| 142 public CompositorImpl::VSyncObserver { | |
| 143 public: | |
| 144 explicit ExternalBeginFrameSource(CompositorImpl* compositor) | |
| 145 : compositor_(compositor) { | |
| 146 compositor_->AddObserver(this); | |
| 147 } | |
| 148 ~ExternalBeginFrameSource() override { compositor_->RemoveObserver(this); } | |
| 149 | |
| 150 // cc::BeginFrameSource implementation. | |
| 151 void AddObserver(cc::BeginFrameObserver* obs) override; | |
| 152 void RemoveObserver(cc::BeginFrameObserver* obs) override; | |
| 153 void DidFinishFrame(cc::BeginFrameObserver* obs, | |
| 154 size_t remaining_frames) override {} | |
| 155 bool IsThrottled() const override { return true; } | |
| 156 | |
| 157 // CompositorImpl::VSyncObserver implementation. | |
| 158 void OnVSync(base::TimeTicks frame_time, | |
| 159 base::TimeDelta vsync_period) override; | |
| 160 | |
| 161 private: | |
| 162 CompositorImpl* const compositor_; | |
| 163 std::unordered_set<cc::BeginFrameObserver*> observers_; | |
| 164 cc::BeginFrameArgs last_begin_frame_args_; | |
| 165 }; | |
| 166 | |
| 167 void ExternalBeginFrameSource::AddObserver(cc::BeginFrameObserver* obs) { | |
| 168 DCHECK(obs); | |
| 169 DCHECK(observers_.find(obs) == observers_.end()); | |
| 170 | |
| 171 observers_.insert(obs); | |
| 172 obs->OnBeginFrameSourcePausedChanged(false); | |
| 173 compositor_->OnNeedsBeginFramesChange(true); | |
| 174 | |
| 175 if (last_begin_frame_args_.IsValid()) { | |
| 176 // Send a MISSED begin frame if necessary. | |
| 177 cc::BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs(); | |
| 178 if (!last_args.IsValid() || | |
| 179 (last_begin_frame_args_.frame_time > last_args.frame_time)) { | |
| 180 last_begin_frame_args_.type = cc::BeginFrameArgs::MISSED; | |
| 181 // TODO(crbug.com/602485): A deadline doesn't make too much sense | |
| 182 // for a missed BeginFrame (the intention rather is 'immediately'), | |
| 183 // but currently the retro frame logic is very strict in discarding | |
| 184 // BeginFrames. | |
| 185 last_begin_frame_args_.deadline = | |
| 186 base::TimeTicks::Now() + last_begin_frame_args_.interval; | |
| 187 obs->OnBeginFrame(last_begin_frame_args_); | |
| 188 } | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 void ExternalBeginFrameSource::RemoveObserver(cc::BeginFrameObserver* obs) { | |
| 193 DCHECK(obs); | |
| 194 DCHECK(observers_.find(obs) != observers_.end()); | |
| 195 | |
| 196 observers_.erase(obs); | |
| 197 if (observers_.empty()) | |
| 198 compositor_->OnNeedsBeginFramesChange(false); | |
| 199 } | |
| 200 | |
| 201 void ExternalBeginFrameSource::OnVSync(base::TimeTicks frame_time, | |
| 202 base::TimeDelta vsync_period) { | |
| 203 // frame time is in the past, so give the next vsync period as the deadline. | |
| 204 base::TimeTicks deadline = frame_time + vsync_period; | |
| 205 last_begin_frame_args_ = | |
| 206 cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline, | |
| 207 vsync_period, cc::BeginFrameArgs::NORMAL); | |
| 208 std::unordered_set<cc::BeginFrameObserver*> observers(observers_); | |
| 209 for (auto* obs : observers) | |
| 210 obs->OnBeginFrame(last_begin_frame_args_); | |
| 211 } | |
| 212 | |
| 213 class AndroidOutputSurface : public cc::OutputSurface { | 141 class AndroidOutputSurface : public cc::OutputSurface { |
| 214 public: | 142 public: |
| 215 explicit AndroidOutputSurface( | 143 explicit AndroidOutputSurface( |
| 216 scoped_refptr<ContextProviderCommandBuffer> context_provider) | 144 scoped_refptr<ContextProviderCommandBuffer> context_provider) |
| 217 : cc::OutputSurface(std::move(context_provider)), | 145 : cc::OutputSurface(std::move(context_provider)), |
| 218 overlay_candidate_validator_( | 146 overlay_candidate_validator_( |
| 219 new display_compositor:: | 147 new display_compositor:: |
| 220 CompositorOverlayCandidateValidatorAndroid()), | 148 CompositorOverlayCandidateValidatorAndroid()), |
| 221 weak_ptr_factory_(this) { | 149 weak_ptr_factory_(this) { |
| 222 capabilities_.max_frames_pending = kMaxDisplaySwapBuffers; | 150 capabilities_.max_frames_pending = kMaxDisplaySwapBuffers; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 resource_manager_(root_window), | 327 resource_manager_(root_window), |
| 400 device_scale_factor_(1), | 328 device_scale_factor_(1), |
| 401 window_(NULL), | 329 window_(NULL), |
| 402 surface_handle_(gpu::kNullSurfaceHandle), | 330 surface_handle_(gpu::kNullSurfaceHandle), |
| 403 client_(client), | 331 client_(client), |
| 404 root_window_(root_window), | 332 root_window_(root_window), |
| 405 needs_animate_(false), | 333 needs_animate_(false), |
| 406 pending_swapbuffers_(0U), | 334 pending_swapbuffers_(0U), |
| 407 num_successive_context_creation_failures_(0), | 335 num_successive_context_creation_failures_(0), |
| 408 compositor_frame_sink_request_pending_(false), | 336 compositor_frame_sink_request_pending_(false), |
| 409 needs_begin_frames_(false), | |
| 410 weak_factory_(this) { | 337 weak_factory_(this) { |
| 411 ui::ContextProviderFactory::GetInstance() | 338 ui::ContextProviderFactory::GetInstance() |
| 412 ->GetSurfaceManager() | 339 ->GetSurfaceManager() |
| 413 ->RegisterFrameSinkId(frame_sink_id_); | 340 ->RegisterFrameSinkId(frame_sink_id_); |
| 414 DCHECK(client); | 341 DCHECK(client); |
| 415 DCHECK(root_window); | 342 DCHECK(root_window); |
| 416 DCHECK(root_window->GetLayer() == nullptr); | 343 DCHECK(root_window->GetLayer() == nullptr); |
| 417 root_window->SetLayer(cc::Layer::Create()); | 344 root_window->SetLayer(cc::Layer::Create()); |
| 418 readback_layer_tree_ = cc::Layer::Create(); | 345 readback_layer_tree_ = cc::Layer::Create(); |
| 419 readback_layer_tree_->SetHideLayerAndSubtree(true); | 346 readback_layer_tree_->SetHideLayerAndSubtree(true); |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 721 | 648 |
| 722 if (context_provider) { | 649 if (context_provider) { |
| 723 gpu_capabilities_ = context_provider->ContextCapabilities(); | 650 gpu_capabilities_ = context_provider->ContextCapabilities(); |
| 724 } else { | 651 } else { |
| 725 // TODO(danakj): Populate gpu_capabilities_ for VulkanContextProvider. | 652 // TODO(danakj): Populate gpu_capabilities_ for VulkanContextProvider. |
| 726 } | 653 } |
| 727 | 654 |
| 728 cc::SurfaceManager* manager = | 655 cc::SurfaceManager* manager = |
| 729 ui::ContextProviderFactory::GetInstance()->GetSurfaceManager(); | 656 ui::ContextProviderFactory::GetInstance()->GetSurfaceManager(); |
| 730 auto* task_runner = base::ThreadTaskRunnerHandle::Get().get(); | 657 auto* task_runner = base::ThreadTaskRunnerHandle::Get().get(); |
| 731 std::unique_ptr<ExternalBeginFrameSource> begin_frame_source( | 658 std::unique_ptr<cc::DelegatingBeginFrameSource> begin_frame_source( |
|
Sami
2016/12/07 16:59:40
Dumb question: why do we need delegation here inst
Eric Seckler
2016/12/08 17:54:28
I thought this is the simplest solution to the own
brianderson
2016/12/09 01:08:11
Is it hard / or non sensical to move ownership up
Eric Seckler
2016/12/09 16:47:16
I think you're right, that might be a better solut
| |
| 732 new ExternalBeginFrameSource(this)); | 659 new cc::DelegatingBeginFrameSource(root_window_->GetBeginFrameSource())); |
| 733 std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler( | 660 std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler( |
| 734 begin_frame_source.get(), task_runner, | 661 task_runner, display_output_surface->capabilities().max_frames_pending)); |
| 735 display_output_surface->capabilities().max_frames_pending)); | |
| 736 | 662 |
| 737 display_.reset(new cc::Display( | 663 display_.reset(new cc::Display( |
| 738 HostSharedBitmapManager::current(), | 664 HostSharedBitmapManager::current(), |
| 739 BrowserGpuMemoryBufferManager::current(), | 665 BrowserGpuMemoryBufferManager::current(), |
| 740 host_->GetSettings().renderer_settings, frame_sink_id_, | 666 host_->GetSettings().renderer_settings, frame_sink_id_, |
| 741 std::move(begin_frame_source), std::move(display_output_surface), | 667 std::move(begin_frame_source), std::move(display_output_surface), |
| 742 std::move(scheduler), | 668 std::move(scheduler), |
| 743 base::MakeUnique<cc::TextureMailboxDeleter>(task_runner))); | 669 base::MakeUnique<cc::TextureMailboxDeleter>(task_runner))); |
| 744 | 670 |
| 745 auto compositor_frame_sink = | 671 auto compositor_frame_sink = |
| 746 vulkan_context_provider | 672 vulkan_context_provider |
| 747 ? base::MakeUnique<cc::DirectCompositorFrameSink>( | 673 ? base::MakeUnique<cc::DirectCompositorFrameSink>( |
| 748 frame_sink_id_, manager, display_.get(), | 674 frame_sink_id_, manager, display_.get(), |
| 749 vulkan_context_provider) | 675 vulkan_context_provider) |
| 750 : base::MakeUnique<cc::DirectCompositorFrameSink>( | 676 : base::MakeUnique<cc::DirectCompositorFrameSink>( |
| 751 frame_sink_id_, manager, display_.get(), context_provider, | 677 frame_sink_id_, manager, display_.get(), context_provider, |
| 752 nullptr, BrowserGpuMemoryBufferManager::current(), | 678 nullptr, BrowserGpuMemoryBufferManager::current(), |
| 753 HostSharedBitmapManager::current()); | 679 HostSharedBitmapManager::current()); |
| 754 | 680 |
| 755 display_->SetVisible(true); | 681 display_->SetVisible(true); |
| 756 display_->Resize(size_); | 682 display_->Resize(size_); |
| 757 host_->SetCompositorFrameSink(std::move(compositor_frame_sink)); | 683 host_->SetCompositorFrameSink(std::move(compositor_frame_sink)); |
| 758 } | 684 } |
| 759 | 685 |
| 760 void CompositorImpl::AddObserver(VSyncObserver* observer) { | |
| 761 observer_list_.AddObserver(observer); | |
| 762 } | |
| 763 | |
| 764 void CompositorImpl::RemoveObserver(VSyncObserver* observer) { | |
| 765 observer_list_.RemoveObserver(observer); | |
| 766 } | |
| 767 | |
| 768 cc::UIResourceId CompositorImpl::CreateUIResource( | 686 cc::UIResourceId CompositorImpl::CreateUIResource( |
| 769 cc::UIResourceClient* client) { | 687 cc::UIResourceClient* client) { |
| 770 TRACE_EVENT0("compositor", "CompositorImpl::CreateUIResource"); | 688 TRACE_EVENT0("compositor", "CompositorImpl::CreateUIResource"); |
| 771 return host_->GetUIResourceManager()->CreateUIResource(client); | 689 return host_->GetUIResourceManager()->CreateUIResource(client); |
| 772 } | 690 } |
| 773 | 691 |
| 774 void CompositorImpl::DeleteUIResource(cc::UIResourceId resource_id) { | 692 void CompositorImpl::DeleteUIResource(cc::UIResourceId resource_id) { |
| 775 TRACE_EVENT0("compositor", "CompositorImpl::DeleteUIResource"); | 693 TRACE_EVENT0("compositor", "CompositorImpl::DeleteUIResource"); |
| 776 host_->GetUIResourceManager()->DeleteUIResource(resource_id); | 694 host_->GetUIResourceManager()->DeleteUIResource(resource_id); |
| 777 } | 695 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 803 | 721 |
| 804 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { | 722 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { |
| 805 readback_layer_tree_->AddChild(layer); | 723 readback_layer_tree_->AddChild(layer); |
| 806 } | 724 } |
| 807 | 725 |
| 808 void CompositorImpl::RequestCopyOfOutputOnRootLayer( | 726 void CompositorImpl::RequestCopyOfOutputOnRootLayer( |
| 809 std::unique_ptr<cc::CopyOutputRequest> request) { | 727 std::unique_ptr<cc::CopyOutputRequest> request) { |
| 810 root_window_->GetLayer()->RequestCopyOfOutput(std::move(request)); | 728 root_window_->GetLayer()->RequestCopyOfOutput(std::move(request)); |
| 811 } | 729 } |
| 812 | 730 |
| 813 void CompositorImpl::OnVSync(base::TimeTicks frame_time, | |
| 814 base::TimeDelta vsync_period) { | |
| 815 for (auto& observer : observer_list_) | |
| 816 observer.OnVSync(frame_time, vsync_period); | |
| 817 if (needs_begin_frames_) | |
| 818 root_window_->RequestVSyncUpdate(); | |
| 819 } | |
| 820 | |
| 821 void CompositorImpl::OnNeedsBeginFramesChange(bool needs_begin_frames) { | |
| 822 if (needs_begin_frames_ == needs_begin_frames) | |
| 823 return; | |
| 824 | |
| 825 needs_begin_frames_ = needs_begin_frames; | |
| 826 if (needs_begin_frames_) | |
| 827 root_window_->RequestVSyncUpdate(); | |
| 828 } | |
| 829 | |
| 830 void CompositorImpl::SetNeedsAnimate() { | 731 void CompositorImpl::SetNeedsAnimate() { |
| 831 needs_animate_ = true; | 732 needs_animate_ = true; |
| 832 if (!host_->IsVisible()) | 733 if (!host_->IsVisible()) |
| 833 return; | 734 return; |
| 834 | 735 |
| 835 TRACE_EVENT0("compositor", "Compositor::SetNeedsAnimate"); | 736 TRACE_EVENT0("compositor", "Compositor::SetNeedsAnimate"); |
| 836 host_->SetNeedsAnimate(); | 737 host_->SetNeedsAnimate(); |
| 837 } | 738 } |
| 838 | 739 |
| 839 cc::FrameSinkId CompositorImpl::GetFrameSinkId() { | 740 cc::FrameSinkId CompositorImpl::GetFrameSinkId() { |
| 840 return frame_sink_id_; | 741 return frame_sink_id_; |
| 841 } | 742 } |
| 842 | 743 |
| 843 bool CompositorImpl::HavePendingReadbacks() { | 744 bool CompositorImpl::HavePendingReadbacks() { |
| 844 return !readback_layer_tree_->children().empty(); | 745 return !readback_layer_tree_->children().empty(); |
| 845 } | 746 } |
| 846 | 747 |
| 847 } // namespace content | 748 } // namespace content |
| OLD | NEW |