OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/webgraphicscontext3d_command_buffer_impl.h" | 5 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" |
6 | 6 |
7 #include "third_party/khronos/GLES2/gl2.h" | 7 #include "third_party/khronos/GLES2/gl2.h" |
8 #ifndef GL_GLEXT_PROTOTYPES | 8 #ifndef GL_GLEXT_PROTOTYPES |
9 #define GL_GLEXT_PROTOTYPES 1 | 9 #define GL_GLEXT_PROTOTYPES 1 |
10 #endif | 10 #endif |
(...skipping 28 matching lines...) Expand all Loading... | |
39 | 39 |
40 namespace content { | 40 namespace content { |
41 | 41 |
42 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( | 42 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( |
43 gpu::SurfaceHandle surface_handle, | 43 gpu::SurfaceHandle surface_handle, |
44 const GURL& active_url, | 44 const GURL& active_url, |
45 gpu::GpuChannelHost* host, | 45 gpu::GpuChannelHost* host, |
46 gfx::GpuPreference gpu_preference, | 46 gfx::GpuPreference gpu_preference, |
47 bool automatic_flushes) | 47 bool automatic_flushes) |
48 : automatic_flushes_(automatic_flushes), | 48 : automatic_flushes_(automatic_flushes), |
49 host_(host), | |
50 surface_handle_(surface_handle), | 49 surface_handle_(surface_handle), |
51 active_url_(active_url), | 50 active_url_(active_url), |
52 gpu_preference_(gpu_preference), | 51 gpu_preference_(gpu_preference), |
53 weak_ptr_factory_(this) { | 52 host_(host) { |
54 DCHECK(host); | 53 DCHECK(host_); |
55 } | 54 } |
56 | 55 |
57 WebGraphicsContext3DCommandBufferImpl:: | 56 WebGraphicsContext3DCommandBufferImpl:: |
58 ~WebGraphicsContext3DCommandBufferImpl() { | 57 ~WebGraphicsContext3DCommandBufferImpl() { |
59 if (real_gl_) | 58 if (real_gl_) |
60 real_gl_->SetLostContextCallback(base::Closure()); | 59 real_gl_->SetLostContextCallback(base::Closure()); |
61 | |
62 Destroy(); | |
63 } | 60 } |
64 | 61 |
65 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL( | 62 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL( |
66 const gpu::SharedMemoryLimits& memory_limits, | 63 const gpu::SharedMemoryLimits& memory_limits, |
67 gpu::CommandBufferProxyImpl* shared_command_buffer, | 64 gpu::CommandBufferProxyImpl* shared_command_buffer, |
68 scoped_refptr<gpu::gles2::ShareGroup> share_group, | 65 scoped_refptr<gpu::gles2::ShareGroup> share_group, |
69 const gpu::gles2::ContextCreationAttribHelper& attributes, | 66 const gpu::gles2::ContextCreationAttribHelper& attributes, |
70 command_buffer_metrics::ContextType context_type) { | 67 command_buffer_metrics::ContextType context_type) { |
71 if (initialized_) | 68 DCHECK_EQ(!!shared_command_buffer, !!share_group); |
72 return true; | |
73 | |
74 if (initialize_failed_) | |
75 return false; | |
76 | |
77 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL"); | 69 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL"); |
78 | 70 |
79 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is fixed. | |
danakj
2016/04/30 01:56:39
Moved this out to GpuProcessTransportFactory, sinc
| |
80 tracked_objects::ScopedTracker tracking_profile( | |
81 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
82 "125248 WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL")); | |
83 | |
84 if (!CreateContext(memory_limits, shared_command_buffer, | |
85 std::move(share_group), attributes, context_type)) { | |
86 Destroy(); | |
87 | |
88 initialize_failed_ = true; | |
89 return false; | |
90 } | |
91 | |
92 real_gl_->SetLostContextCallback( | |
93 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnContextLost, | |
94 // The callback is unset in the destructor. | |
95 base::Unretained(this))); | |
96 | |
97 real_gl_->TraceBeginCHROMIUM("WebGraphicsContext3D", | |
98 "CommandBufferContext"); | |
99 | |
100 initialized_ = true; | |
101 return true; | |
102 } | |
103 | |
104 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( | |
105 gpu::CommandBufferProxyImpl* shared_command_buffer, | |
106 const gpu::gles2::ContextCreationAttribHelper& attributes, | |
107 command_buffer_metrics::ContextType context_type) { | |
108 if (!host_.get()) | |
109 return false; | |
110 | |
111 DCHECK(attributes.buffer_preserved); | 71 DCHECK(attributes.buffer_preserved); |
112 std::vector<int32_t> serialized_attributes; | 72 std::vector<int32_t> serialized_attributes; |
113 attributes.Serialize(&serialized_attributes); | 73 attributes.Serialize(&serialized_attributes); |
114 | 74 |
115 // Create a proxy to a command buffer in the GPU process. | 75 // Create a proxy to a command buffer in the GPU process. |
116 command_buffer_ = host_->CreateCommandBuffer( | 76 command_buffer_ = host_->CreateCommandBuffer( |
117 surface_handle_, gfx::Size(), shared_command_buffer, | 77 surface_handle_, gfx::Size(), shared_command_buffer, |
118 gpu::GpuChannelHost::kDefaultStreamId, | 78 gpu::GpuChannelHost::kDefaultStreamId, |
119 gpu::GpuChannelHost::kDefaultStreamPriority, serialized_attributes, | 79 gpu::GpuChannelHost::kDefaultStreamPriority, serialized_attributes, |
120 active_url_, gpu_preference_); | 80 active_url_, gpu_preference_); |
121 | 81 |
122 if (!command_buffer_) { | 82 if (!command_buffer_) { |
123 DLOG(ERROR) << "GpuChannelHost failed to create command buffer."; | 83 DLOG(ERROR) << "GpuChannelHost failed to create command buffer."; |
124 command_buffer_metrics::UmaRecordContextInitFailed(context_type); | 84 command_buffer_metrics::UmaRecordContextInitFailed(context_type); |
125 return false; | 85 return false; |
126 } | 86 } |
87 if (!command_buffer_->Initialize()) { | |
88 DLOG(ERROR) << "CommandBufferProxy::Initialize failed."; | |
89 command_buffer_metrics::UmaRecordContextInitFailed(context_type); | |
90 return false; | |
91 } | |
127 | 92 |
128 DVLOG_IF(1, gpu::error::IsError(command_buffer_->GetLastError())) | 93 // The GLES2 helper writes the command buffer protocol. |
danakj
2016/04/30 01:56:39
I can't see a way for last_state_ to be set to any
| |
129 << "Context dead on arrival. Last error: " | 94 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); |
130 << command_buffer_->GetLastError(); | 95 gles2_helper_->SetAutomaticFlushes(automatic_flushes_); |
danakj
2016/04/30 01:56:39
I thot it was a bit weird that we set this after c
| |
131 // Initialize the command buffer. | 96 if (!gles2_helper_->Initialize(memory_limits.command_buffer_size)) { |
132 bool result = command_buffer_->Initialize(); | 97 DLOG(ERROR) << "Failed to initialize GLES2CmdHelper."; |
danakj
2016/04/30 01:56:39
I turned all the LOGs into DLOGs which print when
| |
133 LOG_IF(ERROR, !result) << "CommandBufferProxy::Initialize failed."; | |
134 if (!result) | |
135 command_buffer_metrics::UmaRecordContextInitFailed(context_type); | |
136 return result; | |
137 } | |
138 | |
139 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( | |
140 const gpu::SharedMemoryLimits& memory_limits, | |
141 gpu::CommandBufferProxyImpl* shared_command_buffer, | |
142 scoped_refptr<gpu::gles2::ShareGroup> share_group, | |
143 const gpu::gles2::ContextCreationAttribHelper& attributes, | |
144 command_buffer_metrics::ContextType context_type) { | |
145 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::CreateContext"); | |
146 DCHECK_EQ(!!shared_command_buffer, !!share_group); | |
147 | |
148 if (!InitializeCommandBuffer(shared_command_buffer, attributes, | |
149 context_type)) { | |
150 LOG(ERROR) << "Failed to initialize command buffer."; | |
151 return false; | 98 return false; |
152 } | 99 } |
153 | 100 |
154 // Create the GLES2 helper, which writes the command buffer protocol. | 101 // The transfer buffer is used to copy resources between the client |
155 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); | |
156 if (!gles2_helper_->Initialize(memory_limits.command_buffer_size)) { | |
157 LOG(ERROR) << "Failed to initialize GLES2CmdHelper."; | |
158 return false; | |
159 } | |
160 | |
161 if (!automatic_flushes_) | |
162 gles2_helper_->SetAutomaticFlushes(false); | |
163 // Create a transfer buffer used to copy resources between the renderer | |
164 // process and the GPU process. | 102 // process and the GPU process. |
165 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); | 103 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); |
166 | 104 |
167 DCHECK(host_.get()); | |
168 | |
169 const bool bind_generates_resource = attributes.bind_generates_resource; | 105 const bool bind_generates_resource = attributes.bind_generates_resource; |
170 const bool lose_context_when_out_of_memory = | 106 const bool lose_context_when_out_of_memory = |
171 attributes.lose_context_when_out_of_memory; | 107 attributes.lose_context_when_out_of_memory; |
172 const bool support_client_side_arrays = false; | 108 const bool support_client_side_arrays = false; |
173 | 109 |
174 // Create the object exposing the OpenGL API. | 110 // The GLES2Implementation exposes the OpenGLES2 API, as well as the |
111 // gpu::ContextSupport interface. | |
175 real_gl_.reset(new gpu::gles2::GLES2Implementation( | 112 real_gl_.reset(new gpu::gles2::GLES2Implementation( |
176 gles2_helper_.get(), std::move(share_group), transfer_buffer_.get(), | 113 gles2_helper_.get(), std::move(share_group), transfer_buffer_.get(), |
177 bind_generates_resource, lose_context_when_out_of_memory, | 114 bind_generates_resource, lose_context_when_out_of_memory, |
178 support_client_side_arrays, command_buffer_.get())); | 115 support_client_side_arrays, command_buffer_.get())); |
179 if (!real_gl_->Initialize(memory_limits.start_transfer_buffer_size, | 116 if (!real_gl_->Initialize(memory_limits.start_transfer_buffer_size, |
180 memory_limits.min_transfer_buffer_size, | 117 memory_limits.min_transfer_buffer_size, |
181 memory_limits.max_transfer_buffer_size, | 118 memory_limits.max_transfer_buffer_size, |
182 memory_limits.mapped_memory_reclaim_limit)) { | 119 memory_limits.mapped_memory_reclaim_limit)) { |
183 LOG(ERROR) << "Failed to initialize GLES2Implementation."; | 120 DLOG(ERROR) << "Failed to initialize GLES2Implementation."; |
184 return false; | 121 return false; |
185 } | 122 } |
186 | 123 |
124 real_gl_->SetLostContextCallback( | |
125 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnContextLost, | |
126 // The callback is unset in the destructor. | |
127 base::Unretained(this))); | |
128 real_gl_->TraceBeginCHROMIUM("WebGraphicsContext3D", "CommandBufferContext"); | |
187 return true; | 129 return true; |
188 } | 130 } |
189 | 131 |
190 bool WebGraphicsContext3DCommandBufferImpl::InitializeOnCurrentThread( | 132 bool WebGraphicsContext3DCommandBufferImpl::InitializeOnCurrentThread( |
191 const gpu::SharedMemoryLimits& memory_limits, | 133 const gpu::SharedMemoryLimits& memory_limits, |
192 gpu::CommandBufferProxyImpl* shared_command_buffer, | 134 gpu::CommandBufferProxyImpl* shared_command_buffer, |
193 scoped_refptr<gpu::gles2::ShareGroup> share_group, | 135 scoped_refptr<gpu::gles2::ShareGroup> share_group, |
194 const gpu::gles2::ContextCreationAttribHelper& attributes, | 136 const gpu::gles2::ContextCreationAttribHelper& attributes, |
195 command_buffer_metrics::ContextType context_type) { | 137 command_buffer_metrics::ContextType context_type) { |
196 if (!MaybeInitializeGL(memory_limits, shared_command_buffer, | 138 if (!MaybeInitializeGL(memory_limits, shared_command_buffer, |
197 std::move(share_group), attributes, context_type)) { | 139 std::move(share_group), attributes, context_type)) |
198 DLOG(ERROR) << "Failed to initialize context."; | |
199 return false; | 140 return false; |
200 } | |
201 if (gpu::error::IsError(command_buffer_->GetLastError())) { | 141 if (gpu::error::IsError(command_buffer_->GetLastError())) { |
202 LOG(ERROR) << "Context dead on arrival. Last error: " | 142 DLOG(ERROR) << "Context dead on arrival. Last error: " |
203 << command_buffer_->GetLastError(); | 143 << command_buffer_->GetLastError(); |
204 return false; | 144 return false; |
205 } | 145 } |
206 | 146 |
207 return true; | 147 return true; |
208 } | 148 } |
209 | 149 |
210 void WebGraphicsContext3DCommandBufferImpl::Destroy() { | |
211 trace_gl_.reset(); | |
212 real_gl_.reset(); | |
213 transfer_buffer_.reset(); | |
214 gles2_helper_.reset(); | |
215 real_gl_.reset(); | |
216 command_buffer_.reset(); | |
217 | |
218 host_ = nullptr; | |
219 } | |
220 | |
221 gpu::ContextSupport* | |
222 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() { | |
danakj
2016/04/30 01:56:39
This is just collatoral damage, as it's pointless
| |
223 return real_gl_.get(); | |
224 } | |
225 | |
226 void WebGraphicsContext3DCommandBufferImpl::OnContextLost() { | 150 void WebGraphicsContext3DCommandBufferImpl::OnContextLost() { |
227 if (context_lost_callback_) | 151 if (context_lost_callback_) |
228 context_lost_callback_->onContextLost(); | 152 context_lost_callback_->onContextLost(); |
229 } | 153 } |
230 | 154 |
231 } // namespace content | 155 } // namespace content |
OLD | NEW |