| 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 |