OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/android/in_process/synchronous_compositor_impl.h" | 5 #include "content/browser/android/in_process/synchronous_compositor_impl.h" |
6 | 6 |
7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/synchronization/lock.h" | 9 #include "base/synchronization/lock.h" |
10 #include "cc/input/input_handler.h" | 10 #include "cc/input/input_handler.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
69 | 69 |
70 scoped_refptr<cc::ContextProvider> context_provider_; | 70 scoped_refptr<cc::ContextProvider> context_provider_; |
71 gpu::GLInProcessContext* gl_in_process_context_; | 71 gpu::GLInProcessContext* gl_in_process_context_; |
72 | 72 |
73 DISALLOW_COPY_AND_ASSIGN(VideoContextProvider); | 73 DISALLOW_COPY_AND_ASSIGN(VideoContextProvider); |
74 }; | 74 }; |
75 | 75 |
76 class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { | 76 class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { |
77 public: | 77 public: |
78 SynchronousCompositorFactoryImpl() | 78 SynchronousCompositorFactoryImpl() |
79 : wrapped_gl_context_for_main_thread_(NULL) { | 79 : wrapped_gl_context_for_main_thread_(NULL), |
80 num_hardware_compositors_(0) { | |
80 SynchronousCompositorFactory::SetInstance(this); | 81 SynchronousCompositorFactory::SetInstance(this); |
81 } | 82 } |
82 | 83 |
83 // SynchronousCompositorFactory | 84 // SynchronousCompositorFactory |
84 virtual scoped_refptr<base::MessageLoopProxy> | 85 virtual scoped_refptr<base::MessageLoopProxy> |
85 GetCompositorMessageLoop() OVERRIDE { | 86 GetCompositorMessageLoop() OVERRIDE { |
86 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); | 87 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); |
87 } | 88 } |
88 | 89 |
89 virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface( | 90 virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 if (!context.get()) | 131 if (!context.get()) |
131 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(); | 132 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(); |
132 | 133 |
133 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>( | 134 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>( |
134 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext( | 135 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext( |
135 context.Pass(), attributes)); | 136 context.Pass(), attributes)); |
136 } | 137 } |
137 | 138 |
138 virtual scoped_refptr<cc::ContextProvider> | 139 virtual scoped_refptr<cc::ContextProvider> |
139 GetOffscreenContextProviderForMainThread() OVERRIDE { | 140 GetOffscreenContextProviderForMainThread() OVERRIDE { |
140 if (!offscreen_context_for_main_thread_.get() || | 141 bool can_create_context = CanCreateMainThreadContext(); |
141 offscreen_context_for_main_thread_->DestroyedOnMainThread()) { | 142 if (can_create_context && |
143 (!offscreen_context_for_main_thread_.get() || | |
144 offscreen_context_for_main_thread_->DestroyedOnMainThread())) { | |
142 offscreen_context_for_main_thread_ = | 145 offscreen_context_for_main_thread_ = |
143 webkit::gpu::ContextProviderInProcess::Create( | 146 webkit::gpu::ContextProviderInProcess::Create( |
144 CreateOffscreenContext()); | 147 CreateOffscreenContext()); |
145 if (offscreen_context_for_main_thread_.get() && | 148 } |
146 !offscreen_context_for_main_thread_->BindToCurrentThread()) { | 149 |
147 offscreen_context_for_main_thread_ = NULL; | 150 if (!can_create_context || |
joth
2013/09/05 20:47:12
splicing the can_create_context into both expressi
boliu
2013/09/05 23:21:25
Done.
| |
148 wrapped_gl_context_for_main_thread_ = NULL; | 151 (offscreen_context_for_main_thread_.get() && |
149 } | 152 !offscreen_context_for_main_thread_->BindToCurrentThread())) { |
153 offscreen_context_for_main_thread_ = NULL; | |
154 wrapped_gl_context_for_main_thread_ = NULL; | |
150 } | 155 } |
151 return offscreen_context_for_main_thread_; | 156 return offscreen_context_for_main_thread_; |
152 } | 157 } |
153 | 158 |
154 // This is called on both renderer main thread (offscreen context creation | 159 // This is called on both renderer main thread (offscreen context creation |
155 // path shared between cross-process and in-process platforms) and renderer | 160 // path shared between cross-process and in-process platforms) and renderer |
156 // compositor impl thread (InitializeHwDraw) in order to support Android | 161 // compositor impl thread (InitializeHwDraw) in order to support Android |
157 // WebView synchronously enable and disable hardware mode multiple times in | 162 // WebView synchronously enable and disable hardware mode multiple times in |
158 // the same task. This is ok because in-process WGC3D creation may happen on | 163 // the same task. This is ok because in-process WGC3D creation may happen on |
159 // any thread and is lightweight. | 164 // any thread and is lightweight. |
160 virtual scoped_refptr<cc::ContextProvider> | 165 virtual scoped_refptr<cc::ContextProvider> |
161 GetOffscreenContextProviderForCompositorThread() OVERRIDE { | 166 GetOffscreenContextProviderForCompositorThread() OVERRIDE { |
162 base::AutoLock lock(offscreen_context_for_compositor_thread_creation_lock_); | 167 base::AutoLock lock(offscreen_context_for_compositor_thread_lock_); |
163 if (!offscreen_context_for_compositor_thread_.get() || | 168 if (!offscreen_context_for_compositor_thread_.get() || |
164 offscreen_context_for_compositor_thread_->DestroyedOnMainThread()) { | 169 offscreen_context_for_compositor_thread_->DestroyedOnMainThread()) { |
165 offscreen_context_for_compositor_thread_ = | 170 offscreen_context_for_compositor_thread_ = |
166 webkit::gpu::ContextProviderInProcess::CreateOffscreen(); | 171 webkit::gpu::ContextProviderInProcess::CreateOffscreen(); |
167 } | 172 } |
168 return offscreen_context_for_compositor_thread_; | 173 return offscreen_context_for_compositor_thread_; |
169 } | 174 } |
170 | 175 |
171 virtual scoped_ptr<StreamTextureFactory> CreateStreamTextureFactory( | 176 virtual scoped_ptr<StreamTextureFactory> CreateStreamTextureFactory( |
172 int view_id) OVERRIDE { | 177 int view_id) OVERRIDE { |
173 scoped_refptr<VideoContextProvider> context_provider = | 178 scoped_refptr<VideoContextProvider> context_provider; |
174 new VideoContextProvider(offscreen_context_for_main_thread_, | 179 if (CanCreateMainThreadContext()) { |
175 wrapped_gl_context_for_main_thread_); | 180 context_provider = |
181 new VideoContextProvider(offscreen_context_for_main_thread_, | |
182 wrapped_gl_context_for_main_thread_); | |
183 } | |
176 return make_scoped_ptr(new StreamTextureFactorySynchronousImpl( | 184 return make_scoped_ptr(new StreamTextureFactorySynchronousImpl( |
177 context_provider.get(), view_id)) | 185 context_provider.get(), view_id)) |
178 .PassAs<StreamTextureFactory>(); | 186 .PassAs<StreamTextureFactory>(); |
179 } | 187 } |
180 | 188 |
189 void CompositorInitializedHardwareDraw(SynchronousCompositorImpl* compositor); | |
190 void CompositorReleasedHardwareDraw(SynchronousCompositorImpl* compositor); | |
191 | |
181 private: | 192 private: |
193 void ReleaseGlobalHardwareResources(); | |
194 bool CanCreateMainThreadContext(); | |
195 | |
182 SynchronousInputEventFilter synchronous_input_event_filter_; | 196 SynchronousInputEventFilter synchronous_input_event_filter_; |
183 | 197 |
184 // Only guards construction of |offscreen_context_for_compositor_thread_|, | 198 // Only guards construction and destruction of |
185 // not usage. | 199 // |offscreen_context_for_compositor_thread_|, not usage. |
186 base::Lock offscreen_context_for_compositor_thread_creation_lock_; | 200 base::Lock offscreen_context_for_compositor_thread_lock_; |
187 scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_; | 201 scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_; |
188 // This is a pointer to the context owned by | 202 // This is a pointer to the context owned by |
189 // |offscreen_context_for_main_thread_|. | 203 // |offscreen_context_for_main_thread_|. |
190 gpu::GLInProcessContext* wrapped_gl_context_for_main_thread_; | 204 gpu::GLInProcessContext* wrapped_gl_context_for_main_thread_; |
191 scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_; | 205 scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_; |
206 | |
207 base::Lock num_hardware_compositor_lock_; | |
joth
2013/09/05 20:47:12
comment that num_hardware_compositors_ is always u
boliu
2013/09/05 23:21:25
Both done
| |
208 unsigned int num_hardware_compositors_; | |
192 }; | 209 }; |
193 | 210 |
211 void SynchronousCompositorFactoryImpl::CompositorInitializedHardwareDraw( | |
212 SynchronousCompositorImpl* compositor) { | |
213 base::AutoLock lock(num_hardware_compositor_lock_); | |
214 num_hardware_compositors_++; | |
215 } | |
216 | |
217 void SynchronousCompositorFactoryImpl::CompositorReleasedHardwareDraw( | |
218 SynchronousCompositorImpl* compositor) { | |
219 bool should_release_resources = false; | |
220 { | |
221 base::AutoLock lock(num_hardware_compositor_lock_); | |
222 DCHECK_GT(num_hardware_compositors_, 0u); | |
223 num_hardware_compositors_--; | |
224 should_release_resources = num_hardware_compositors_ == 0u; | |
225 } | |
226 if (should_release_resources) | |
227 ReleaseGlobalHardwareResources(); | |
228 } | |
229 | |
230 void SynchronousCompositorFactoryImpl::ReleaseGlobalHardwareResources() { | |
231 { | |
232 base::AutoLock lock(offscreen_context_for_compositor_thread_lock_); | |
233 offscreen_context_for_compositor_thread_ = NULL; | |
234 } | |
235 | |
236 // TODO(boliu): Properly clean up command buffer server of main thread | |
237 // context here. | |
238 } | |
239 | |
240 bool SynchronousCompositorFactoryImpl::CanCreateMainThreadContext() { | |
241 base::AutoLock lock(num_hardware_compositor_lock_); | |
242 return num_hardware_compositors_ > 0; | |
243 } | |
244 | |
194 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = | 245 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = |
195 LAZY_INSTANCE_INITIALIZER; | 246 LAZY_INSTANCE_INITIALIZER; |
196 | 247 |
197 } // namespace | 248 } // namespace |
198 | 249 |
199 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); | 250 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); |
200 | 251 |
201 // static | 252 // static |
202 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id, | 253 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id, |
203 int routing_id) { | 254 int routing_id) { |
(...skipping 30 matching lines...) Expand all Loading... | |
234 void SynchronousCompositorImpl::SetClient( | 285 void SynchronousCompositorImpl::SetClient( |
235 SynchronousCompositorClient* compositor_client) { | 286 SynchronousCompositorClient* compositor_client) { |
236 DCHECK(CalledOnValidThread()); | 287 DCHECK(CalledOnValidThread()); |
237 compositor_client_ = compositor_client; | 288 compositor_client_ = compositor_client; |
238 } | 289 } |
239 | 290 |
240 bool SynchronousCompositorImpl::InitializeHwDraw( | 291 bool SynchronousCompositorImpl::InitializeHwDraw( |
241 scoped_refptr<gfx::GLSurface> surface) { | 292 scoped_refptr<gfx::GLSurface> surface) { |
242 DCHECK(CalledOnValidThread()); | 293 DCHECK(CalledOnValidThread()); |
243 DCHECK(output_surface_); | 294 DCHECK(output_surface_); |
244 return output_surface_->InitializeHwDraw( | 295 bool success = output_surface_->InitializeHwDraw( |
245 surface, | 296 surface, |
246 g_factory.Get().GetOffscreenContextProviderForCompositorThread()); | 297 g_factory.Get().GetOffscreenContextProviderForCompositorThread()); |
298 if (success) | |
299 g_factory.Get().CompositorInitializedHardwareDraw(this); | |
300 return success; | |
247 } | 301 } |
248 | 302 |
249 void SynchronousCompositorImpl::ReleaseHwDraw() { | 303 void SynchronousCompositorImpl::ReleaseHwDraw() { |
250 DCHECK(CalledOnValidThread()); | 304 DCHECK(CalledOnValidThread()); |
251 DCHECK(output_surface_); | 305 DCHECK(output_surface_); |
252 return output_surface_->ReleaseHwDraw(); | 306 output_surface_->ReleaseHwDraw(); |
307 g_factory.Get().CompositorReleasedHardwareDraw(this); | |
253 } | 308 } |
254 | 309 |
255 bool SynchronousCompositorImpl::DemandDrawHw( | 310 bool SynchronousCompositorImpl::DemandDrawHw( |
256 gfx::Size view_size, | 311 gfx::Size view_size, |
257 const gfx::Transform& transform, | 312 const gfx::Transform& transform, |
258 gfx::Rect damage_area, | 313 gfx::Rect damage_area, |
259 bool stencil_enabled) { | 314 bool stencil_enabled) { |
260 DCHECK(CalledOnValidThread()); | 315 DCHECK(CalledOnValidThread()); |
261 DCHECK(output_surface_); | 316 DCHECK(output_surface_); |
262 | 317 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 g_factory.Get(); // Ensure it's initialized. | 429 g_factory.Get(); // Ensure it's initialized. |
375 SynchronousCompositorImpl::CreateForWebContents(contents); | 430 SynchronousCompositorImpl::CreateForWebContents(contents); |
376 } | 431 } |
377 if (SynchronousCompositorImpl* instance = | 432 if (SynchronousCompositorImpl* instance = |
378 SynchronousCompositorImpl::FromWebContents(contents)) { | 433 SynchronousCompositorImpl::FromWebContents(contents)) { |
379 instance->SetClient(client); | 434 instance->SetClient(client); |
380 } | 435 } |
381 } | 436 } |
382 | 437 |
383 } // namespace content | 438 } // namespace content |
OLD | NEW |