Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(329)

Side by Side Diff: content/common/gpu/client/context_provider_command_buffer.cc

Issue 1944603002: Delete WebGraphicsContext3DCommandBufferImpl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@construct
Patch Set: killitwithfire: const Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <set> 10 #include <set>
11 #include <utility> 11 #include <utility>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
17 #include "cc/output/managed_memory_policy.h" 17 #include "cc/output/managed_memory_policy.h"
18 #include "content/common/gpu/client/command_buffer_metrics.h" 18 #include "content/common/gpu/client/command_buffer_metrics.h"
19 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 19 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
20 #include "gpu/command_buffer/client/gles2_implementation.h" 20 #include "gpu/command_buffer/client/gles2_implementation.h"
21 #include "gpu/command_buffer/client/gles2_trace_implementation.h" 21 #include "gpu/command_buffer/client/gles2_trace_implementation.h"
22 #include "gpu/command_buffer/client/gpu_switches.h" 22 #include "gpu/command_buffer/client/gpu_switches.h"
23 #include "gpu/command_buffer/client/transfer_buffer.h"
24 #include "gpu/command_buffer/common/constants.h"
25 #include "gpu/ipc/client/command_buffer_proxy_impl.h"
23 #include "gpu/ipc/client/gpu_channel_host.h" 26 #include "gpu/ipc/client/gpu_channel_host.h"
24 #include "gpu/skia_bindings/grcontext_for_gles2_interface.h" 27 #include "gpu/skia_bindings/grcontext_for_gles2_interface.h"
25 #include "third_party/skia/include/gpu/GrContext.h" 28 #include "third_party/skia/include/gpu/GrContext.h"
26 29
30 namespace {
31
32 // Similar to base::AutoReset but it sets the variable to the new value
33 // when it is destroyed. Use reset() to cancel setting the variable.
34 class AutoSet {
35 public:
36 AutoSet(bool* b, bool set) : b_(b), set_(set) {}
37 ~AutoSet() {
38 if (b_)
39 *b_ = set_;
40 }
41 // Stops us from setting _b on destruction.
42 void Reset() { b_ = nullptr; }
43
44 private:
45 bool* b_;
46 const bool set_;
47 };
48 }
49
27 namespace content { 50 namespace content {
28 51
29 ContextProviderCommandBuffer::SharedProviders::SharedProviders() = default; 52 ContextProviderCommandBuffer::SharedProviders::SharedProviders() = default;
30 ContextProviderCommandBuffer::SharedProviders::~SharedProviders() = default; 53 ContextProviderCommandBuffer::SharedProviders::~SharedProviders() = default;
31 54
32 ContextProviderCommandBuffer::ContextProviderCommandBuffer( 55 ContextProviderCommandBuffer::ContextProviderCommandBuffer(
33 scoped_refptr<gpu::GpuChannelHost> channel, 56 scoped_refptr<gpu::GpuChannelHost> channel,
34 gpu::SurfaceHandle surface_handle, 57 gpu::SurfaceHandle surface_handle,
35 const GURL& active_url, 58 const GURL& active_url,
36 gfx::GpuPreference gpu_preference, 59 gfx::GpuPreference gpu_preference,
37 bool automatic_flushes, 60 bool automatic_flushes,
38 const gpu::SharedMemoryLimits& memory_limits, 61 const gpu::SharedMemoryLimits& memory_limits,
39 const gpu::gles2::ContextCreationAttribHelper& attributes, 62 const gpu::gles2::ContextCreationAttribHelper& attributes,
40 ContextProviderCommandBuffer* shared_context_provider, 63 ContextProviderCommandBuffer* shared_context_provider,
41 command_buffer_metrics::ContextType type) 64 command_buffer_metrics::ContextType type)
42 : surface_handle_(surface_handle), 65 : surface_handle_(surface_handle),
43 active_url_(active_url), 66 active_url_(active_url),
44 gpu_preference_(gpu_preference), 67 gpu_preference_(gpu_preference),
45 automatic_flushes_(automatic_flushes), 68 automatic_flushes_(automatic_flushes),
46 memory_limits_(memory_limits), 69 memory_limits_(memory_limits),
47 attributes_(attributes), 70 attributes_(attributes),
48 context_type_(type), 71 context_type_(type),
49 shared_providers_(shared_context_provider 72 shared_providers_(shared_context_provider
50 ? shared_context_provider->shared_providers_ 73 ? shared_context_provider->shared_providers_
51 : new SharedProviders), 74 : new SharedProviders),
52 channel_(std::move(channel)), 75 channel_(std::move(channel)) {
53 context3d_(new WebGraphicsContext3DCommandBufferImpl) {
54 DCHECK(main_thread_checker_.CalledOnValidThread()); 76 DCHECK(main_thread_checker_.CalledOnValidThread());
55 DCHECK(channel_); 77 DCHECK(channel_);
56 context_thread_checker_.DetachFromThread(); 78 context_thread_checker_.DetachFromThread();
57 } 79 }
58 80
59 ContextProviderCommandBuffer::~ContextProviderCommandBuffer() { 81 ContextProviderCommandBuffer::~ContextProviderCommandBuffer() {
60 DCHECK(main_thread_checker_.CalledOnValidThread() || 82 DCHECK(main_thread_checker_.CalledOnValidThread() ||
61 context_thread_checker_.CalledOnValidThread()); 83 context_thread_checker_.CalledOnValidThread());
62 84
63 { 85 {
64 base::AutoLock hold(shared_providers_->lock); 86 base::AutoLock hold(shared_providers_->lock);
65 auto it = std::find(shared_providers_->list.begin(), 87 auto it = std::find(shared_providers_->list.begin(),
66 shared_providers_->list.end(), this); 88 shared_providers_->list.end(), this);
67 if (it != shared_providers_->list.end()) 89 if (it != shared_providers_->list.end())
68 shared_providers_->list.erase(it); 90 shared_providers_->list.erase(it);
69 } 91 }
70 92
71 if (bind_succeeded_) { 93 if (bind_succeeded_) {
72 // Clear the lock to avoid DCHECKs that the lock is being held during 94 // Clear the lock to avoid DCHECKs that the lock is being held during
73 // shutdown. 95 // shutdown.
74 context3d_->GetCommandBufferProxy()->SetLock(nullptr); 96 command_buffer_->SetLock(nullptr);
75 // Disconnect lost callbacks during destruction. 97 // Disconnect lost callbacks during destruction.
76 context3d_->GetImplementation()->SetLostContextCallback(base::Closure()); 98 gles2_impl_->SetLostContextCallback(base::Closure());
77 } 99 }
78 } 100 }
79 101
80 gpu::CommandBufferProxyImpl* 102 gpu::CommandBufferProxyImpl*
81 ContextProviderCommandBuffer::GetCommandBufferProxy() { 103 ContextProviderCommandBuffer::GetCommandBufferProxy() {
82 return context3d_->GetCommandBufferProxy(); 104 return command_buffer_.get();
83 } 105 }
84 106
85 bool ContextProviderCommandBuffer::BindToCurrentThread() { 107 bool ContextProviderCommandBuffer::BindToCurrentThread() {
86 // This is called on the thread the context will be used. 108 // This is called on the thread the context will be used.
87 DCHECK(context_thread_checker_.CalledOnValidThread()); 109 DCHECK(context_thread_checker_.CalledOnValidThread());
88 110
89 if (!context3d_) 111 if (bind_failed_)
90 return false; // Already failed. 112 return false;
91 if (bind_succeeded_) 113 if (bind_succeeded_)
92 return true; // Already succeeded. 114 return true;
115
116 // Early outs should report failure.
117 AutoSet set_bind_failed(&bind_failed_, true);
93 118
94 // It's possible to be running BindToCurrentThread on two contexts 119 // It's possible to be running BindToCurrentThread on two contexts
95 // on different threads at the same time, but which will be in the same share 120 // on different threads at the same time, but which will be in the same share
96 // group. To ensure they end up in the same group, hold the lock on the 121 // group. To ensure they end up in the same group, hold the lock on the
97 // shared_providers_ (which they will share) after querying the group, until 122 // shared_providers_ (which they will share) after querying the group, until
98 // this context has been added to the list. 123 // this context has been added to the list.
99 { 124 {
100 ContextProviderCommandBuffer* shared_context_provider = nullptr; 125 ContextProviderCommandBuffer* shared_context_provider = nullptr;
101 gpu::CommandBufferProxyImpl* shared_command_buffer = nullptr; 126 gpu::CommandBufferProxyImpl* shared_command_buffer = nullptr;
102 scoped_refptr<gpu::gles2::ShareGroup> share_group; 127 scoped_refptr<gpu::gles2::ShareGroup> share_group;
103 128
104 base::AutoLock hold(shared_providers_->lock); 129 base::AutoLock hold(shared_providers_->lock);
105 130
106 if (!shared_providers_->list.empty()) { 131 if (!shared_providers_->list.empty()) {
107 shared_context_provider = shared_providers_->list.front(); 132 shared_context_provider = shared_providers_->list.front();
108 shared_command_buffer = 133 shared_command_buffer = shared_context_provider->command_buffer_.get();
109 shared_context_provider->context3d_->GetCommandBufferProxy(); 134 share_group = shared_context_provider->gles2_impl_->share_group();
110 share_group = shared_context_provider->context3d_->GetImplementation() 135 DCHECK_EQ(!!shared_command_buffer, !!share_group);
111 ->share_group();
112 } 136 }
113 137
114 if (!context3d_->InitializeOnCurrentThread( 138 DCHECK(attributes_.buffer_preserved);
115 surface_handle_, active_url_, channel_.get(), gpu_preference_, 139 std::vector<int32_t> serialized_attributes;
116 automatic_flushes_, memory_limits_, shared_command_buffer, 140 attributes_.Serialize(&serialized_attributes);
117 share_group, attributes_, context_type_)) { 141
118 context3d_ = nullptr; 142 // This command buffer is a client-side proxy to the command buffer in the
143 // GPU process.
144 command_buffer_ = channel_->CreateCommandBuffer(
145 surface_handle_, gfx::Size(), shared_command_buffer,
146 gpu::GpuChannelHost::kDefaultStreamId,
147 gpu::GpuChannelHost::kDefaultStreamPriority, serialized_attributes,
148 active_url_, gpu_preference_);
149 // The command buffer takes ownership of the |channel_|, so no need to keep
150 // a reference around here.
151 channel_ = nullptr;
152 if (!command_buffer_) {
153 DLOG(ERROR) << "GpuChannelHost failed to create command buffer.";
154 command_buffer_metrics::UmaRecordContextInitFailed(context_type_);
119 return false; 155 return false;
120 } 156 }
121 157
158 // The GLES2 helper writes the command buffer protocol.
159 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get()));
160 gles2_helper_->SetAutomaticFlushes(automatic_flushes_);
161 if (!gles2_helper_->Initialize(memory_limits_.command_buffer_size)) {
162 DLOG(ERROR) << "Failed to initialize GLES2CmdHelper.";
163 return false;
164 }
165
166 // The transfer buffer is used to copy resources between the client
167 // process and the GPU process.
168 transfer_buffer_.reset(new gpu::TransferBuffer(gles2_helper_.get()));
169
170 // The GLES2Implementation exposes the OpenGLES2 API, as well as the
171 // gpu::ContextSupport interface.
172 constexpr bool support_client_side_arrays = false;
173 gles2_impl_.reset(new gpu::gles2::GLES2Implementation(
174 gles2_helper_.get(), share_group, transfer_buffer_.get(),
175 attributes_.bind_generates_resource,
176 attributes_.lose_context_when_out_of_memory, support_client_side_arrays,
177 command_buffer_.get()));
178 if (!gles2_impl_->Initialize(memory_limits_.start_transfer_buffer_size,
179 memory_limits_.min_transfer_buffer_size,
180 memory_limits_.max_transfer_buffer_size,
181 memory_limits_.mapped_memory_reclaim_limit)) {
182 DLOG(ERROR) << "Failed to initialize GLES2Implementation.";
183 return false;
184 }
185
186 if (command_buffer_->GetLastError() != gpu::error::kNoError) {
187 DLOG(ERROR) << "Context dead on arrival. Last error: "
188 << command_buffer_->GetLastError();
189 return false;
190 }
191
122 // If any context in the share group has been lost, then abort and don't 192 // If any context in the share group has been lost, then abort and don't
123 // continue since we need to go back to the caller of the constructor to 193 // continue since we need to go back to the caller of the constructor to
124 // find the correct share group. 194 // find the correct share group.
125 // This may happen in between the share group being chosen at the 195 // This may happen in between the share group being chosen at the
126 // constructor, and getting to run this BindToCurrentThread method which 196 // constructor, and getting to run this BindToCurrentThread method which
127 // can be on some other thread. 197 // can be on some other thread.
128 // We intentionally call this *after* creating the command buffer via the 198 // We intentionally call this *after* creating the command buffer via the
129 // GpuChannelHost. Once that has happened, the service knows we are in the 199 // GpuChannelHost. Once that has happened, the service knows we are in the
130 // share group and if a shared context is lost, our context will be informed 200 // share group and if a shared context is lost, our context will be informed
131 // also, and the lost context callback will occur for the owner of the 201 // also, and the lost context callback will occur for the owner of the
132 // context provider. If we check sooner, the shared context may be lost in 202 // context provider. If we check sooner, the shared context may be lost in
133 // between these two states and our context here would be left in an orphan 203 // between these two states and our context here would be left in an orphan
134 // share group. 204 // share group.
135 if (share_group && share_group->IsLost()) { 205 if (share_group && share_group->IsLost())
136 context3d_ = nullptr;
137 return false; 206 return false;
138 }
139 207
140 shared_providers_->list.push_back(this); 208 shared_providers_->list.push_back(this);
141 } 209 }
210 set_bind_failed.Reset();
211 bind_succeeded_ = true;
142 212
143 context3d_->GetImplementation()->SetLostContextCallback( 213 gles2_impl_->SetLostContextCallback(
144 base::Bind(&ContextProviderCommandBuffer::OnLostContext, 214 base::Bind(&ContextProviderCommandBuffer::OnLostContext,
145 // |this| owns the GLES2Implementation which holds the 215 // |this| owns the GLES2Implementation which holds the
146 // callback. 216 // callback.
147 base::Unretained(this))); 217 base::Unretained(this)));
148 218
149 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 219 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
150 switches::kEnableGpuClientTracing)) { 220 switches::kEnableGpuClientTracing)) {
151 // This wraps the real GLES2Implementation and we should always use this 221 // This wraps the real GLES2Implementation and we should always use this
152 // instead when it's present. 222 // instead when it's present.
153 trace_impl_.reset(new gpu::gles2::GLES2TraceImplementation( 223 trace_impl_.reset(
154 context3d_->GetImplementation())); 224 new gpu::gles2::GLES2TraceImplementation(gles2_impl_.get()));
155 } 225 }
156 226
157 bind_succeeded_ = true;
158
159 // Do this last once the context is set up. 227 // Do this last once the context is set up.
160 std::string type_name = 228 std::string type_name =
161 command_buffer_metrics::ContextTypeToString(context_type_); 229 command_buffer_metrics::ContextTypeToString(context_type_);
162 std::string unique_context_name = 230 std::string unique_context_name =
163 base::StringPrintf("%s-%p", type_name.c_str(), context3d_.get()); 231 base::StringPrintf("%s-%p", type_name.c_str(), gles2_impl_.get());
164 ContextGL()->TraceBeginCHROMIUM("gpu_toplevel", unique_context_name.c_str()); 232 ContextGL()->TraceBeginCHROMIUM("gpu_toplevel", unique_context_name.c_str());
165 return true; 233 return true;
166 } 234 }
167 235
168 void ContextProviderCommandBuffer::DetachFromThread() { 236 void ContextProviderCommandBuffer::DetachFromThread() {
169 context_thread_checker_.DetachFromThread(); 237 context_thread_checker_.DetachFromThread();
170 } 238 }
171 239
172 gpu::gles2::GLES2Interface* ContextProviderCommandBuffer::ContextGL() { 240 gpu::gles2::GLES2Interface* ContextProviderCommandBuffer::ContextGL() {
173 DCHECK(context3d_);
174 DCHECK(bind_succeeded_); 241 DCHECK(bind_succeeded_);
175 DCHECK(context_thread_checker_.CalledOnValidThread()); 242 DCHECK(context_thread_checker_.CalledOnValidThread());
176 243
177 if (trace_impl_) 244 if (trace_impl_)
178 return trace_impl_.get(); 245 return trace_impl_.get();
179 return context3d_->GetImplementation(); 246 return gles2_impl_.get();
180 } 247 }
181 248
182 gpu::ContextSupport* ContextProviderCommandBuffer::ContextSupport() { 249 gpu::ContextSupport* ContextProviderCommandBuffer::ContextSupport() {
183 return context3d_->GetImplementation(); 250 return gles2_impl_.get();
184 } 251 }
185 252
186 class GrContext* ContextProviderCommandBuffer::GrContext() { 253 class GrContext* ContextProviderCommandBuffer::GrContext() {
187 DCHECK(bind_succeeded_); 254 DCHECK(bind_succeeded_);
188 DCHECK(context_thread_checker_.CalledOnValidThread()); 255 DCHECK(context_thread_checker_.CalledOnValidThread());
189 256
190 if (gr_context_) 257 if (gr_context_)
191 return gr_context_->get(); 258 return gr_context_->get();
192 259
193 gr_context_.reset(new skia_bindings::GrContextForGLES2Interface(ContextGL())); 260 gr_context_.reset(new skia_bindings::GrContextForGLES2Interface(ContextGL()));
(...skipping 10 matching lines...) Expand all
204 if (gr_context_) { 271 if (gr_context_) {
205 DCHECK(bind_succeeded_); 272 DCHECK(bind_succeeded_);
206 DCHECK(context_thread_checker_.CalledOnValidThread()); 273 DCHECK(context_thread_checker_.CalledOnValidThread());
207 gr_context_->ResetContext(state); 274 gr_context_->ResetContext(state);
208 } 275 }
209 } 276 }
210 277
211 void ContextProviderCommandBuffer::SetupLock() { 278 void ContextProviderCommandBuffer::SetupLock() {
212 DCHECK(bind_succeeded_); 279 DCHECK(bind_succeeded_);
213 DCHECK(context_thread_checker_.CalledOnValidThread()); 280 DCHECK(context_thread_checker_.CalledOnValidThread());
214 context3d_->GetCommandBufferProxy()->SetLock(&context_lock_); 281 command_buffer_->SetLock(&context_lock_);
215 } 282 }
216 283
217 base::Lock* ContextProviderCommandBuffer::GetLock() { 284 base::Lock* ContextProviderCommandBuffer::GetLock() {
218 return &context_lock_; 285 return &context_lock_;
219 } 286 }
220 287
221 gpu::Capabilities ContextProviderCommandBuffer::ContextCapabilities() { 288 gpu::Capabilities ContextProviderCommandBuffer::ContextCapabilities() {
222 DCHECK(bind_succeeded_); 289 DCHECK(bind_succeeded_);
223 DCHECK(context_thread_checker_.CalledOnValidThread()); 290 DCHECK(context_thread_checker_.CalledOnValidThread());
224 // Skips past the trace_impl_ as it doesn't have capabilities. 291 // Skips past the trace_impl_ as it doesn't have capabilities.
225 return context3d_->GetImplementation()->capabilities(); 292 return gles2_impl_->capabilities();
226 } 293 }
227 294
228 void ContextProviderCommandBuffer::DeleteCachedResources() { 295 void ContextProviderCommandBuffer::DeleteCachedResources() {
229 DCHECK(context_thread_checker_.CalledOnValidThread()); 296 DCHECK(context_thread_checker_.CalledOnValidThread());
230 297
231 if (gr_context_) 298 if (gr_context_)
232 gr_context_->FreeGpuResources(); 299 gr_context_->FreeGpuResources();
233 } 300 }
234 301
235 void ContextProviderCommandBuffer::OnLostContext() { 302 void ContextProviderCommandBuffer::OnLostContext() {
(...skipping 11 matching lines...) Expand all
247 314
248 void ContextProviderCommandBuffer::SetLostContextCallback( 315 void ContextProviderCommandBuffer::SetLostContextCallback(
249 const LostContextCallback& lost_context_callback) { 316 const LostContextCallback& lost_context_callback) {
250 DCHECK(context_thread_checker_.CalledOnValidThread()); 317 DCHECK(context_thread_checker_.CalledOnValidThread());
251 DCHECK(lost_context_callback_.is_null() || 318 DCHECK(lost_context_callback_.is_null() ||
252 lost_context_callback.is_null()); 319 lost_context_callback.is_null());
253 lost_context_callback_ = lost_context_callback; 320 lost_context_callback_ = lost_context_callback;
254 } 321 }
255 322
256 } // namespace content 323 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698