OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "services/ui/surfaces/surfaces_context_provider.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/bind_helpers.h" | |
11 #include "base/command_line.h" | |
12 #include "base/single_thread_task_runner.h" | |
13 #include "base/synchronization/waitable_event.h" | |
14 #include "base/threading/thread_task_runner_handle.h" | |
15 #include "build/build_config.h" | |
16 #include "cc/output/context_cache_controller.h" | |
17 #include "gpu/command_buffer/client/gles2_cmd_helper.h" | |
18 #include "gpu/command_buffer/client/gles2_implementation.h" | |
19 #include "gpu/command_buffer/client/shared_memory_limits.h" | |
20 #include "gpu/command_buffer/client/transfer_buffer.h" | |
21 #include "gpu/ipc/client/command_buffer_proxy_impl.h" | |
22 #include "gpu/ipc/client/gpu_channel_host.h" | |
23 #include "services/ui/common/switches.h" | |
24 #include "services/ui/surfaces/surfaces_context_provider_delegate.h" | |
25 #include "ui/gl/gpu_preference.h" | |
26 #include "url/gurl.h" | |
27 | |
28 namespace ui { | |
29 | |
30 SurfacesContextProvider::SurfacesContextProvider( | |
31 gfx::AcceleratedWidget widget, | |
32 scoped_refptr<gpu::GpuChannelHost> gpu_channel) | |
33 : delegate_(nullptr), | |
34 widget_(widget), | |
35 task_runner_(base::ThreadTaskRunnerHandle::Get()) { | |
36 gpu::CommandBufferProxyImpl* shared_command_buffer = nullptr; | |
37 gpu::GpuStreamId stream_id = gpu::GpuStreamId::GPU_STREAM_DEFAULT; | |
38 gpu::GpuStreamPriority stream_priority = gpu::GpuStreamPriority::NORMAL; | |
39 gpu::gles2::ContextCreationAttribHelper attributes; | |
40 attributes.alpha_size = -1; | |
41 attributes.depth_size = 0; | |
42 attributes.stencil_size = 0; | |
43 attributes.samples = 0; | |
44 attributes.sample_buffers = 0; | |
45 attributes.bind_generates_resource = false; | |
46 attributes.lose_context_when_out_of_memory = true; | |
47 GURL active_url; | |
48 command_buffer_proxy_impl_ = gpu::CommandBufferProxyImpl::Create( | |
49 std::move(gpu_channel), widget, shared_command_buffer, stream_id, | |
50 stream_priority, attributes, active_url, task_runner_); | |
51 CHECK(command_buffer_proxy_impl_); | |
52 command_buffer_proxy_impl_->SetSwapBuffersCompletionCallback( | |
53 base::Bind(&SurfacesContextProvider::OnGpuSwapBuffersCompleted, | |
54 base::Unretained(this))); | |
55 command_buffer_proxy_impl_->SetUpdateVSyncParametersCallback( | |
56 base::Bind(&SurfacesContextProvider::OnUpdateVSyncParameters, | |
57 base::Unretained(this))); | |
58 } | |
59 | |
60 void SurfacesContextProvider::SetDelegate( | |
61 SurfacesContextProviderDelegate* delegate) { | |
62 DCHECK(!delegate_); | |
63 delegate_ = delegate; | |
64 } | |
65 | |
66 // This routine needs to be safe to call more than once. | |
67 // This is called when we have an accelerated widget. | |
68 bool SurfacesContextProvider::BindToCurrentThread() { | |
69 if (implementation_) | |
70 return true; | |
71 | |
72 // SurfacesContextProvider should always live on the same thread as the | |
73 // Window Manager. | |
74 DCHECK(CalledOnValidThread()); | |
75 if (!command_buffer_proxy_impl_) | |
76 return false; | |
77 gpu::GpuControl* gpu_control = command_buffer_proxy_impl_.get(); | |
78 gpu::CommandBuffer* command_buffer = command_buffer_proxy_impl_.get(); | |
79 | |
80 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer)); | |
81 constexpr gpu::SharedMemoryLimits default_limits; | |
82 if (!gles2_helper_->Initialize(default_limits.command_buffer_size)) | |
83 return false; | |
84 gles2_helper_->SetAutomaticFlushes(false); | |
85 transfer_buffer_.reset(new gpu::TransferBuffer(gles2_helper_.get())); | |
86 capabilities_ = gpu_control->GetCapabilities(); | |
87 bool bind_generates_resource = | |
88 !!capabilities_.bind_generates_resource_chromium; | |
89 // TODO(piman): Some contexts (such as compositor) want this to be true, so | |
90 // this needs to be a public parameter. | |
91 bool lose_context_when_out_of_memory = false; | |
92 bool support_client_side_arrays = false; | |
93 implementation_.reset(new gpu::gles2::GLES2Implementation( | |
94 gles2_helper_.get(), NULL, transfer_buffer_.get(), | |
95 bind_generates_resource, lose_context_when_out_of_memory, | |
96 support_client_side_arrays, gpu_control)); | |
97 cache_controller_.reset( | |
98 new cc::ContextCacheController(implementation_.get(), task_runner_)); | |
99 return implementation_->Initialize( | |
100 default_limits.start_transfer_buffer_size, | |
101 default_limits.min_transfer_buffer_size, | |
102 default_limits.max_transfer_buffer_size, | |
103 default_limits.mapped_memory_reclaim_limit); | |
104 } | |
105 | |
106 gpu::gles2::GLES2Interface* SurfacesContextProvider::ContextGL() { | |
107 DCHECK(implementation_); | |
108 return implementation_.get(); | |
109 } | |
110 | |
111 gpu::ContextSupport* SurfacesContextProvider::ContextSupport() { | |
112 return implementation_.get(); | |
113 } | |
114 | |
115 class GrContext* SurfacesContextProvider::GrContext() { | |
116 return NULL; | |
117 } | |
118 | |
119 cc::ContextCacheController* SurfacesContextProvider::CacheController() { | |
120 return cache_controller_.get(); | |
121 } | |
122 | |
123 void SurfacesContextProvider::InvalidateGrContext(uint32_t state) {} | |
124 | |
125 gpu::Capabilities SurfacesContextProvider::ContextCapabilities() { | |
126 return capabilities_; | |
127 } | |
128 | |
129 base::Lock* SurfacesContextProvider::GetLock() { | |
130 // This context provider is not used on multiple threads. | |
131 NOTREACHED(); | |
132 return nullptr; | |
133 } | |
134 | |
135 void SurfacesContextProvider::SetLostContextCallback( | |
136 const LostContextCallback& lost_context_callback) { | |
137 implementation_->SetLostContextCallback(lost_context_callback); | |
138 } | |
139 | |
140 SurfacesContextProvider::~SurfacesContextProvider() { | |
141 implementation_->Flush(); | |
142 implementation_.reset(); | |
143 transfer_buffer_.reset(); | |
144 gles2_helper_.reset(); | |
145 command_buffer_proxy_impl_.reset(); | |
146 } | |
147 | |
148 void SurfacesContextProvider::OnGpuSwapBuffersCompleted( | |
149 const std::vector<ui::LatencyInfo>& latency_info, | |
150 gfx::SwapResult result, | |
151 const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) { | |
152 if (!swap_buffers_completion_callback_.is_null()) { | |
153 swap_buffers_completion_callback_.Run(result); | |
154 } | |
155 } | |
156 | |
157 void SurfacesContextProvider::OnUpdateVSyncParameters( | |
158 base::TimeTicks timebase, | |
159 base::TimeDelta interval) { | |
160 if (delegate_) | |
161 delegate_->OnVSyncParametersUpdated(timebase, interval); | |
162 } | |
163 | |
164 void SurfacesContextProvider::SetSwapBuffersCompletionCallback( | |
165 gl::GLSurface::SwapCompletionCallback callback) { | |
166 swap_buffers_completion_callback_ = callback; | |
167 } | |
168 | |
169 } // namespace ui | |
OLD | NEW |