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 scoped_refptr<gpu::GpuChannelHost> host, | 45 scoped_refptr<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_(std::move(host)), | 49 host_(std::move(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 return true; | 131 return true; |
138 } | 132 } |
139 | 133 |
140 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( | 134 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( |
141 const gpu::SharedMemoryLimits& memory_limits, | 135 const gpu::SharedMemoryLimits& memory_limits, |
142 gpu::CommandBufferProxyImpl* shared_command_buffer, | 136 gpu::CommandBufferProxyImpl* shared_command_buffer, |
143 scoped_refptr<gpu::gles2::ShareGroup> share_group) { | 137 scoped_refptr<gpu::gles2::ShareGroup> share_group, |
| 138 const gpu::gles2::ContextCreationAttribHelper& attributes, |
| 139 command_buffer_metrics::ContextType context_type) { |
144 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::CreateContext"); | 140 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::CreateContext"); |
145 DCHECK_EQ(!!shared_command_buffer, !!share_group); | 141 DCHECK_EQ(!!shared_command_buffer, !!share_group); |
146 | 142 |
147 if (!InitializeCommandBuffer(shared_command_buffer)) { | 143 if (!InitializeCommandBuffer(shared_command_buffer, attributes, |
| 144 context_type)) { |
148 LOG(ERROR) << "Failed to initialize command buffer."; | 145 LOG(ERROR) << "Failed to initialize command buffer."; |
149 return false; | 146 return false; |
150 } | 147 } |
151 | 148 |
152 // Create the GLES2 helper, which writes the command buffer protocol. | 149 // Create the GLES2 helper, which writes the command buffer protocol. |
153 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); | 150 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); |
154 if (!gles2_helper_->Initialize(memory_limits.command_buffer_size)) { | 151 if (!gles2_helper_->Initialize(memory_limits.command_buffer_size)) { |
155 LOG(ERROR) << "Failed to initialize GLES2CmdHelper."; | 152 LOG(ERROR) << "Failed to initialize GLES2CmdHelper."; |
156 return false; | 153 return false; |
157 } | 154 } |
158 | 155 |
159 if (!automatic_flushes_) | 156 if (!automatic_flushes_) |
160 gles2_helper_->SetAutomaticFlushes(false); | 157 gles2_helper_->SetAutomaticFlushes(false); |
161 // Create a transfer buffer used to copy resources between the renderer | 158 // Create a transfer buffer used to copy resources between the renderer |
162 // process and the GPU process. | 159 // process and the GPU process. |
163 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); | 160 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); |
164 | 161 |
165 DCHECK(host_.get()); | 162 DCHECK(host_.get()); |
166 | 163 |
167 const bool bind_generates_resource = attributes_.bind_generates_resource; | 164 const bool bind_generates_resource = attributes.bind_generates_resource; |
168 const bool lose_context_when_out_of_memory = | 165 const bool lose_context_when_out_of_memory = |
169 attributes_.lose_context_when_out_of_memory; | 166 attributes.lose_context_when_out_of_memory; |
170 const bool support_client_side_arrays = false; | 167 const bool support_client_side_arrays = false; |
171 | 168 |
172 // Create the object exposing the OpenGL API. | 169 // Create the object exposing the OpenGL API. |
173 real_gl_.reset(new gpu::gles2::GLES2Implementation( | 170 real_gl_.reset(new gpu::gles2::GLES2Implementation( |
174 gles2_helper_.get(), std::move(share_group), transfer_buffer_.get(), | 171 gles2_helper_.get(), std::move(share_group), transfer_buffer_.get(), |
175 bind_generates_resource, lose_context_when_out_of_memory, | 172 bind_generates_resource, lose_context_when_out_of_memory, |
176 support_client_side_arrays, command_buffer_.get())); | 173 support_client_side_arrays, command_buffer_.get())); |
177 if (!real_gl_->Initialize(memory_limits.start_transfer_buffer_size, | 174 if (!real_gl_->Initialize(memory_limits.start_transfer_buffer_size, |
178 memory_limits.min_transfer_buffer_size, | 175 memory_limits.min_transfer_buffer_size, |
179 memory_limits.max_transfer_buffer_size, | 176 memory_limits.max_transfer_buffer_size, |
180 memory_limits.mapped_memory_reclaim_limit)) { | 177 memory_limits.mapped_memory_reclaim_limit)) { |
181 LOG(ERROR) << "Failed to initialize GLES2Implementation."; | 178 LOG(ERROR) << "Failed to initialize GLES2Implementation."; |
182 return false; | 179 return false; |
183 } | 180 } |
184 | 181 |
185 return true; | 182 return true; |
186 } | 183 } |
187 | 184 |
188 bool WebGraphicsContext3DCommandBufferImpl::InitializeOnCurrentThread( | 185 bool WebGraphicsContext3DCommandBufferImpl::InitializeOnCurrentThread( |
189 const gpu::SharedMemoryLimits& memory_limits, | 186 const gpu::SharedMemoryLimits& memory_limits, |
190 gpu::CommandBufferProxyImpl* shared_command_buffer, | 187 gpu::CommandBufferProxyImpl* shared_command_buffer, |
191 scoped_refptr<gpu::gles2::ShareGroup> share_group) { | 188 scoped_refptr<gpu::gles2::ShareGroup> share_group, |
| 189 const gpu::gles2::ContextCreationAttribHelper& attributes, |
| 190 command_buffer_metrics::ContextType context_type) { |
192 if (!MaybeInitializeGL(memory_limits, shared_command_buffer, | 191 if (!MaybeInitializeGL(memory_limits, shared_command_buffer, |
193 std::move(share_group))) { | 192 std::move(share_group), attributes, context_type)) { |
194 DLOG(ERROR) << "Failed to initialize context."; | 193 DLOG(ERROR) << "Failed to initialize context."; |
195 return false; | 194 return false; |
196 } | 195 } |
197 if (gpu::error::IsError(command_buffer_->GetLastError())) { | 196 if (gpu::error::IsError(command_buffer_->GetLastError())) { |
198 LOG(ERROR) << "Context dead on arrival. Last error: " | 197 LOG(ERROR) << "Context dead on arrival. Last error: " |
199 << command_buffer_->GetLastError(); | 198 << command_buffer_->GetLastError(); |
200 return false; | 199 return false; |
201 } | 200 } |
202 | 201 |
203 return true; | 202 return true; |
(...skipping 11 matching lines...) Expand all Loading... |
215 } | 214 } |
216 | 215 |
217 gpu::ContextSupport* | 216 gpu::ContextSupport* |
218 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() { | 217 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() { |
219 return real_gl_.get(); | 218 return real_gl_.get(); |
220 } | 219 } |
221 | 220 |
222 void WebGraphicsContext3DCommandBufferImpl::OnContextLost() { | 221 void WebGraphicsContext3DCommandBufferImpl::OnContextLost() { |
223 if (context_lost_callback_) | 222 if (context_lost_callback_) |
224 context_lost_callback_->onContextLost(); | 223 context_lost_callback_->onContextLost(); |
225 | |
226 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); | |
227 UmaRecordContextLost(context_type_, state.error, state.context_lost_reason); | |
228 } | 224 } |
229 | 225 |
230 } // namespace content | 226 } // namespace content |
OLD | NEW |