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 #if defined(ENABLE_GPU) | |
6 | |
7 #include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" | 5 #include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" |
8 | 6 |
9 #include <GLES2/gl2.h> | 7 #include <GLES2/gl2.h> |
10 #ifndef GL_GLEXT_PROTOTYPES | 8 #ifndef GL_GLEXT_PROTOTYPES |
11 #define GL_GLEXT_PROTOTYPES 1 | 9 #define GL_GLEXT_PROTOTYPES 1 |
12 #endif | 10 #endif |
13 #include <GLES2/gl2ext.h> | 11 #include <GLES2/gl2ext.h> |
14 | 12 |
15 #include <algorithm> | 13 #include <algorithm> |
16 #include <set> | 14 #include <set> |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 | 81 |
84 // Terminate the library. This must be called after any other functions | 82 // Terminate the library. This must be called after any other functions |
85 // have completed. | 83 // have completed. |
86 static bool Terminate(); | 84 static bool Terminate(); |
87 | 85 |
88 ~GLInProcessContext(); | 86 ~GLInProcessContext(); |
89 | 87 |
90 void PumpCommands(); | 88 void PumpCommands(); |
91 bool GetBufferChanged(int32 transfer_buffer_id); | 89 bool GetBufferChanged(int32 transfer_buffer_id); |
92 | 90 |
93 // Create a GLInProcessContext that renders directly to a view. The view and | |
94 // the associated window must not be destroyed until the returned | |
95 // GLInProcessContext has been destroyed, otherwise the GPU process might | |
96 // attempt to render to an invalid window handle. | |
97 // | |
98 // NOTE: on Mac OS X, this entry point is only used to set up the | |
99 // accelerated compositor's output. On this platform, we actually pass | |
100 // a gfx::PluginWindowHandle in place of the gfx::NativeViewId, | |
101 // because the facility to allocate a fake PluginWindowHandle is | |
102 // already in place. We could add more entry points and messages to | |
103 // allocate both fake PluginWindowHandles and NativeViewIds and map | |
104 // from fake NativeViewIds to PluginWindowHandles, but this seems like | |
105 // unnecessary complexity at the moment. | |
106 // | |
107 static GLInProcessContext* CreateViewContext( | |
108 gfx::PluginWindowHandle render_surface, | |
109 GLInProcessContext* context_group, | |
110 const char* allowed_extensions, | |
111 const int32* attrib_list, | |
112 const GURL& active_url, | |
113 gfx::GpuPreference gpu_preference); | |
114 | |
115 // Create a GLInProcessContext that renders to an offscreen frame buffer. If | 91 // Create a GLInProcessContext that renders to an offscreen frame buffer. If |
116 // parent is not NULL, that GLInProcessContext can access a copy of the | 92 // parent is not NULL, that GLInProcessContext can access a copy of the |
117 // created GLInProcessContext's frame buffer that is updated every time | 93 // created GLInProcessContext's frame buffer that is updated every time |
118 // SwapBuffers is called. It is not as general as shared GLInProcessContexts | 94 // SwapBuffers is called. It is not as general as shared GLInProcessContexts |
119 // in other implementations of OpenGL. If parent is not NULL, it must be used | 95 // in other implementations of OpenGL. If parent is not NULL, it must be used |
120 // on the same thread as the parent. A child GLInProcessContext may not | 96 // on the same thread as the parent. A child GLInProcessContext may not |
121 // outlive its parent. attrib_list must be NULL or a NONE-terminated list of | 97 // outlive its parent. attrib_list must be NULL or a NONE-terminated list of |
122 // attribute/value pairs. | 98 // attribute/value pairs. |
123 static GLInProcessContext* CreateOffscreenContext( | 99 static GLInProcessContext* CreateOffscreenContext( |
124 GLInProcessContext* parent, | 100 GLInProcessContext* parent, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 | 140 |
165 // Return true if GPU process reported GLInProcessContext lost or there was a | 141 // Return true if GPU process reported GLInProcessContext lost or there was a |
166 // problem communicating with the GPU process. | 142 // problem communicating with the GPU process. |
167 bool IsCommandBufferContextLost(); | 143 bool IsCommandBufferContextLost(); |
168 | 144 |
169 CommandBufferService* GetCommandBufferService(); | 145 CommandBufferService* GetCommandBufferService(); |
170 | 146 |
171 private: | 147 private: |
172 explicit GLInProcessContext(GLInProcessContext* parent); | 148 explicit GLInProcessContext(GLInProcessContext* parent); |
173 | 149 |
174 bool Initialize(bool onscreen, | 150 bool Initialize(const gfx::Size& size, |
175 gfx::PluginWindowHandle render_surface, | |
176 const gfx::Size& size, | |
177 GLInProcessContext* context_group, | 151 GLInProcessContext* context_group, |
178 const char* allowed_extensions, | 152 const char* allowed_extensions, |
179 const int32* attrib_list, | 153 const int32* attrib_list, |
180 const GURL& active_url, | 154 const GURL& active_url, |
181 gfx::GpuPreference gpu_preference); | 155 gfx::GpuPreference gpu_preference); |
182 void Destroy(); | 156 void Destroy(); |
183 | 157 |
184 void OnContextLost(); | 158 void OnContextLost(); |
185 | 159 |
186 base::WeakPtr<GLInProcessContext> parent_; | 160 base::WeakPtr<GLInProcessContext> parent_; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 | 207 |
234 static base::LazyInstance<GLES2Initializer> g_gles2_initializer = | 208 static base::LazyInstance<GLES2Initializer> g_gles2_initializer = |
235 LAZY_INSTANCE_INITIALIZER; | 209 LAZY_INSTANCE_INITIALIZER; |
236 | 210 |
237 } // namespace anonymous | 211 } // namespace anonymous |
238 | 212 |
239 GLInProcessContext::~GLInProcessContext() { | 213 GLInProcessContext::~GLInProcessContext() { |
240 Destroy(); | 214 Destroy(); |
241 } | 215 } |
242 | 216 |
243 GLInProcessContext* GLInProcessContext::CreateViewContext( | |
244 gfx::PluginWindowHandle render_surface, | |
245 GLInProcessContext* context_group, | |
246 const char* allowed_extensions, | |
247 const int32* attrib_list, | |
248 const GURL& active_url, | |
249 gfx::GpuPreference gpu_preference) { | |
250 #if defined(ENABLE_GPU) | |
251 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(NULL)); | |
252 if (!context->Initialize( | |
253 true, | |
254 render_surface, | |
255 gfx::Size(), | |
256 context_group, | |
257 allowed_extensions, | |
258 attrib_list, | |
259 active_url, | |
260 gpu_preference)) | |
261 return NULL; | |
262 | |
263 return context.release(); | |
264 #else | |
265 return NULL; | |
266 #endif | |
267 } | |
268 | |
269 GLInProcessContext* GLInProcessContext::CreateOffscreenContext( | 217 GLInProcessContext* GLInProcessContext::CreateOffscreenContext( |
270 GLInProcessContext* parent, | 218 GLInProcessContext* parent, |
271 const gfx::Size& size, | 219 const gfx::Size& size, |
272 GLInProcessContext* context_group, | 220 GLInProcessContext* context_group, |
273 const char* allowed_extensions, | 221 const char* allowed_extensions, |
274 const int32* attrib_list, | 222 const int32* attrib_list, |
275 const GURL& active_url, | 223 const GURL& active_url, |
276 gfx::GpuPreference gpu_preference) { | 224 gfx::GpuPreference gpu_preference) { |
277 #if defined(ENABLE_GPU) | |
278 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(parent)); | 225 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(parent)); |
279 if (!context->Initialize( | 226 if (!context->Initialize( |
280 false, | |
281 gfx::kNullPluginWindow, | |
282 size, | 227 size, |
283 context_group, | 228 context_group, |
284 allowed_extensions, | 229 allowed_extensions, |
285 attrib_list, | 230 attrib_list, |
286 active_url, | 231 active_url, |
287 gpu_preference)) | 232 gpu_preference)) |
288 return NULL; | 233 return NULL; |
289 | 234 |
290 return context.release(); | 235 return context.release(); |
291 #else | |
292 return NULL; | |
293 #endif | |
294 } | 236 } |
295 | 237 |
296 // In the normal command buffer implementation, all commands are passed over IPC | 238 // In the normal command buffer implementation, all commands are passed over IPC |
297 // to the gpu process where they are fed to the GLES2Decoder from a single | 239 // to the gpu process where they are fed to the GLES2Decoder from a single |
298 // thread. In layout tests, any thread could call this function. GLES2Decoder, | 240 // thread. In layout tests, any thread could call this function. GLES2Decoder, |
299 // and in particular the GL implementations behind it, are not generally | 241 // and in particular the GL implementations behind it, are not generally |
300 // threadsafe, so we guard entry points with a mutex. | 242 // threadsafe, so we guard entry points with a mutex. |
301 static base::LazyInstance<base::Lock> g_decoder_lock = | 243 static base::LazyInstance<base::Lock> g_decoder_lock = |
302 LAZY_INSTANCE_INITIALIZER; | 244 LAZY_INSTANCE_INITIALIZER; |
303 | 245 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 return gles2_implementation_.get(); | 334 return gles2_implementation_.get(); |
393 } | 335 } |
394 | 336 |
395 GLInProcessContext::GLInProcessContext(GLInProcessContext* parent) | 337 GLInProcessContext::GLInProcessContext(GLInProcessContext* parent) |
396 : parent_(parent ? | 338 : parent_(parent ? |
397 parent->AsWeakPtr() : base::WeakPtr<GLInProcessContext>()), | 339 parent->AsWeakPtr() : base::WeakPtr<GLInProcessContext>()), |
398 parent_texture_id_(0), | 340 parent_texture_id_(0), |
399 last_error_(SUCCESS) { | 341 last_error_(SUCCESS) { |
400 } | 342 } |
401 | 343 |
402 bool GLInProcessContext::Initialize(bool onscreen, | 344 bool GLInProcessContext::Initialize(const gfx::Size& size, |
403 gfx::PluginWindowHandle render_surface, | |
404 const gfx::Size& size, | |
405 GLInProcessContext* context_group, | 345 GLInProcessContext* context_group, |
406 const char* allowed_extensions, | 346 const char* allowed_extensions, |
407 const int32* attrib_list, | 347 const int32* attrib_list, |
408 const GURL& active_url, | 348 const GURL& active_url, |
409 gfx::GpuPreference gpu_preference) { | 349 gfx::GpuPreference gpu_preference) { |
410 // Use one share group for all contexts. | 350 // Use one share group for all contexts. |
411 CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group, | 351 CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group, |
412 (new gfx::GLShareGroup)); | 352 (new gfx::GLShareGroup)); |
413 | 353 |
414 DCHECK(size.width() >= 0 && size.height() >= 0); | 354 DCHECK(size.width() >= 0 && size.height() >= 0); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group ? | 405 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group ? |
466 context_group->decoder_->GetContextGroup() : | 406 context_group->decoder_->GetContextGroup() : |
467 new ::gpu::gles2::ContextGroup(bind_generates_resource))); | 407 new ::gpu::gles2::ContextGroup(bind_generates_resource))); |
468 | 408 |
469 gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(), | 409 gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(), |
470 decoder_.get(), | 410 decoder_.get(), |
471 decoder_.get())); | 411 decoder_.get())); |
472 | 412 |
473 decoder_->set_engine(gpu_scheduler_.get()); | 413 decoder_->set_engine(gpu_scheduler_.get()); |
474 | 414 |
475 if (onscreen) { | 415 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1)); |
476 if (render_surface == gfx::kNullPluginWindow) { | |
477 LOG(ERROR) << "Invalid surface handle for onscreen context."; | |
478 command_buffer_.reset(); | |
479 } else { | |
480 surface_ = gfx::GLSurface::CreateViewGLSurface(false, render_surface); | |
481 } | |
482 } else { | |
483 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(false, | |
484 gfx::Size(1, 1)); | |
485 } | |
486 | 416 |
487 if (!surface_.get()) { | 417 if (!surface_.get()) { |
488 LOG(ERROR) << "Could not create GLSurface."; | 418 LOG(ERROR) << "Could not create GLSurface."; |
489 Destroy(); | 419 Destroy(); |
490 return false; | 420 return false; |
491 } | 421 } |
492 | 422 |
493 context_ = gfx::GLContext::CreateGLContext(share_group.get(), | 423 context_ = gfx::GLContext::CreateGLContext(share_group.get(), |
494 surface_.get(), | 424 surface_.get(), |
495 gpu_preference); | 425 gpu_preference); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 void GLInProcessContext::OnContextLost() { | 506 void GLInProcessContext::OnContextLost() { |
577 if (!context_lost_callback_.is_null()) | 507 if (!context_lost_callback_.is_null()) |
578 context_lost_callback_.Run(); | 508 context_lost_callback_.Run(); |
579 } | 509 } |
580 | 510 |
581 WebGraphicsContext3DInProcessCommandBufferImpl:: | 511 WebGraphicsContext3DInProcessCommandBufferImpl:: |
582 WebGraphicsContext3DInProcessCommandBufferImpl() | 512 WebGraphicsContext3DInProcessCommandBufferImpl() |
583 : context_(NULL), | 513 : context_(NULL), |
584 gl_(NULL), | 514 gl_(NULL), |
585 web_view_(NULL), | 515 web_view_(NULL), |
586 #if defined(OS_MACOSX) | |
587 plugin_handle_(NULL), | |
588 #endif // defined(OS_MACOSX) | |
589 context_lost_callback_(NULL), | 516 context_lost_callback_(NULL), |
590 context_lost_reason_(GL_NO_ERROR), | 517 context_lost_reason_(GL_NO_ERROR), |
591 cached_width_(0), | 518 cached_width_(0), |
592 cached_height_(0), | 519 cached_height_(0), |
593 bound_fbo_(0) { | 520 bound_fbo_(0) { |
594 } | 521 } |
595 | 522 |
596 WebGraphicsContext3DInProcessCommandBufferImpl:: | 523 WebGraphicsContext3DInProcessCommandBufferImpl:: |
597 ~WebGraphicsContext3DInProcessCommandBufferImpl() { | 524 ~WebGraphicsContext3DInProcessCommandBufferImpl() { |
598 base::AutoLock a(g_all_shared_contexts_lock.Get()); | 525 base::AutoLock a(g_all_shared_contexts_lock.Get()); |
(...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 void WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost() { | 1583 void WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost() { |
1657 // TODO(kbr): improve the precision here. | 1584 // TODO(kbr): improve the precision here. |
1658 context_lost_reason_ = GL_UNKNOWN_CONTEXT_RESET_ARB; | 1585 context_lost_reason_ = GL_UNKNOWN_CONTEXT_RESET_ARB; |
1659 if (context_lost_callback_) { | 1586 if (context_lost_callback_) { |
1660 context_lost_callback_->onContextLost(); | 1587 context_lost_callback_->onContextLost(); |
1661 } | 1588 } |
1662 } | 1589 } |
1663 | 1590 |
1664 } // namespace gpu | 1591 } // namespace gpu |
1665 } // namespace webkit | 1592 } // namespace webkit |
1666 | |
1667 #endif // defined(ENABLE_GPU) | |
OLD | NEW |