| 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/gpu_process_transport_factory.h" | 5 #include "content/browser/compositor/gpu_process_transport_factory.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 using gpu::gles2::GLES2Interface; | 51 using gpu::gles2::GLES2Interface; |
| 52 | 52 |
| 53 namespace content { | 53 namespace content { |
| 54 | 54 |
| 55 struct GpuProcessTransportFactory::PerCompositorData { | 55 struct GpuProcessTransportFactory::PerCompositorData { |
| 56 int surface_id; | 56 int surface_id; |
| 57 scoped_refptr<ReflectorImpl> reflector; | 57 scoped_refptr<ReflectorImpl> reflector; |
| 58 }; | 58 }; |
| 59 | 59 |
| 60 GpuProcessTransportFactory::GpuProcessTransportFactory() | 60 GpuProcessTransportFactory::GpuProcessTransportFactory() |
| 61 : callback_factory_(this), offscreen_content_bound_to_other_thread_(false) { | 61 : callback_factory_(this) { |
| 62 output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy( | 62 output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy( |
| 63 &output_surface_map_); | 63 &output_surface_map_); |
| 64 } | 64 } |
| 65 | 65 |
| 66 GpuProcessTransportFactory::~GpuProcessTransportFactory() { | 66 GpuProcessTransportFactory::~GpuProcessTransportFactory() { |
| 67 DCHECK(per_compositor_data_.empty()); | 67 DCHECK(per_compositor_data_.empty()); |
| 68 | 68 |
| 69 // Make sure the lost context callback doesn't try to run during destruction. | 69 // Make sure the lost context callback doesn't try to run during destruction. |
| 70 callback_factory_.InvalidateWeakPtrs(); | 70 callback_factory_.InvalidateWeakPtrs(); |
| 71 | |
| 72 if (offscreen_compositor_contexts_.get() && | |
| 73 offscreen_content_bound_to_other_thread_) { | |
| 74 // Leak shared contexts on other threads, as we can not get to the correct | |
| 75 // thread to destroy them. | |
| 76 offscreen_compositor_contexts_->set_leak_on_destroy(); | |
| 77 } | |
| 78 } | 71 } |
| 79 | 72 |
| 80 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> | 73 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> |
| 81 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext() { | 74 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext() { |
| 82 return CreateContextCommon(0); | 75 return CreateContextCommon(0); |
| 83 } | 76 } |
| 84 | 77 |
| 85 scoped_ptr<cc::SoftwareOutputDevice> CreateSoftwareOutputDevice( | 78 scoped_ptr<cc::SoftwareOutputDevice> CreateSoftwareOutputDevice( |
| 86 ui::Compositor* compositor) { | 79 ui::Compositor* compositor) { |
| 87 #if defined(OS_WIN) | 80 #if defined(OS_WIN) |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 ImageTransportFactoryObserver* observer) { | 244 ImageTransportFactoryObserver* observer) { |
| 252 observer_list_.AddObserver(observer); | 245 observer_list_.AddObserver(observer); |
| 253 } | 246 } |
| 254 | 247 |
| 255 void GpuProcessTransportFactory::RemoveObserver( | 248 void GpuProcessTransportFactory::RemoveObserver( |
| 256 ImageTransportFactoryObserver* observer) { | 249 ImageTransportFactoryObserver* observer) { |
| 257 observer_list_.RemoveObserver(observer); | 250 observer_list_.RemoveObserver(observer); |
| 258 } | 251 } |
| 259 | 252 |
| 260 scoped_refptr<cc::ContextProvider> | 253 scoped_refptr<cc::ContextProvider> |
| 261 GpuProcessTransportFactory::OffscreenCompositorContextProvider() { | |
| 262 // Don't check for DestroyedOnMainThread() here. We hear about context | |
| 263 // loss for this context through the lost context callback. If the context | |
| 264 // is lost, we want to leave this ContextProvider available until the lost | |
| 265 // context notification is sent to the ImageTransportFactoryObserver clients. | |
| 266 if (offscreen_compositor_contexts_.get()) | |
| 267 return offscreen_compositor_contexts_; | |
| 268 | |
| 269 offscreen_compositor_contexts_ = ContextProviderCommandBuffer::Create( | |
| 270 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(), | |
| 271 "Compositor-Offscreen"); | |
| 272 offscreen_content_bound_to_other_thread_ = | |
| 273 ui::Compositor::WasInitializedWithThread(); | |
| 274 | |
| 275 return offscreen_compositor_contexts_; | |
| 276 } | |
| 277 | |
| 278 scoped_refptr<cc::ContextProvider> | |
| 279 GpuProcessTransportFactory::SharedMainThreadContextProvider() { | 254 GpuProcessTransportFactory::SharedMainThreadContextProvider() { |
| 280 if (shared_main_thread_contexts_.get()) | 255 if (shared_main_thread_contexts_.get()) |
| 281 return shared_main_thread_contexts_; | 256 return shared_main_thread_contexts_; |
| 282 | 257 |
| 283 // In threaded compositing mode, we have to create our own context for the | 258 // In threaded compositing mode, we have to create our own context for the |
| 284 // main thread since the compositor's context will be bound to the | 259 // main thread since the compositor's context will be bound to the |
| 285 // compositor thread. When not in threaded mode, we still need a separate | 260 // compositor thread. When not in threaded mode, we still need a separate |
| 286 // context so that skia and gl_helper don't step on each other. | 261 // context so that skia and gl_helper don't step on each other. |
| 287 shared_main_thread_contexts_ = ContextProviderCommandBuffer::Create( | 262 shared_main_thread_contexts_ = ContextProviderCommandBuffer::Create( |
| 288 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(), | 263 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(), |
| 289 "Offscreen-MainThread"); | 264 "Offscreen-MainThread"); |
| 290 | 265 |
| 291 if (shared_main_thread_contexts_) { | 266 if (shared_main_thread_contexts_) { |
| 292 shared_main_thread_contexts_->SetLostContextCallback( | 267 shared_main_thread_contexts_->SetLostContextCallback( |
| 293 base::Bind(&GpuProcessTransportFactory:: | 268 base::Bind(&GpuProcessTransportFactory:: |
| 294 OnLostMainThreadSharedContextInsideCallback, | 269 OnLostMainThreadSharedContextInsideCallback, |
| 295 callback_factory_.GetWeakPtr())); | 270 callback_factory_.GetWeakPtr())); |
| 296 if (!shared_main_thread_contexts_->BindToCurrentThread()) { | 271 if (!shared_main_thread_contexts_->BindToCurrentThread()) |
| 297 shared_main_thread_contexts_ = NULL; | 272 shared_main_thread_contexts_ = NULL; |
| 298 offscreen_compositor_contexts_ = NULL; | |
| 299 } | |
| 300 } | 273 } |
| 301 return shared_main_thread_contexts_; | 274 return shared_main_thread_contexts_; |
| 302 } | 275 } |
| 303 | 276 |
| 304 GpuProcessTransportFactory::PerCompositorData* | 277 GpuProcessTransportFactory::PerCompositorData* |
| 305 GpuProcessTransportFactory::CreatePerCompositorData( | 278 GpuProcessTransportFactory::CreatePerCompositorData( |
| 306 ui::Compositor* compositor) { | 279 ui::Compositor* compositor) { |
| 307 DCHECK(!per_compositor_data_[compositor]); | 280 DCHECK(!per_compositor_data_[compositor]); |
| 308 | 281 |
| 309 gfx::AcceleratedWidget widget = compositor->widget(); | 282 gfx::AcceleratedWidget widget = compositor->widget(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 callback_factory_.GetWeakPtr())); | 332 callback_factory_.GetWeakPtr())); |
| 360 } | 333 } |
| 361 | 334 |
| 362 void GpuProcessTransportFactory::OnLostMainThreadSharedContext() { | 335 void GpuProcessTransportFactory::OnLostMainThreadSharedContext() { |
| 363 LOG(ERROR) << "Lost UI shared context."; | 336 LOG(ERROR) << "Lost UI shared context."; |
| 364 | 337 |
| 365 // Keep old resources around while we call the observers, but ensure that | 338 // Keep old resources around while we call the observers, but ensure that |
| 366 // new resources are created if needed. | 339 // new resources are created if needed. |
| 367 // Kill shared contexts for both threads in tandem so they are always in | 340 // Kill shared contexts for both threads in tandem so they are always in |
| 368 // the same share group. | 341 // the same share group. |
| 369 scoped_refptr<cc::ContextProvider> lost_offscreen_compositor_contexts = | |
| 370 offscreen_compositor_contexts_; | |
| 371 scoped_refptr<cc::ContextProvider> lost_shared_main_thread_contexts = | 342 scoped_refptr<cc::ContextProvider> lost_shared_main_thread_contexts = |
| 372 shared_main_thread_contexts_; | 343 shared_main_thread_contexts_; |
| 373 offscreen_compositor_contexts_ = NULL; | |
| 374 shared_main_thread_contexts_ = NULL; | 344 shared_main_thread_contexts_ = NULL; |
| 375 | 345 |
| 376 scoped_ptr<GLHelper> lost_gl_helper = gl_helper_.Pass(); | 346 scoped_ptr<GLHelper> lost_gl_helper = gl_helper_.Pass(); |
| 377 | 347 |
| 378 FOR_EACH_OBSERVER(ImageTransportFactoryObserver, | 348 FOR_EACH_OBSERVER(ImageTransportFactoryObserver, |
| 379 observer_list_, | 349 observer_list_, |
| 380 OnLostResources()); | 350 OnLostResources()); |
| 381 | 351 |
| 382 // Kill things that use the shared context before killing the shared context. | 352 // Kill things that use the shared context before killing the shared context. |
| 383 lost_gl_helper.reset(); | 353 lost_gl_helper.reset(); |
| 384 lost_offscreen_compositor_contexts = NULL; | |
| 385 lost_shared_main_thread_contexts = NULL; | 354 lost_shared_main_thread_contexts = NULL; |
| 386 } | 355 } |
| 387 | 356 |
| 388 } // namespace content | 357 } // namespace content |
| OLD | NEW |