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 25 matching lines...) Expand all Loading... |
36 #include "gpu/ipc/client/gpu_channel_host.h" | 36 #include "gpu/ipc/client/gpu_channel_host.h" |
37 #include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" | 37 #include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" |
38 #include "third_party/skia/include/core/SkTypes.h" | 38 #include "third_party/skia/include/core/SkTypes.h" |
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 const gpu::gles2::ContextCreationAttribHelper& attributes, | |
47 gfx::GpuPreference gpu_preference, | 46 gfx::GpuPreference gpu_preference, |
48 bool automatic_flushes) | 47 bool automatic_flushes) |
49 : automatic_flushes_(automatic_flushes), | 48 : automatic_flushes_(automatic_flushes), |
50 attributes_(attributes), | |
51 host_(host), | 49 host_(host), |
52 surface_handle_(surface_handle), | 50 surface_handle_(surface_handle), |
53 active_url_(active_url), | 51 active_url_(active_url), |
54 gpu_preference_(gpu_preference), | 52 gpu_preference_(gpu_preference), |
55 weak_ptr_factory_(this) { | 53 weak_ptr_factory_(this) { |
56 DCHECK(host); | 54 DCHECK(host); |
57 switch (attributes.context_type) { | |
58 case gpu::gles2::CONTEXT_TYPE_OPENGLES2: | |
59 case gpu::gles2::CONTEXT_TYPE_OPENGLES3: | |
60 context_type_ = CONTEXT_TYPE_UNKNOWN; | |
61 case gpu::gles2::CONTEXT_TYPE_WEBGL1: | |
62 case gpu::gles2::CONTEXT_TYPE_WEBGL2: | |
63 context_type_ = OFFSCREEN_CONTEXT_FOR_WEBGL; | |
64 } | |
65 } | 55 } |
66 | 56 |
67 WebGraphicsContext3DCommandBufferImpl:: | 57 WebGraphicsContext3DCommandBufferImpl:: |
68 ~WebGraphicsContext3DCommandBufferImpl() { | 58 ~WebGraphicsContext3DCommandBufferImpl() { |
69 if (real_gl_) | 59 if (real_gl_) |
70 real_gl_->SetLostContextCallback(base::Closure()); | 60 real_gl_->SetLostContextCallback(base::Closure()); |
71 | 61 |
72 Destroy(); | 62 Destroy(); |
73 } | 63 } |
74 | 64 |
75 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL( | 65 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL( |
76 const gpu::SharedMemoryLimits& memory_limits, | 66 const gpu::SharedMemoryLimits& memory_limits, |
77 gpu::CommandBufferProxyImpl* shared_command_buffer, | 67 gpu::CommandBufferProxyImpl* shared_command_buffer, |
78 scoped_refptr<gpu::gles2::ShareGroup> share_group) { | 68 scoped_refptr<gpu::gles2::ShareGroup> share_group, |
| 69 const gpu::gles2::ContextCreationAttribHelper& attributes, |
| 70 command_buffer_metrics::ContextType context_type) { |
79 if (initialized_) | 71 if (initialized_) |
80 return true; | 72 return true; |
81 | 73 |
82 if (initialize_failed_) | 74 if (initialize_failed_) |
83 return false; | 75 return false; |
84 | 76 |
85 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL"); | 77 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL"); |
86 | 78 |
87 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is fixed. | 79 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is fixed. |
88 tracked_objects::ScopedTracker tracking_profile( | 80 tracked_objects::ScopedTracker tracking_profile( |
89 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 81 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
90 "125248 WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL")); | 82 "125248 WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL")); |
91 | 83 |
92 if (!CreateContext(memory_limits, shared_command_buffer, | 84 if (!CreateContext(memory_limits, shared_command_buffer, |
93 std::move(share_group))) { | 85 std::move(share_group), attributes, context_type)) { |
94 Destroy(); | 86 Destroy(); |
95 | 87 |
96 initialize_failed_ = true; | 88 initialize_failed_ = true; |
97 return false; | 89 return false; |
98 } | 90 } |
99 | 91 |
100 real_gl_->SetLostContextCallback( | 92 real_gl_->SetLostContextCallback( |
101 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnContextLost, | 93 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnContextLost, |
102 // The callback is unset in the destructor. | 94 // The callback is unset in the destructor. |
103 base::Unretained(this))); | 95 base::Unretained(this))); |
104 | 96 |
105 real_gl_->TraceBeginCHROMIUM("WebGraphicsContext3D", | 97 real_gl_->TraceBeginCHROMIUM("WebGraphicsContext3D", |
106 "CommandBufferContext"); | 98 "CommandBufferContext"); |
107 | 99 |
108 initialized_ = true; | 100 initialized_ = true; |
109 return true; | 101 return true; |
110 } | 102 } |
111 | 103 |
112 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( | 104 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( |
113 gpu::CommandBufferProxyImpl* shared_command_buffer) { | 105 gpu::CommandBufferProxyImpl* shared_command_buffer, |
| 106 const gpu::gles2::ContextCreationAttribHelper& attributes, |
| 107 command_buffer_metrics::ContextType context_type) { |
114 if (!host_.get()) | 108 if (!host_.get()) |
115 return false; | 109 return false; |
116 | 110 |
117 DCHECK(attributes_.buffer_preserved); | 111 DCHECK(attributes.buffer_preserved); |
118 std::vector<int32_t> serialized_attributes; | 112 std::vector<int32_t> serialized_attributes; |
119 attributes_.Serialize(&serialized_attributes); | 113 attributes.Serialize(&serialized_attributes); |
120 | 114 |
121 // Create a proxy to a command buffer in the GPU process. | 115 // Create a proxy to a command buffer in the GPU process. |
122 command_buffer_ = host_->CreateCommandBuffer( | 116 command_buffer_ = host_->CreateCommandBuffer( |
123 surface_handle_, gfx::Size(), shared_command_buffer, | 117 surface_handle_, gfx::Size(), shared_command_buffer, |
124 gpu::GpuChannelHost::kDefaultStreamId, | 118 gpu::GpuChannelHost::kDefaultStreamId, |
125 gpu::GpuChannelHost::kDefaultStreamPriority, serialized_attributes, | 119 gpu::GpuChannelHost::kDefaultStreamPriority, serialized_attributes, |
126 active_url_, gpu_preference_); | 120 active_url_, gpu_preference_); |
127 | 121 |
128 if (!command_buffer_) { | 122 if (!command_buffer_) { |
129 DLOG(ERROR) << "GpuChannelHost failed to create command buffer."; | 123 DLOG(ERROR) << "GpuChannelHost failed to create command buffer."; |
130 UmaRecordContextInitFailed(context_type_); | 124 command_buffer_metrics::UmaRecordContextInitFailed(context_type); |
131 return false; | 125 return false; |
132 } | 126 } |
133 | 127 |
134 DVLOG_IF(1, gpu::error::IsError(command_buffer_->GetLastError())) | 128 DVLOG_IF(1, gpu::error::IsError(command_buffer_->GetLastError())) |
135 << "Context dead on arrival. Last error: " | 129 << "Context dead on arrival. Last error: " |
136 << command_buffer_->GetLastError(); | 130 << command_buffer_->GetLastError(); |
137 // Initialize the command buffer. | 131 // Initialize the command buffer. |
138 bool result = command_buffer_->Initialize(); | 132 bool result = command_buffer_->Initialize(); |
139 LOG_IF(ERROR, !result) << "CommandBufferProxy::Initialize failed."; | 133 LOG_IF(ERROR, !result) << "CommandBufferProxy::Initialize failed."; |
140 if (!result) | 134 if (!result) |
141 UmaRecordContextInitFailed(context_type_); | 135 command_buffer_metrics::UmaRecordContextInitFailed(context_type); |
142 return result; | 136 return result; |
143 } | 137 } |
144 | 138 |
145 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( | 139 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( |
146 const gpu::SharedMemoryLimits& memory_limits, | 140 const gpu::SharedMemoryLimits& memory_limits, |
147 gpu::CommandBufferProxyImpl* shared_command_buffer, | 141 gpu::CommandBufferProxyImpl* shared_command_buffer, |
148 scoped_refptr<gpu::gles2::ShareGroup> share_group) { | 142 scoped_refptr<gpu::gles2::ShareGroup> share_group, |
| 143 const gpu::gles2::ContextCreationAttribHelper& attributes, |
| 144 command_buffer_metrics::ContextType context_type) { |
149 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::CreateContext"); | 145 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::CreateContext"); |
150 DCHECK_EQ(!!shared_command_buffer, !!share_group); | 146 DCHECK_EQ(!!shared_command_buffer, !!share_group); |
151 | 147 |
152 if (!InitializeCommandBuffer(shared_command_buffer)) { | 148 if (!InitializeCommandBuffer(shared_command_buffer, attributes, |
| 149 context_type)) { |
153 LOG(ERROR) << "Failed to initialize command buffer."; | 150 LOG(ERROR) << "Failed to initialize command buffer."; |
154 return false; | 151 return false; |
155 } | 152 } |
156 | 153 |
157 // Create the GLES2 helper, which writes the command buffer protocol. | 154 // Create the GLES2 helper, which writes the command buffer protocol. |
158 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); | 155 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); |
159 if (!gles2_helper_->Initialize(memory_limits.command_buffer_size)) { | 156 if (!gles2_helper_->Initialize(memory_limits.command_buffer_size)) { |
160 LOG(ERROR) << "Failed to initialize GLES2CmdHelper."; | 157 LOG(ERROR) << "Failed to initialize GLES2CmdHelper."; |
161 return false; | 158 return false; |
162 } | 159 } |
163 | 160 |
164 if (!automatic_flushes_) | 161 if (!automatic_flushes_) |
165 gles2_helper_->SetAutomaticFlushes(false); | 162 gles2_helper_->SetAutomaticFlushes(false); |
166 // Create a transfer buffer used to copy resources between the renderer | 163 // Create a transfer buffer used to copy resources between the renderer |
167 // process and the GPU process. | 164 // process and the GPU process. |
168 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); | 165 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); |
169 | 166 |
170 DCHECK(host_.get()); | 167 DCHECK(host_.get()); |
171 | 168 |
172 const bool bind_generates_resource = attributes_.bind_generates_resource; | 169 const bool bind_generates_resource = attributes.bind_generates_resource; |
173 const bool lose_context_when_out_of_memory = | 170 const bool lose_context_when_out_of_memory = |
174 attributes_.lose_context_when_out_of_memory; | 171 attributes.lose_context_when_out_of_memory; |
175 const bool support_client_side_arrays = false; | 172 const bool support_client_side_arrays = false; |
176 | 173 |
177 // Create the object exposing the OpenGL API. | 174 // Create the object exposing the OpenGL API. |
178 real_gl_.reset(new gpu::gles2::GLES2Implementation( | 175 real_gl_.reset(new gpu::gles2::GLES2Implementation( |
179 gles2_helper_.get(), std::move(share_group), transfer_buffer_.get(), | 176 gles2_helper_.get(), std::move(share_group), transfer_buffer_.get(), |
180 bind_generates_resource, lose_context_when_out_of_memory, | 177 bind_generates_resource, lose_context_when_out_of_memory, |
181 support_client_side_arrays, command_buffer_.get())); | 178 support_client_side_arrays, command_buffer_.get())); |
182 if (!real_gl_->Initialize(memory_limits.start_transfer_buffer_size, | 179 if (!real_gl_->Initialize(memory_limits.start_transfer_buffer_size, |
183 memory_limits.min_transfer_buffer_size, | 180 memory_limits.min_transfer_buffer_size, |
184 memory_limits.max_transfer_buffer_size, | 181 memory_limits.max_transfer_buffer_size, |
185 memory_limits.mapped_memory_reclaim_limit)) { | 182 memory_limits.mapped_memory_reclaim_limit)) { |
186 LOG(ERROR) << "Failed to initialize GLES2Implementation."; | 183 LOG(ERROR) << "Failed to initialize GLES2Implementation."; |
187 return false; | 184 return false; |
188 } | 185 } |
189 | 186 |
190 return true; | 187 return true; |
191 } | 188 } |
192 | 189 |
193 bool WebGraphicsContext3DCommandBufferImpl::InitializeOnCurrentThread( | 190 bool WebGraphicsContext3DCommandBufferImpl::InitializeOnCurrentThread( |
194 const gpu::SharedMemoryLimits& memory_limits, | 191 const gpu::SharedMemoryLimits& memory_limits, |
195 gpu::CommandBufferProxyImpl* shared_command_buffer, | 192 gpu::CommandBufferProxyImpl* shared_command_buffer, |
196 scoped_refptr<gpu::gles2::ShareGroup> share_group) { | 193 scoped_refptr<gpu::gles2::ShareGroup> share_group, |
| 194 const gpu::gles2::ContextCreationAttribHelper& attributes, |
| 195 command_buffer_metrics::ContextType context_type) { |
197 if (!MaybeInitializeGL(memory_limits, shared_command_buffer, | 196 if (!MaybeInitializeGL(memory_limits, shared_command_buffer, |
198 std::move(share_group))) { | 197 std::move(share_group), attributes, context_type)) { |
199 DLOG(ERROR) << "Failed to initialize context."; | 198 DLOG(ERROR) << "Failed to initialize context."; |
200 return false; | 199 return false; |
201 } | 200 } |
202 if (gpu::error::IsError(command_buffer_->GetLastError())) { | 201 if (gpu::error::IsError(command_buffer_->GetLastError())) { |
203 LOG(ERROR) << "Context dead on arrival. Last error: " | 202 LOG(ERROR) << "Context dead on arrival. Last error: " |
204 << command_buffer_->GetLastError(); | 203 << command_buffer_->GetLastError(); |
205 return false; | 204 return false; |
206 } | 205 } |
207 | 206 |
208 return true; | 207 return true; |
(...skipping 11 matching lines...) Expand all Loading... |
220 } | 219 } |
221 | 220 |
222 gpu::ContextSupport* | 221 gpu::ContextSupport* |
223 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() { | 222 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() { |
224 return real_gl_.get(); | 223 return real_gl_.get(); |
225 } | 224 } |
226 | 225 |
227 void WebGraphicsContext3DCommandBufferImpl::OnContextLost() { | 226 void WebGraphicsContext3DCommandBufferImpl::OnContextLost() { |
228 if (context_lost_callback_) | 227 if (context_lost_callback_) |
229 context_lost_callback_->onContextLost(); | 228 context_lost_callback_->onContextLost(); |
230 | |
231 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); | |
232 UmaRecordContextLost(context_type_, state.error, state.context_lost_reason); | |
233 } | 229 } |
234 | 230 |
235 } // namespace content | 231 } // namespace content |
OLD | NEW |