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