15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GL_GLEXT_PROTOTYPES 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GL_GLEXT_PROTOTYPES 1 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2ext.h> 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <GLES2/gl2extchromium.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/atomicops.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_implementation.h" 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h" 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/gfx/size.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gl/gl_implementation.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using gpu::gles2::GLES2Implementation; 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing gpu::GLInProcessContext; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace webkit { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebGraphicsContext3DInProcessCommandBufferImpl::CreateViewContext( 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebGraphicsContext3D::Attributes& attributes, 37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool lose_context_when_out_of_memory, 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::AcceleratedWidget window) { 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(gfx::GetGLImplementation(), gfx::kGLImplementationNone); 40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool is_offscreen = false; 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return make_scoped_ptr(new WebGraphicsContext3DInProcessCommandBufferImpl( 42e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch scoped_ptr< ::gpu::GLInProcessContext>(), 43e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch attributes, 44e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch lose_context_when_out_of_memory, 45e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_offscreen, 46e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch window)); 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext( 52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const blink::WebGraphicsContext3D::Attributes& attributes, 53e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool lose_context_when_out_of_memory) { 54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool is_offscreen = true; 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return make_scoped_ptr(new WebGraphicsContext3DInProcessCommandBufferImpl( 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr< ::gpu::GLInProcessContext>(), 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) attributes, 58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch lose_context_when_out_of_memory, 59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_offscreen, 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::kNullAcceleratedWidget)); 61bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 62bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> 64bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochWebGraphicsContext3DInProcessCommandBufferImpl::WrapContext( 65bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_ptr< ::gpu::GLInProcessContext> context, 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebGraphicsContext3D::Attributes& attributes) { 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool lose_context_when_out_of_memory = false; // Not used. 68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool is_offscreen = true; // Not used. 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return make_scoped_ptr(new WebGraphicsContext3DInProcessCommandBufferImpl( 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) context.Pass(), 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) attributes, 72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch lose_context_when_out_of_memory, 73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_offscreen, 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::kNullAcceleratedWidget /* window. Not used. */)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebGraphicsContext3DInProcessCommandBufferImpl:: 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebGraphicsContext3DInProcessCommandBufferImpl( 79bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_ptr< ::gpu::GLInProcessContext> context, 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebGraphicsContext3D::Attributes& attributes, 81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool lose_context_when_out_of_memory, 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_offscreen, 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::AcceleratedWidget window) 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : share_resources_(attributes.shareResources), 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) webgl_context_(attributes.webGL), 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_offscreen_(is_offscreen), 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_(window), 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) context_(context.Pass()) { 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ConvertAttributes(attributes, &attribs_); 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) attribs_.lose_context_when_out_of_memory = lose_context_when_out_of_memory; 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebGraphicsContext3DInProcessCommandBufferImpl:: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~WebGraphicsContext3DInProcessCommandBufferImpl() { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)size_t WebGraphicsContext3DInProcessCommandBufferImpl::GetMappedMemoryLimit() { 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return context_->GetMappedMemoryLimit(); 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool WebGraphicsContext3DInProcessCommandBufferImpl::MaybeInitializeGL() { 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (initialized_) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (initialize_failed_) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!context_) { 109bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // TODO(kbr): More work will be needed in this implementation to 110bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // properly support GPU switching. Like in the out-of-process 111bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // command buffer implementation, all previously created contexts 112bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // will need to be lost either when the first context requesting the 113bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // discrete GPU is created, or the last one is destroyed. 114bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; 11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) context_.reset(GLInProcessContext::Create( 11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NULL, /* service */ 11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NULL, /* surface */ 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) is_offscreen_, 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) window_, 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::Size(1, 1), 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NULL, /* share_context */ 12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) share_resources_, 12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) attribs_, 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gpu_preference, 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ::gpu::GLInProcessContextSharedMemoryLimits())); 126bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 127bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 128bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (context_) { 129bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::Closure context_lost_callback = base::Bind( 130bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch &WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost, 131bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::Unretained(this)); 132bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch context_->SetContextLostCallback(context_lost_callback); 133bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } else { 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) initialize_failed_ = true; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) real_gl_ = context_->GetImplementation(); 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) setGLInterface(real_gl_); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (real_gl_ && webgl_context_) 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) real_gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation"); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) initialized_ = true; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebGraphicsContext3DInProcessCommandBufferImpl::InitializeOnCurrentThread() { 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!MaybeInitializeGL()) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return context_ && !isContextLost(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebGraphicsContext3DInProcessCommandBufferImpl::isContextLost() { 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return context_lost_reason_ != GL_NO_ERROR; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WGC3Denum WebGraphicsContext3DInProcessCommandBufferImpl:: 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getGraphicsResetStatusARB() { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context_lost_reason_; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)::gpu::ContextSupport* 1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)WebGraphicsContext3DInProcessCommandBufferImpl::GetContextSupport() { 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return real_gl_; 1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost() { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kbr): improve the precision here. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_lost_reason_ = GL_UNKNOWN_CONTEXT_RESET_ARB; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (context_lost_callback_) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_lost_callback_->onContextLost(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gpu 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace webkit 179