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/renderer/pepper/ppb_graphics_3d_impl.h" | 5 #include "content/renderer/pepper/ppb_graphics_3d_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 namespace { | 37 namespace { |
38 const int32 kCommandBufferSize = 1024 * 1024; | 38 const int32 kCommandBufferSize = 1024 * 1024; |
39 const int32 kTransferBufferSize = 1024 * 1024; | 39 const int32 kTransferBufferSize = 1024 * 1024; |
40 | 40 |
41 } // namespace. | 41 } // namespace. |
42 | 42 |
43 PPB_Graphics3D_Impl::PPB_Graphics3D_Impl(PP_Instance instance) | 43 PPB_Graphics3D_Impl::PPB_Graphics3D_Impl(PP_Instance instance) |
44 : PPB_Graphics3D_Shared(instance), | 44 : PPB_Graphics3D_Shared(instance), |
45 bound_to_instance_(false), | 45 bound_to_instance_(false), |
46 commit_pending_(false), | 46 commit_pending_(false), |
47 weak_ptr_factory_(this) { | 47 weak_ptr_factory_(this) {} |
48 } | |
49 | 48 |
50 PPB_Graphics3D_Impl::~PPB_Graphics3D_Impl() { | 49 PPB_Graphics3D_Impl::~PPB_Graphics3D_Impl() { DestroyGLES2Impl(); } |
51 DestroyGLES2Impl(); | |
52 } | |
53 | 50 |
54 // static | 51 // static |
55 PP_Resource PPB_Graphics3D_Impl::Create(PP_Instance instance, | 52 PP_Resource PPB_Graphics3D_Impl::Create(PP_Instance instance, |
56 PP_Resource share_context, | 53 PP_Resource share_context, |
57 const int32_t* attrib_list) { | 54 const int32_t* attrib_list) { |
58 PPB_Graphics3D_API* share_api = NULL; | 55 PPB_Graphics3D_API* share_api = NULL; |
59 if (share_context) { | 56 if (share_context) { |
60 EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true); | 57 EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true); |
61 if (enter.failed()) | 58 if (enter.failed()) |
62 return 0; | 59 return 0; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 | 125 |
129 uint32_t PPB_Graphics3D_Impl::InsertSyncPoint() { | 126 uint32_t PPB_Graphics3D_Impl::InsertSyncPoint() { |
130 return platform_context_->GetGpuControl()->InsertSyncPoint(); | 127 return platform_context_->GetGpuControl()->InsertSyncPoint(); |
131 } | 128 } |
132 | 129 |
133 bool PPB_Graphics3D_Impl::BindToInstance(bool bind) { | 130 bool PPB_Graphics3D_Impl::BindToInstance(bool bind) { |
134 bound_to_instance_ = bind; | 131 bound_to_instance_ = bind; |
135 return true; | 132 return true; |
136 } | 133 } |
137 | 134 |
138 bool PPB_Graphics3D_Impl::IsOpaque() { | 135 bool PPB_Graphics3D_Impl::IsOpaque() { return platform_context_->IsOpaque(); } |
139 return platform_context_->IsOpaque(); | |
140 } | |
141 | 136 |
142 void PPB_Graphics3D_Impl::ViewInitiatedPaint() { | 137 void PPB_Graphics3D_Impl::ViewInitiatedPaint() { |
143 commit_pending_ = false; | 138 commit_pending_ = false; |
144 | 139 |
145 if (HasPendingSwap()) | 140 if (HasPendingSwap()) |
146 SwapBuffersACK(PP_OK); | 141 SwapBuffersACK(PP_OK); |
147 } | 142 } |
148 | 143 |
149 void PPB_Graphics3D_Impl::ViewFlushedPaint() { | 144 void PPB_Graphics3D_Impl::ViewFlushedPaint() {} |
150 } | |
151 | 145 |
152 gpu::CommandBuffer* PPB_Graphics3D_Impl::GetCommandBuffer() { | 146 gpu::CommandBuffer* PPB_Graphics3D_Impl::GetCommandBuffer() { |
153 return platform_context_->GetCommandBuffer(); | 147 return platform_context_->GetCommandBuffer(); |
154 } | 148 } |
155 | 149 |
156 gpu::GpuControl* PPB_Graphics3D_Impl::GetGpuControl() { | 150 gpu::GpuControl* PPB_Graphics3D_Impl::GetGpuControl() { |
157 return platform_context_->GetGpuControl(); | 151 return platform_context_->GetGpuControl(); |
158 } | 152 } |
159 | 153 |
160 int32 PPB_Graphics3D_Impl::DoSwapBuffers() { | 154 int32 PPB_Graphics3D_Impl::DoSwapBuffers() { |
(...skipping 16 matching lines...) Expand all Loading... |
177 // Don't need to check for NULL from GetPluginInstance since when we're | 171 // Don't need to check for NULL from GetPluginInstance since when we're |
178 // bound, we know our instance is valid. | 172 // bound, we know our instance is valid. |
179 HostGlobals::Get()->GetInstance(pp_instance())->CommitBackingTexture(); | 173 HostGlobals::Get()->GetInstance(pp_instance())->CommitBackingTexture(); |
180 commit_pending_ = true; | 174 commit_pending_ = true; |
181 } else { | 175 } else { |
182 // Wait for the command to complete on the GPU to allow for throttling. | 176 // Wait for the command to complete on the GPU to allow for throttling. |
183 platform_context_->Echo(base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers, | 177 platform_context_->Echo(base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers, |
184 weak_ptr_factory_.GetWeakPtr())); | 178 weak_ptr_factory_.GetWeakPtr())); |
185 } | 179 } |
186 | 180 |
187 | |
188 return PP_OK_COMPLETIONPENDING; | 181 return PP_OK_COMPLETIONPENDING; |
189 } | 182 } |
190 | 183 |
191 bool PPB_Graphics3D_Impl::Init(PPB_Graphics3D_API* share_context, | 184 bool PPB_Graphics3D_Impl::Init(PPB_Graphics3D_API* share_context, |
192 const int32_t* attrib_list) { | 185 const int32_t* attrib_list) { |
193 if (!InitRaw(share_context, attrib_list)) | 186 if (!InitRaw(share_context, attrib_list)) |
194 return false; | 187 return false; |
195 | 188 |
196 gpu::CommandBuffer* command_buffer = GetCommandBuffer(); | 189 gpu::CommandBuffer* command_buffer = GetCommandBuffer(); |
197 if (!command_buffer->Initialize()) | 190 if (!command_buffer->Initialize()) |
198 return false; | 191 return false; |
199 | 192 |
200 gpu::gles2::GLES2Implementation* share_gles2 = NULL; | 193 gpu::gles2::GLES2Implementation* share_gles2 = NULL; |
201 if (share_context) { | 194 if (share_context) { |
202 share_gles2 = | 195 share_gles2 = |
203 static_cast<PPB_Graphics3D_Shared*>(share_context)->gles2_impl(); | 196 static_cast<PPB_Graphics3D_Shared*>(share_context)->gles2_impl(); |
204 } | 197 } |
205 | 198 |
206 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize, | 199 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize, share_gles2); |
207 share_gles2); | |
208 } | 200 } |
209 | 201 |
210 bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context, | 202 bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context, |
211 const int32_t* attrib_list) { | 203 const int32_t* attrib_list) { |
212 PepperPluginInstanceImpl* plugin_instance = | 204 PepperPluginInstanceImpl* plugin_instance = |
213 HostGlobals::Get()->GetInstance(pp_instance()); | 205 HostGlobals::Get()->GetInstance(pp_instance()); |
214 if (!plugin_instance) | 206 if (!plugin_instance) |
215 return false; | 207 return false; |
216 | 208 |
217 const WebPreferences& prefs = static_cast<RenderViewImpl*>(plugin_instance-> | 209 const WebPreferences& prefs = |
218 GetRenderView())->webkit_preferences(); | 210 static_cast<RenderViewImpl*>(plugin_instance->GetRenderView()) |
| 211 ->webkit_preferences(); |
219 // 3D access might be disabled or blacklisted. | 212 // 3D access might be disabled or blacklisted. |
220 if (!prefs.pepper_3d_enabled) | 213 if (!prefs.pepper_3d_enabled) |
221 return false; | 214 return false; |
222 // If accelerated compositing of plugins is disabled, fail to create a 3D | 215 // If accelerated compositing of plugins is disabled, fail to create a 3D |
223 // context, because it won't be visible. This allows graceful fallback in the | 216 // context, because it won't be visible. This allows graceful fallback in the |
224 // modules. | 217 // modules. |
225 if (!prefs.accelerated_compositing_for_plugins_enabled) | 218 if (!prefs.accelerated_compositing_for_plugins_enabled) |
226 return false; | 219 return false; |
227 | 220 |
228 platform_context_.reset(new PlatformContext3D); | 221 platform_context_.reset(new PlatformContext3D); |
229 if (!platform_context_) | 222 if (!platform_context_) |
230 return false; | 223 return false; |
231 | 224 |
232 PlatformContext3D* share_platform_context = NULL; | 225 PlatformContext3D* share_platform_context = NULL; |
233 if (share_context) { | 226 if (share_context) { |
234 PPB_Graphics3D_Impl* share_graphics = | 227 PPB_Graphics3D_Impl* share_graphics = |
235 static_cast<PPB_Graphics3D_Impl*>(share_context); | 228 static_cast<PPB_Graphics3D_Impl*>(share_context); |
236 share_platform_context = share_graphics->platform_context(); | 229 share_platform_context = share_graphics->platform_context(); |
237 } | 230 } |
238 | 231 |
239 if (!platform_context_->Init(attrib_list, share_platform_context)) | 232 if (!platform_context_->Init(attrib_list, share_platform_context)) |
240 return false; | 233 return false; |
241 | 234 |
242 platform_context_->SetContextLostCallback( | 235 platform_context_->SetContextLostCallback(base::Bind( |
243 base::Bind(&PPB_Graphics3D_Impl::OnContextLost, | 236 &PPB_Graphics3D_Impl::OnContextLost, weak_ptr_factory_.GetWeakPtr())); |
244 weak_ptr_factory_.GetWeakPtr())); | |
245 | 237 |
246 platform_context_->SetOnConsoleMessageCallback( | 238 platform_context_->SetOnConsoleMessageCallback(base::Bind( |
247 base::Bind(&PPB_Graphics3D_Impl::OnConsoleMessage, | 239 &PPB_Graphics3D_Impl::OnConsoleMessage, weak_ptr_factory_.GetWeakPtr())); |
248 weak_ptr_factory_.GetWeakPtr())); | |
249 return true; | 240 return true; |
250 } | 241 } |
251 | 242 |
252 void PPB_Graphics3D_Impl::OnConsoleMessage(const std::string& message, | 243 void PPB_Graphics3D_Impl::OnConsoleMessage(const std::string& message, int id) { |
253 int id) { | |
254 if (!bound_to_instance_) | 244 if (!bound_to_instance_) |
255 return; | 245 return; |
256 WebPluginContainer* container = | 246 WebPluginContainer* container = |
257 HostGlobals::Get()->GetInstance(pp_instance())->container(); | 247 HostGlobals::Get()->GetInstance(pp_instance())->container(); |
258 if (!container) | 248 if (!container) |
259 return; | 249 return; |
260 WebFrame* frame = container->element().document().frame(); | 250 WebFrame* frame = container->element().document().frame(); |
261 if (!frame) | 251 if (!frame) |
262 return; | 252 return; |
263 WebConsoleMessage console_message = WebConsoleMessage( | 253 WebConsoleMessage console_message = WebConsoleMessage( |
264 WebConsoleMessage::LevelError, WebString(base::UTF8ToUTF16(message))); | 254 WebConsoleMessage::LevelError, WebString(base::UTF8ToUTF16(message))); |
265 frame->addMessageToConsole(console_message); | 255 frame->addMessageToConsole(console_message); |
266 } | 256 } |
267 | 257 |
268 void PPB_Graphics3D_Impl::OnSwapBuffers() { | 258 void PPB_Graphics3D_Impl::OnSwapBuffers() { |
269 if (HasPendingSwap()) { | 259 if (HasPendingSwap()) { |
270 // If we're off-screen, no need to trigger and wait for compositing. | 260 // If we're off-screen, no need to trigger and wait for compositing. |
271 // Just send the swap-buffers ACK to the plugin immediately. | 261 // Just send the swap-buffers ACK to the plugin immediately. |
272 commit_pending_ = false; | 262 commit_pending_ = false; |
273 SwapBuffersACK(PP_OK); | 263 SwapBuffersACK(PP_OK); |
274 } | 264 } |
275 } | 265 } |
276 | 266 |
277 void PPB_Graphics3D_Impl::OnContextLost() { | 267 void PPB_Graphics3D_Impl::OnContextLost() { |
278 // Don't need to check for NULL from GetPluginInstance since when we're | 268 // Don't need to check for NULL from GetPluginInstance since when we're |
279 // bound, we know our instance is valid. | 269 // bound, we know our instance is valid. |
280 if (bound_to_instance_) { | 270 if (bound_to_instance_) { |
281 HostGlobals::Get()->GetInstance(pp_instance())->BindGraphics( | 271 HostGlobals::Get()->GetInstance(pp_instance())->BindGraphics(pp_instance(), |
282 pp_instance(), 0); | 272 0); |
283 } | 273 } |
284 | 274 |
285 // Send context lost to plugin. This may have been caused by a PPAPI call, so | 275 // Send context lost to plugin. This may have been caused by a PPAPI call, so |
286 // avoid re-entering. | 276 // avoid re-entering. |
287 base::MessageLoop::current()->PostTask( | 277 base::MessageLoop::current()->PostTask( |
288 FROM_HERE, | 278 FROM_HERE, |
289 base::Bind(&PPB_Graphics3D_Impl::SendContextLost, | 279 base::Bind(&PPB_Graphics3D_Impl::SendContextLost, |
290 weak_ptr_factory_.GetWeakPtr())); | 280 weak_ptr_factory_.GetWeakPtr())); |
291 } | 281 } |
292 | 282 |
293 void PPB_Graphics3D_Impl::SendContextLost() { | 283 void PPB_Graphics3D_Impl::SendContextLost() { |
294 // By the time we run this, the instance may have been deleted, or in the | 284 // By the time we run this, the instance may have been deleted, or in the |
295 // process of being deleted. Even in the latter case, we don't want to send a | 285 // process of being deleted. Even in the latter case, we don't want to send a |
296 // callback after DidDestroy. | 286 // callback after DidDestroy. |
297 PepperPluginInstanceImpl* instance = | 287 PepperPluginInstanceImpl* instance = |
298 HostGlobals::Get()->GetInstance(pp_instance()); | 288 HostGlobals::Get()->GetInstance(pp_instance()); |
299 if (!instance || !instance->container()) | 289 if (!instance || !instance->container()) |
300 return; | 290 return; |
301 | 291 |
302 // This PPB_Graphics3D_Impl could be deleted during the call to | 292 // This PPB_Graphics3D_Impl could be deleted during the call to |
303 // GetPluginInterface (which sends a sync message in some cases). We still | 293 // GetPluginInterface (which sends a sync message in some cases). We still |
304 // send the Graphics3DContextLost to the plugin; the instance may care about | 294 // send the Graphics3DContextLost to the plugin; the instance may care about |
305 // that event even though this context has been destroyed. | 295 // that event even though this context has been destroyed. |
306 PP_Instance this_pp_instance = pp_instance(); | 296 PP_Instance this_pp_instance = pp_instance(); |
307 const PPP_Graphics3D* ppp_graphics_3d = | 297 const PPP_Graphics3D* ppp_graphics_3d = static_cast<const PPP_Graphics3D*>( |
308 static_cast<const PPP_Graphics3D*>( | 298 instance->module()->GetPluginInterface(PPP_GRAPHICS_3D_INTERFACE)); |
309 instance->module()->GetPluginInterface( | |
310 PPP_GRAPHICS_3D_INTERFACE)); | |
311 // We have to check *again* that the instance exists, because it could have | 299 // We have to check *again* that the instance exists, because it could have |
312 // been deleted during GetPluginInterface(). Even the PluginModule could be | 300 // been deleted during GetPluginInterface(). Even the PluginModule could be |
313 // deleted, but in that case, the instance should also be gone, so the | 301 // deleted, but in that case, the instance should also be gone, so the |
314 // GetInstance check covers both cases. | 302 // GetInstance check covers both cases. |
315 if (ppp_graphics_3d && HostGlobals::Get()->GetInstance(this_pp_instance)) | 303 if (ppp_graphics_3d && HostGlobals::Get()->GetInstance(this_pp_instance)) |
316 ppp_graphics_3d->Graphics3DContextLost(this_pp_instance); | 304 ppp_graphics_3d->Graphics3DContextLost(this_pp_instance); |
317 } | 305 } |
318 | 306 |
319 } // namespace content | 307 } // namespace content |
OLD | NEW |