| 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 "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" | 5 #include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" |
| 6 | 6 |
| 7 #include <GLES2/gl2.h> | 7 #include <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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 // 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 |
| 96 // 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 |
| 97 // 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 |
| 98 // attribute/value pairs. | 98 // attribute/value pairs. |
| 99 static GLInProcessContext* CreateOffscreenContext( | 99 static GLInProcessContext* CreateOffscreenContext( |
| 100 GLInProcessContext* parent, | 100 GLInProcessContext* parent, |
| 101 const gfx::Size& size, | 101 const gfx::Size& size, |
| 102 GLInProcessContext* context_group, | 102 GLInProcessContext* context_group, |
| 103 const char* allowed_extensions, | 103 const char* allowed_extensions, |
| 104 const int32* attrib_list, | 104 const int32* attrib_list, |
| 105 const GURL& active_url, | |
| 106 gfx::GpuPreference gpu_preference); | 105 gfx::GpuPreference gpu_preference); |
| 107 | 106 |
| 108 // For an offscreen frame buffer GLInProcessContext, return the texture ID | 107 // For an offscreen frame buffer GLInProcessContext, return the texture ID |
| 109 // with respect to the parent GLInProcessContext. Returns zero if | 108 // with respect to the parent GLInProcessContext. Returns zero if |
| 110 // GLInProcessContext does not have a parent. | 109 // GLInProcessContext does not have a parent. |
| 111 uint32 GetParentTextureId(); | 110 uint32 GetParentTextureId(); |
| 112 | 111 |
| 113 // Create a new texture in the parent's GLInProcessContext. Returns zero if | 112 // Create a new texture in the parent's GLInProcessContext. Returns zero if |
| 114 // GLInProcessContext does not have a parent. | 113 // GLInProcessContext does not have a parent. |
| 115 uint32 CreateParentTexture(const gfx::Size& size); | 114 uint32 CreateParentTexture(const gfx::Size& size); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 144 | 143 |
| 145 CommandBufferService* GetCommandBufferService(); | 144 CommandBufferService* GetCommandBufferService(); |
| 146 | 145 |
| 147 private: | 146 private: |
| 148 explicit GLInProcessContext(GLInProcessContext* parent); | 147 explicit GLInProcessContext(GLInProcessContext* parent); |
| 149 | 148 |
| 150 bool Initialize(const gfx::Size& size, | 149 bool Initialize(const gfx::Size& size, |
| 151 GLInProcessContext* context_group, | 150 GLInProcessContext* context_group, |
| 152 const char* allowed_extensions, | 151 const char* allowed_extensions, |
| 153 const int32* attrib_list, | 152 const int32* attrib_list, |
| 154 const GURL& active_url, | |
| 155 gfx::GpuPreference gpu_preference); | 153 gfx::GpuPreference gpu_preference); |
| 156 void Destroy(); | 154 void Destroy(); |
| 157 | 155 |
| 158 void OnContextLost(); | 156 void OnContextLost(); |
| 159 | 157 |
| 160 base::WeakPtr<GLInProcessContext> parent_; | 158 base::WeakPtr<GLInProcessContext> parent_; |
| 161 base::Closure context_lost_callback_; | 159 base::Closure context_lost_callback_; |
| 162 uint32 parent_texture_id_; | 160 uint32 parent_texture_id_; |
| 163 scoped_ptr<CommandBufferService> command_buffer_; | 161 scoped_ptr<CommandBufferService> command_buffer_; |
| 164 scoped_ptr< ::gpu::GpuScheduler> gpu_scheduler_; | 162 scoped_ptr< ::gpu::GpuScheduler> gpu_scheduler_; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 GLInProcessContext::~GLInProcessContext() { | 211 GLInProcessContext::~GLInProcessContext() { |
| 214 Destroy(); | 212 Destroy(); |
| 215 } | 213 } |
| 216 | 214 |
| 217 GLInProcessContext* GLInProcessContext::CreateOffscreenContext( | 215 GLInProcessContext* GLInProcessContext::CreateOffscreenContext( |
| 218 GLInProcessContext* parent, | 216 GLInProcessContext* parent, |
| 219 const gfx::Size& size, | 217 const gfx::Size& size, |
| 220 GLInProcessContext* context_group, | 218 GLInProcessContext* context_group, |
| 221 const char* allowed_extensions, | 219 const char* allowed_extensions, |
| 222 const int32* attrib_list, | 220 const int32* attrib_list, |
| 223 const GURL& active_url, | |
| 224 gfx::GpuPreference gpu_preference) { | 221 gfx::GpuPreference gpu_preference) { |
| 225 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(parent)); | 222 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(parent)); |
| 226 if (!context->Initialize( | 223 if (!context->Initialize( |
| 227 size, | 224 size, |
| 228 context_group, | 225 context_group, |
| 229 allowed_extensions, | 226 allowed_extensions, |
| 230 attrib_list, | 227 attrib_list, |
| 231 active_url, | |
| 232 gpu_preference)) | 228 gpu_preference)) |
| 233 return NULL; | 229 return NULL; |
| 234 | 230 |
| 235 return context.release(); | 231 return context.release(); |
| 236 } | 232 } |
| 237 | 233 |
| 238 // In the normal command buffer implementation, all commands are passed over IPC | 234 // In the normal command buffer implementation, all commands are passed over IPC |
| 239 // to the gpu process where they are fed to the GLES2Decoder from a single | 235 // to the gpu process where they are fed to the GLES2Decoder from a single |
| 240 // thread. In layout tests, any thread could call this function. GLES2Decoder, | 236 // thread. In layout tests, any thread could call this function. GLES2Decoder, |
| 241 // and in particular the GL implementations behind it, are not generally | 237 // and in particular the GL implementations behind it, are not generally |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 : parent_(parent ? | 334 : parent_(parent ? |
| 339 parent->AsWeakPtr() : base::WeakPtr<GLInProcessContext>()), | 335 parent->AsWeakPtr() : base::WeakPtr<GLInProcessContext>()), |
| 340 parent_texture_id_(0), | 336 parent_texture_id_(0), |
| 341 last_error_(SUCCESS) { | 337 last_error_(SUCCESS) { |
| 342 } | 338 } |
| 343 | 339 |
| 344 bool GLInProcessContext::Initialize(const gfx::Size& size, | 340 bool GLInProcessContext::Initialize(const gfx::Size& size, |
| 345 GLInProcessContext* context_group, | 341 GLInProcessContext* context_group, |
| 346 const char* allowed_extensions, | 342 const char* allowed_extensions, |
| 347 const int32* attrib_list, | 343 const int32* attrib_list, |
| 348 const GURL& active_url, | |
| 349 gfx::GpuPreference gpu_preference) { | 344 gfx::GpuPreference gpu_preference) { |
| 350 // Use one share group for all contexts. | 345 // Use one share group for all contexts. |
| 351 CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group, | 346 CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group, |
| 352 (new gfx::GLShareGroup)); | 347 (new gfx::GLShareGroup)); |
| 353 | 348 |
| 354 DCHECK(size.width() >= 0 && size.height() >= 0); | 349 DCHECK(size.width() >= 0 && size.height() >= 0); |
| 355 | 350 |
| 356 // Ensure the gles2 library is initialized first in a thread safe way. | 351 // Ensure the gles2 library is initialized first in a thread safe way. |
| 357 g_gles2_initializer.Get(); | 352 g_gles2_initializer.Get(); |
| 358 | 353 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 | 500 |
| 506 void GLInProcessContext::OnContextLost() { | 501 void GLInProcessContext::OnContextLost() { |
| 507 if (!context_lost_callback_.is_null()) | 502 if (!context_lost_callback_.is_null()) |
| 508 context_lost_callback_.Run(); | 503 context_lost_callback_.Run(); |
| 509 } | 504 } |
| 510 | 505 |
| 511 WebGraphicsContext3DInProcessCommandBufferImpl:: | 506 WebGraphicsContext3DInProcessCommandBufferImpl:: |
| 512 WebGraphicsContext3DInProcessCommandBufferImpl() | 507 WebGraphicsContext3DInProcessCommandBufferImpl() |
| 513 : context_(NULL), | 508 : context_(NULL), |
| 514 gl_(NULL), | 509 gl_(NULL), |
| 515 web_view_(NULL), | |
| 516 context_lost_callback_(NULL), | 510 context_lost_callback_(NULL), |
| 517 context_lost_reason_(GL_NO_ERROR), | 511 context_lost_reason_(GL_NO_ERROR), |
| 518 cached_width_(0), | 512 cached_width_(0), |
| 519 cached_height_(0), | 513 cached_height_(0), |
| 520 bound_fbo_(0) { | 514 bound_fbo_(0) { |
| 521 } | 515 } |
| 522 | 516 |
| 523 WebGraphicsContext3DInProcessCommandBufferImpl:: | 517 WebGraphicsContext3DInProcessCommandBufferImpl:: |
| 524 ~WebGraphicsContext3DInProcessCommandBufferImpl() { | 518 ~WebGraphicsContext3DInProcessCommandBufferImpl() { |
| 525 base::AutoLock a(g_all_shared_contexts_lock.Get()); | 519 base::AutoLock a(g_all_shared_contexts_lock.Get()); |
| 526 g_all_shared_contexts.Pointer()->erase(this); | 520 g_all_shared_contexts.Pointer()->erase(this); |
| 527 } | 521 } |
| 528 | 522 |
| 529 bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize( | 523 bool WebGraphicsContext3DInProcessCommandBufferImpl::Initialize( |
| 530 WebGraphicsContext3D::Attributes attributes, | 524 WebGraphicsContext3D::Attributes attributes, |
| 531 WebKit::WebView* web_view, | 525 WebKit::WebGraphicsContext3D* view_context) { |
| 532 bool render_directly_to_web_view) { | |
| 533 // Convert WebGL context creation attributes into GLInProcessContext / EGL | 526 // Convert WebGL context creation attributes into GLInProcessContext / EGL |
| 534 // size requests. | 527 // size requests. |
| 535 const int alpha_size = attributes.alpha ? 8 : 0; | 528 const int alpha_size = attributes.alpha ? 8 : 0; |
| 536 const int depth_size = attributes.depth ? 24 : 0; | 529 const int depth_size = attributes.depth ? 24 : 0; |
| 537 const int stencil_size = attributes.stencil ? 8 : 0; | 530 const int stencil_size = attributes.stencil ? 8 : 0; |
| 538 const int samples = attributes.antialias ? 4 : 0; | 531 const int samples = attributes.antialias ? 4 : 0; |
| 539 const int sample_buffers = attributes.antialias ? 1 : 0; | 532 const int sample_buffers = attributes.antialias ? 1 : 0; |
| 540 const int32 attribs[] = { | 533 const int32 attribs[] = { |
| 541 GLInProcessContext::ALPHA_SIZE, alpha_size, | 534 GLInProcessContext::ALPHA_SIZE, alpha_size, |
| 542 GLInProcessContext::DEPTH_SIZE, depth_size, | 535 GLInProcessContext::DEPTH_SIZE, depth_size, |
| 543 GLInProcessContext::STENCIL_SIZE, stencil_size, | 536 GLInProcessContext::STENCIL_SIZE, stencil_size, |
| 544 GLInProcessContext::SAMPLES, samples, | 537 GLInProcessContext::SAMPLES, samples, |
| 545 GLInProcessContext::SAMPLE_BUFFERS, sample_buffers, | 538 GLInProcessContext::SAMPLE_BUFFERS, sample_buffers, |
| 546 GLInProcessContext::NONE, | 539 GLInProcessContext::NONE, |
| 547 }; | 540 }; |
| 548 | 541 |
| 549 const char* preferred_extensions = "*"; | 542 const char* preferred_extensions = "*"; |
| 550 | 543 |
| 551 // TODO(kbr): More work will be needed in this implementation to | 544 // TODO(kbr): More work will be needed in this implementation to |
| 552 // properly support GPU switching. Like in the out-of-process | 545 // properly support GPU switching. Like in the out-of-process |
| 553 // command buffer implementation, all previously created contexts | 546 // command buffer implementation, all previously created contexts |
| 554 // will need to be lost either when the first context requesting the | 547 // will need to be lost either when the first context requesting the |
| 555 // discrete GPU is created, or the last one is destroyed. | 548 // discrete GPU is created, or the last one is destroyed. |
| 556 gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; | 549 gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; |
| 557 | 550 |
| 558 GURL active_url; | |
| 559 if (web_view && web_view->mainFrame()) | |
| 560 active_url = GURL(web_view->mainFrame()->document().url()); | |
| 561 | |
| 562 GLInProcessContext* parent_context = NULL; | 551 GLInProcessContext* parent_context = NULL; |
| 563 if (!render_directly_to_web_view) { | 552 if (view_context) { |
| 564 WebKit::WebGraphicsContext3D* view_context = | 553 WebGraphicsContext3DInProcessCommandBufferImpl* context_impl = |
| 565 web_view ? web_view->graphicsContext3D() : NULL; | 554 static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>( |
| 566 if (view_context) { | 555 view_context); |
| 567 WebGraphicsContext3DInProcessCommandBufferImpl* context_impl = | 556 parent_context = context_impl->context_; |
| 568 static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>( | |
| 569 view_context); | |
| 570 parent_context = context_impl->context_; | |
| 571 } | |
| 572 } | 557 } |
| 573 | 558 |
| 574 WebGraphicsContext3DInProcessCommandBufferImpl* context_group = NULL; | 559 WebGraphicsContext3DInProcessCommandBufferImpl* context_group = NULL; |
| 575 base::AutoLock lock(g_all_shared_contexts_lock.Get()); | 560 base::AutoLock lock(g_all_shared_contexts_lock.Get()); |
| 576 if (attributes.shareResources) | 561 if (attributes.shareResources) |
| 577 context_group = g_all_shared_contexts.Pointer()->empty() ? | 562 context_group = g_all_shared_contexts.Pointer()->empty() ? |
| 578 NULL : *g_all_shared_contexts.Pointer()->begin(); | 563 NULL : *g_all_shared_contexts.Pointer()->begin(); |
| 579 | 564 |
| 580 context_ = GLInProcessContext::CreateOffscreenContext( | 565 context_ = GLInProcessContext::CreateOffscreenContext( |
| 581 parent_context, | 566 parent_context, |
| 582 gfx::Size(1, 1), | 567 gfx::Size(1, 1), |
| 583 context_group ? context_group->context_ : NULL, | 568 context_group ? context_group->context_ : NULL, |
| 584 preferred_extensions, | 569 preferred_extensions, |
| 585 attribs, | 570 attribs, |
| 586 active_url, | |
| 587 gpu_preference); | 571 gpu_preference); |
| 588 web_view_ = NULL; | |
| 589 | 572 |
| 590 if (!context_) | 573 if (!context_) |
| 591 return false; | 574 return false; |
| 592 | 575 |
| 593 gl_ = context_->GetImplementation(); | 576 gl_ = context_->GetImplementation(); |
| 594 | 577 |
| 595 if (gl_ && attributes.noExtensions) | 578 if (gl_ && attributes.noExtensions) |
| 596 gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation"); | 579 gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation"); |
| 597 | 580 |
| 598 context_->SetContextLostCallback( | 581 context_->SetContextLostCallback( |
| (...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1583 void WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost() { | 1566 void WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost() { |
| 1584 // TODO(kbr): improve the precision here. | 1567 // TODO(kbr): improve the precision here. |
| 1585 context_lost_reason_ = GL_UNKNOWN_CONTEXT_RESET_ARB; | 1568 context_lost_reason_ = GL_UNKNOWN_CONTEXT_RESET_ARB; |
| 1586 if (context_lost_callback_) { | 1569 if (context_lost_callback_) { |
| 1587 context_lost_callback_->onContextLost(); | 1570 context_lost_callback_->onContextLost(); |
| 1588 } | 1571 } |
| 1589 } | 1572 } |
| 1590 | 1573 |
| 1591 } // namespace gpu | 1574 } // namespace gpu |
| 1592 } // namespace webkit | 1575 } // namespace webkit |
| OLD | NEW |