OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/common/gpu/client/context_provider_command_buffer.h" | 5 #include "content/common/gpu/client/context_provider_command_buffer.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
12 #include "base/thread_task_runner_handle.h" | |
12 #include "cc/output/managed_memory_policy.h" | 13 #include "cc/output/managed_memory_policy.h" |
13 #include "content/common/gpu/client/grcontext_for_webgraphicscontext3d.h" | 14 #include "content/common/gpu/client/grcontext_for_webgraphicscontext3d.h" |
14 #include "gpu/command_buffer/client/gles2_implementation.h" | 15 #include "gpu/command_buffer/client/gles2_implementation.h" |
15 #include "third_party/skia/include/gpu/GrContext.h" | 16 #include "third_party/skia/include/gpu/GrContext.h" |
16 | 17 |
17 namespace content { | 18 namespace content { |
18 | 19 |
19 class ContextProviderCommandBuffer::LostContextCallbackProxy | 20 class ContextProviderCommandBuffer::LostContextCallbackProxy |
20 : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback { | 21 : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback { |
21 public: | 22 public: |
22 explicit LostContextCallbackProxy(ContextProviderCommandBuffer* provider) | 23 explicit LostContextCallbackProxy(ContextProviderCommandBuffer* provider) |
23 : provider_(provider) { | 24 : provider_(provider) { |
24 provider_->context3d_->setContextLostCallback(this); | 25 provider_->context3d_->setContextLostCallback(this); |
25 } | 26 } |
26 | 27 |
27 virtual ~LostContextCallbackProxy() { | 28 virtual ~LostContextCallbackProxy() { |
28 provider_->context3d_->setContextLostCallback(NULL); | 29 provider_->context3d_->setContextLostCallback(NULL); |
29 } | 30 } |
30 | 31 |
31 virtual void onContextLost() { | 32 virtual void onContextLost() { |
32 provider_->OnLostContext(); | 33 provider_->OnLostContext(); |
33 } | 34 } |
34 | 35 |
35 private: | 36 private: |
36 ContextProviderCommandBuffer* provider_; | 37 ContextProviderCommandBuffer* provider_; |
37 }; | 38 }; |
38 | 39 |
40 void DestroyContext3d( | |
41 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d) { | |
42 context3d.reset(); | |
43 } | |
44 | |
39 scoped_refptr<ContextProviderCommandBuffer> | 45 scoped_refptr<ContextProviderCommandBuffer> |
40 ContextProviderCommandBuffer::Create( | 46 ContextProviderCommandBuffer::Create( |
41 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d, | 47 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d, |
42 CommandBufferContextType type) { | 48 CommandBufferContextType type) { |
43 if (!context3d) | 49 if (!context3d) |
44 return NULL; | 50 return NULL; |
45 | 51 |
46 return new ContextProviderCommandBuffer(context3d.Pass(), type); | 52 return new ContextProviderCommandBuffer(context3d.Pass(), type); |
47 } | 53 } |
48 | 54 |
(...skipping 15 matching lines...) Expand all Loading... | |
64 | 70 |
65 base::AutoLock lock(main_thread_lock_); | 71 base::AutoLock lock(main_thread_lock_); |
66 | 72 |
67 // Destroy references to the context3d_ before leaking it. | 73 // Destroy references to the context3d_ before leaking it. |
68 if (context3d_->GetCommandBufferProxy()) { | 74 if (context3d_->GetCommandBufferProxy()) { |
69 context3d_->GetCommandBufferProxy()->SetLock(nullptr); | 75 context3d_->GetCommandBufferProxy()->SetLock(nullptr); |
70 context3d_->GetCommandBufferProxy()->SetMemoryAllocationChangedCallback( | 76 context3d_->GetCommandBufferProxy()->SetMemoryAllocationChangedCallback( |
71 CommandBufferProxyImpl::MemoryAllocationChangedCallback()); | 77 CommandBufferProxyImpl::MemoryAllocationChangedCallback()); |
72 } | 78 } |
73 lost_context_callback_proxy_.reset(); | 79 lost_context_callback_proxy_.reset(); |
80 | |
81 // Destroy the context3d_ on the same thread it was initialized on. | |
82 if (context3d_task_runner_.get() && base::ThreadTaskRunnerHandle::IsSet() && | |
danakj
2015/09/02 18:19:28
you don't need .get() when checking boolness
reveman
2015/09/02 18:53:08
Done.
| |
83 base::ThreadTaskRunnerHandle::Get() != context3d_task_runner_.get()) { | |
danakj
2015/09/02 18:19:27
I dislike the pattern of "if not on the thread, po
reveman
2015/09/02 18:53:08
I agree and that's what I initially did but it bre
danakj
2015/09/02 21:15:36
I guess this all makes me kinda sad then. Maybe we
reveman
2015/09/02 21:32:35
I'm looking at making this not refcounted. In a se
| |
84 context3d_task_runner_->PostTask( | |
85 FROM_HERE, base::Bind(&DestroyContext3d, base::Passed(&context3d_))); | |
piman
2015/09/02 18:26:08
The potential issue is that it may just mask the p
| |
86 } | |
74 } | 87 } |
75 | 88 |
76 | 89 |
77 CommandBufferProxyImpl* ContextProviderCommandBuffer::GetCommandBufferProxy() { | 90 CommandBufferProxyImpl* ContextProviderCommandBuffer::GetCommandBufferProxy() { |
78 return context3d_->GetCommandBufferProxy(); | 91 return context3d_->GetCommandBufferProxy(); |
79 } | 92 } |
80 | 93 |
81 WebGraphicsContext3DCommandBufferImpl* | 94 WebGraphicsContext3DCommandBufferImpl* |
82 ContextProviderCommandBuffer::WebContext3D() { | 95 ContextProviderCommandBuffer::WebContext3D() { |
83 DCHECK(context3d_); | 96 DCHECK(context3d_); |
84 DCHECK(lost_context_callback_proxy_); // Is bound to thread. | 97 DCHECK(lost_context_callback_proxy_); // Is bound to thread. |
85 DCHECK(context_thread_checker_.CalledOnValidThread()); | 98 DCHECK(context_thread_checker_.CalledOnValidThread()); |
86 | 99 |
87 return context3d_.get(); | 100 return context3d_.get(); |
88 } | 101 } |
89 | 102 |
90 bool ContextProviderCommandBuffer::BindToCurrentThread() { | 103 bool ContextProviderCommandBuffer::BindToCurrentThread() { |
91 // This is called on the thread the context will be used. | 104 // This is called on the thread the context will be used. |
92 DCHECK(context_thread_checker_.CalledOnValidThread()); | 105 DCHECK(context_thread_checker_.CalledOnValidThread()); |
93 | 106 |
94 if (lost_context_callback_proxy_) | 107 if (lost_context_callback_proxy_) |
95 return true; | 108 return true; |
96 | 109 |
97 context3d_->SetContextType(context_type_); | 110 context3d_->SetContextType(context_type_); |
98 if (!context3d_->InitializeOnCurrentThread()) | 111 if (!context3d_->InitializeOnCurrentThread()) |
99 return false; | 112 return false; |
100 | 113 |
114 // The context3d_ should be destroyed on the thread it was initialized. | |
115 if (base::ThreadTaskRunnerHandle::IsSet()) | |
116 context3d_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | |
117 | |
101 InitializeCapabilities(); | 118 InitializeCapabilities(); |
102 | 119 |
103 std::string unique_context_name = | 120 std::string unique_context_name = |
104 base::StringPrintf("%s-%p", debug_name_.c_str(), context3d_.get()); | 121 base::StringPrintf("%s-%p", debug_name_.c_str(), context3d_.get()); |
105 context3d_->traceBeginCHROMIUM("gpu_toplevel", unique_context_name.c_str()); | 122 context3d_->traceBeginCHROMIUM("gpu_toplevel", unique_context_name.c_str()); |
106 | 123 |
107 lost_context_callback_proxy_.reset(new LostContextCallbackProxy(this)); | 124 lost_context_callback_proxy_.reset(new LostContextCallbackProxy(this)); |
108 return true; | 125 return true; |
109 } | 126 } |
110 | 127 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
175 } | 192 } |
176 | 193 |
177 void ContextProviderCommandBuffer::DeleteCachedResources() { | 194 void ContextProviderCommandBuffer::DeleteCachedResources() { |
178 DCHECK(context_thread_checker_.CalledOnValidThread()); | 195 DCHECK(context_thread_checker_.CalledOnValidThread()); |
179 | 196 |
180 if (gr_context_) | 197 if (gr_context_) |
181 gr_context_->FreeGpuResources(); | 198 gr_context_->FreeGpuResources(); |
182 } | 199 } |
183 | 200 |
184 void ContextProviderCommandBuffer::OnLostContext() { | 201 void ContextProviderCommandBuffer::OnLostContext() { |
185 DCHECK(context_thread_checker_.CalledOnValidThread()); | 202 // Note: no thread check here as this should not change the thread for which |
203 // this context is currently bound. e.g. a worker context might be unbound | |
204 // and this should not result in it being bound to the current thread. | |
186 { | 205 { |
187 base::AutoLock lock(main_thread_lock_); | 206 base::AutoLock lock(main_thread_lock_); |
188 if (destroyed_) | 207 if (destroyed_) |
189 return; | 208 return; |
190 destroyed_ = true; | 209 destroyed_ = true; |
191 } | 210 } |
192 if (!lost_context_callback_.is_null()) | 211 if (!lost_context_callback_.is_null()) |
193 base::ResetAndReturn(&lost_context_callback_).Run(); | 212 base::ResetAndReturn(&lost_context_callback_).Run(); |
194 if (gr_context_) | 213 if (gr_context_) |
195 gr_context_->OnLostContext(); | 214 gr_context_->OnLostContext(); |
196 } | 215 } |
197 | 216 |
198 void ContextProviderCommandBuffer::OnMemoryAllocationChanged( | 217 void ContextProviderCommandBuffer::OnMemoryAllocationChanged( |
199 const gpu::MemoryAllocation& allocation) { | 218 const gpu::MemoryAllocation& allocation) { |
200 DCHECK(context_thread_checker_.CalledOnValidThread()); | 219 // Note: no thread check here as this should not change the thread for which |
201 | 220 // this context is currently bound. e.g. a worker context might be unbound |
221 // and this should not result in it being bound to the current thread. | |
202 if (memory_policy_changed_callback_.is_null()) | 222 if (memory_policy_changed_callback_.is_null()) |
203 return; | 223 return; |
204 | 224 |
205 memory_policy_changed_callback_.Run(cc::ManagedMemoryPolicy(allocation)); | 225 memory_policy_changed_callback_.Run(cc::ManagedMemoryPolicy(allocation)); |
206 } | 226 } |
207 | 227 |
208 void ContextProviderCommandBuffer::InitializeCapabilities() { | 228 void ContextProviderCommandBuffer::InitializeCapabilities() { |
209 Capabilities caps; | 229 Capabilities caps; |
210 caps.gpu = context3d_->GetImplementation()->capabilities(); | 230 caps.gpu = context3d_->GetImplementation()->capabilities(); |
211 | 231 |
(...skipping 29 matching lines...) Expand all Loading... | |
241 | 261 |
242 if (!memory_policy_changed_callback_.is_null()) { | 262 if (!memory_policy_changed_callback_.is_null()) { |
243 DCHECK(context3d_->GetCommandBufferProxy()); | 263 DCHECK(context3d_->GetCommandBufferProxy()); |
244 context3d_->GetCommandBufferProxy()->SetMemoryAllocationChangedCallback( | 264 context3d_->GetCommandBufferProxy()->SetMemoryAllocationChangedCallback( |
245 base::Bind(&ContextProviderCommandBuffer::OnMemoryAllocationChanged, | 265 base::Bind(&ContextProviderCommandBuffer::OnMemoryAllocationChanged, |
246 base::Unretained(this))); | 266 base::Unretained(this))); |
247 } | 267 } |
248 } | 268 } |
249 | 269 |
250 } // namespace content | 270 } // namespace content |
OLD | NEW |