summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--android_webview/android_webview.gyp2
-rw-r--r--android_webview/browser/aw_gl_surface.cc48
-rw-r--r--android_webview/browser/aw_gl_surface.h42
-rw-r--r--android_webview/browser/in_process_view_renderer.cc35
-rw-r--r--android_webview/browser/in_process_view_renderer.h5
-rw-r--r--android_webview/browser/scoped_app_gl_state_restore.cc2
-rw-r--r--android_webview/browser/scoped_app_gl_state_restore.h3
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.cc5
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.h3
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.cc40
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.h4
-rw-r--r--content/public/browser/android/synchronous_compositor.h7
-rw-r--r--gpu/command_buffer/client/gl_in_process_context.cc164
-rw-r--r--gpu/command_buffer/client/gl_in_process_context.h47
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.cc55
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.h16
-rw-r--r--webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc100
-rw-r--r--webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h12
18 files changed, 447 insertions, 143 deletions
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp
index c2f23a3..237712a 100644
--- a/android_webview/android_webview.gyp
+++ b/android_webview/android_webview.gyp
@@ -111,6 +111,8 @@
'browser/aw_download_manager_delegate.h',
'browser/aw_form_database_service.cc',
'browser/aw_form_database_service.h',
+ 'browser/aw_gl_surface.cc',
+ 'browser/aw_gl_surface.h',
'browser/aw_http_auth_handler_base.cc',
'browser/aw_http_auth_handler_base.h',
'browser/aw_javascript_dialog_manager.cc',
diff --git a/android_webview/browser/aw_gl_surface.cc b/android_webview/browser/aw_gl_surface.cc
new file mode 100644
index 0000000..5ff9272
--- /dev/null
+++ b/android_webview/browser/aw_gl_surface.cc
@@ -0,0 +1,48 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/browser/aw_gl_surface.h"
+
+namespace android_webview {
+
+AwGLSurface::AwGLSurface() : fbo_(0) {}
+
+AwGLSurface::~AwGLSurface() {}
+
+void AwGLSurface::Destroy() {
+}
+
+bool AwGLSurface::IsOffscreen() {
+ return false;
+}
+
+unsigned int AwGLSurface::GetBackingFrameBufferObject() {
+ return fbo_;
+}
+
+bool AwGLSurface::SwapBuffers() {
+ return true;
+}
+
+gfx::Size AwGLSurface::GetSize() {
+ return gfx::Size(1, 1);
+}
+
+void* AwGLSurface::GetHandle() {
+ return NULL;
+}
+
+void* AwGLSurface::GetDisplay() {
+ return NULL;
+}
+
+void AwGLSurface::SetBackingFrameBufferObject(unsigned int fbo) {
+ fbo_ = fbo;
+}
+
+void AwGLSurface::ResetBackingFrameBufferObject() {
+ fbo_ = 0;
+}
+
+} // namespace android_webview
diff --git a/android_webview/browser/aw_gl_surface.h b/android_webview/browser/aw_gl_surface.h
new file mode 100644
index 0000000..99b8a1d
--- /dev/null
+++ b/android_webview/browser/aw_gl_surface.h
@@ -0,0 +1,42 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_GL_SURFACE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_GL_SURFACE_H_
+
+#include "ui/gl/gl_surface.h"
+
+namespace android_webview {
+
+// This surface is used to represent the underlying surface provided by the App
+// inside a hardware draw. Note that offscreen contexts will not be using this
+// GLSurface.
+class GL_EXPORT AwGLSurface : public gfx::GLSurface {
+ public:
+ AwGLSurface();
+
+ // Implement GLSurface.
+ virtual void Destroy() OVERRIDE;
+ virtual bool IsOffscreen() OVERRIDE;
+ virtual unsigned int GetBackingFrameBufferObject() OVERRIDE;
+ virtual bool SwapBuffers() OVERRIDE;
+ virtual gfx::Size GetSize() OVERRIDE;
+ virtual void* GetHandle() OVERRIDE;
+ virtual void* GetDisplay() OVERRIDE;
+
+ void SetBackingFrameBufferObject(unsigned int fbo);
+ void ResetBackingFrameBufferObject();
+
+ protected:
+ virtual ~AwGLSurface();
+
+ private:
+ unsigned int fbo_;
+
+ DISALLOW_COPY_AND_ASSIGN(AwGLSurface);
+};
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_BROWSER_AW_GL_SURFACE_H_
diff --git a/android_webview/browser/in_process_view_renderer.cc b/android_webview/browser/in_process_view_renderer.cc
index a714956..3e25680 100644
--- a/android_webview/browser/in_process_view_renderer.cc
+++ b/android_webview/browser/in_process_view_renderer.cc
@@ -6,6 +6,7 @@
#include <android/bitmap.h>
+#include "android_webview/browser/aw_gl_surface.h"
#include "android_webview/browser/scoped_app_gl_state_restore.h"
#include "android_webview/common/aw_switches.h"
#include "android_webview/public/browser/draw_gl.h"
@@ -289,6 +290,19 @@ bool InProcessViewRenderer::OnDraw(jobject java_canvas,
return result;
}
+bool InProcessViewRenderer::InitializeHwDraw() {
+ TRACE_EVENT0("android_webview", "InitializeHwDraw");
+ DCHECK(!gl_surface_);
+ gl_surface_ = new AwGLSurface;
+ hardware_failed_ = !compositor_->InitializeHwDraw(gl_surface_);
+ hardware_initialized_ = true;
+
+ if (hardware_failed_)
+ gl_surface_ = NULL;
+
+ return !hardware_failed_;
+}
+
void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) {
TRACE_EVENT0("android_webview", "InProcessViewRenderer::DrawGL");
DCHECK(visible_);
@@ -309,13 +323,11 @@ void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) {
ScopedAllowGL allow_gl;
if (attached_to_window_ && compositor_ && !hardware_initialized_) {
- TRACE_EVENT0("android_webview", "InitializeHwDraw");
- hardware_failed_ = !compositor_->InitializeHwDraw();
- hardware_initialized_ = true;
- last_egl_context_ = current_context;
-
- if (hardware_failed_)
+ if (InitializeHwDraw()) {
+ last_egl_context_ = current_context;
+ } else {
return;
+ }
}
if (draw_info->mode == AwDrawGLInfo::kModeProcess)
@@ -330,7 +342,6 @@ void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) {
TRACE_EVENT_INSTANT0(
"android_webview", "EGLContextChanged", TRACE_EVENT_SCOPE_THREAD);
}
- last_egl_context_ = current_context;
if (!compositor_) {
TRACE_EVENT_INSTANT0(
@@ -338,21 +349,26 @@ void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) {
return;
}
+ DCHECK(gl_surface_);
+ gl_surface_->SetBackingFrameBufferObject(
+ state_restore.framebuffer_binding_ext());
+
gfx::Transform transform;
transform.matrix().setColMajorf(draw_info->transform);
transform.Translate(scroll_at_start_of_frame_.x(),
scroll_at_start_of_frame_.y());
- // TODO(joth): Check return value.
- block_invalidates_ = true;
gfx::Rect clip_rect(draw_info->clip_left,
draw_info->clip_top,
draw_info->clip_right - draw_info->clip_left,
draw_info->clip_bottom - draw_info->clip_top);
+ block_invalidates_ = true;
+ // TODO(joth): Check return value.
compositor_->DemandDrawHw(gfx::Size(draw_info->width, draw_info->height),
transform,
clip_rect,
state_restore.stencil_enabled());
block_invalidates_ = false;
+ gl_surface_->ResetBackingFrameBufferObject();
UpdateCachedGlobalVisibleRect();
bool drew_full_visible_rect = clip_rect.Contains(cached_global_visible_rect_);
@@ -554,6 +570,7 @@ void InProcessViewRenderer::OnDetachedFromWindow() {
hardware_initialized_ = false;
}
+ gl_surface_ = NULL;
attached_to_window_ = false;
}
diff --git a/android_webview/browser/in_process_view_renderer.h b/android_webview/browser/in_process_view_renderer.h
index 6e66a84..8bb2c60 100644
--- a/android_webview/browser/in_process_view_renderer.h
+++ b/android_webview/browser/in_process_view_renderer.h
@@ -23,6 +23,8 @@ class SkCanvas;
namespace android_webview {
+class AwGLSurface;
+
// Provides RenderViewHost wrapper functionality for sending WebView-specific
// IPC messages to the renderer and from there to WebKit.
class InProcessViewRenderer : public BrowserViewRenderer,
@@ -93,6 +95,8 @@ class InProcessViewRenderer : public BrowserViewRenderer,
void NoLongerExpectsDrawGL();
+ bool InitializeHwDraw();
+
// For debug tracing or logging. Return the string representation of this
// view renderer's state and the |draw_info| if provided.
std::string ToString(AwDrawGLInfo* draw_info) const;
@@ -127,6 +131,7 @@ class InProcessViewRenderer : public BrowserViewRenderer,
bool attached_to_window_;
bool hardware_initialized_;
bool hardware_failed_;
+ scoped_refptr<AwGLSurface> gl_surface_;
// Used only for detecting Android View System context changes.
// Not to be used between draw calls.
diff --git a/android_webview/browser/scoped_app_gl_state_restore.cc b/android_webview/browser/scoped_app_gl_state_restore.cc
index cb8d128..e0c8fed 100644
--- a/android_webview/browser/scoped_app_gl_state_restore.cc
+++ b/android_webview/browser/scoped_app_gl_state_restore.cc
@@ -132,6 +132,7 @@ ScopedAppGLStateRestore::ScopedAppGLStateRestore(CallMode mode) : mode_(mode) {
glGetIntegerv(GL_STENCIL_VALUE_MASK, &stencil_mask_);
glGetIntegerv(GL_STENCIL_REF, &stencil_ref_);
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &framebuffer_binding_ext_);
if (!g_gl_max_texture_units) {
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &g_gl_max_texture_units);
@@ -155,6 +156,7 @@ ScopedAppGLStateRestore::~ScopedAppGLStateRestore() {
TRACE_EVENT0("android_webview", "AppGLStateRestore");
MakeAppContextCurrent();
+ glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_binding_ext_);
glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding_);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_);
diff --git a/android_webview/browser/scoped_app_gl_state_restore.h b/android_webview/browser/scoped_app_gl_state_restore.h
index 7840fbf..93b5ad5 100644
--- a/android_webview/browser/scoped_app_gl_state_restore.h
+++ b/android_webview/browser/scoped_app_gl_state_restore.h
@@ -25,6 +25,7 @@ class ScopedAppGLStateRestore {
~ScopedAppGLStateRestore();
bool stencil_enabled() const { return stencil_test_; }
+ GLint framebuffer_binding_ext() const { return framebuffer_binding_ext_; }
private:
const CallMode mode_;
@@ -83,6 +84,8 @@ class ScopedAppGLStateRestore {
GLint stencil_mask_;
GLint stencil_ref_;
+ GLint framebuffer_binding_ext_;
+
struct TextureBindings {
GLint texture_2d;
GLint texture_cube_map;
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc
index 3c7dfe9..041511e 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_impl.cc
@@ -16,6 +16,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/renderer/android/synchronous_compositor_factory.h"
+#include "ui/gl/gl_surface.h"
#include "webkit/common/gpu/context_provider_in_process.h"
namespace content {
@@ -143,10 +144,12 @@ void SynchronousCompositorImpl::SetClient(
compositor_client_ = compositor_client;
}
-bool SynchronousCompositorImpl::InitializeHwDraw() {
+bool SynchronousCompositorImpl::InitializeHwDraw(
+ scoped_refptr<gfx::GLSurface> surface) {
DCHECK(CalledOnValidThread());
DCHECK(output_surface_);
return output_surface_->InitializeHwDraw(
+ surface,
g_factory.Get().GetOffscreenContextProviderForCompositorThread());
}
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h
index f4c932b..f0ea2c6 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_impl.h
@@ -48,7 +48,8 @@ class SynchronousCompositorImpl
// SynchronousCompositor
virtual void SetClient(SynchronousCompositorClient* compositor_client)
OVERRIDE;
- virtual bool InitializeHwDraw() OVERRIDE;
+ virtual bool InitializeHwDraw(
+ scoped_refptr<gfx::GLSurface> surface) OVERRIDE;
virtual void ReleaseHwDraw() OVERRIDE;
virtual bool DemandDrawHw(
gfx::Size view_size,
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
index fafd06f..a6115e9 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
@@ -15,30 +15,50 @@
#include "content/browser/android/in_process/synchronous_compositor_impl.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "content/public/browser/browser_thread.h"
+#include "gpu/command_buffer/client/gl_in_process_context.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkDevice.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"
-#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_surface.h"
#include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
-using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
namespace content {
namespace {
-// TODO(boliu): RenderThreadImpl should create in process contexts as well.
-scoped_ptr<WebKit::WebGraphicsContext3D> CreateWebGraphicsContext3D() {
+scoped_ptr<WebKit::WebGraphicsContext3D> CreateWebGraphicsContext3D(
+ scoped_refptr<gfx::GLSurface> surface) {
+ using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
+ if (!gfx::GLSurface::InitializeOneOff())
+ return scoped_ptr<WebKit::WebGraphicsContext3D>();
+
+ const char* allowed_extensions = "*";
+ const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
+
WebKit::WebGraphicsContext3D::Attributes attributes;
attributes.antialias = false;
attributes.shareResources = true;
attributes.noAutomaticFlushes = true;
+ gpu::GLInProcessContextAttribs in_process_attribs;
+ WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes(
+ attributes, &in_process_attribs);
+ scoped_ptr<gpu::GLInProcessContext> context(
+ gpu::GLInProcessContext::CreateWithSurface(surface,
+ attributes.shareResources,
+ allowed_extensions,
+ in_process_attribs,
+ gpu_preference));
+
+ if (!context.get())
+ return scoped_ptr<WebKit::WebGraphicsContext3D>();
+
return scoped_ptr<WebKit::WebGraphicsContext3D>(
- WebGraphicsContext3DInProcessCommandBufferImpl
- ::CreateViewContext(attributes, NULL));
+ WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext(
+ context.Pass(), attributes));
}
void DidActivatePendingTree(int routing_id) {
@@ -176,13 +196,15 @@ void AdjustTransformForClip(gfx::Transform* transform, gfx::Rect clip) {
} // namespace
bool SynchronousCompositorOutputSurface::InitializeHwDraw(
+ scoped_refptr<gfx::GLSurface> surface,
scoped_refptr<cc::ContextProvider> offscreen_context) {
DCHECK(CalledOnValidThread());
DCHECK(HasClient());
DCHECK(!context3d_);
+ DCHECK(surface);
- return InitializeAndSetContext3D(CreateWebGraphicsContext3D().Pass(),
- offscreen_context);
+ return InitializeAndSetContext3D(
+ CreateWebGraphicsContext3D(surface).Pass(), offscreen_context);
}
void SynchronousCompositorOutputSurface::ReleaseHwDraw() {
@@ -205,8 +227,6 @@ bool SynchronousCompositorOutputSurface::DemandDrawHw(
SetExternalStencilTest(stencil_enabled);
InvokeComposite(clip.size());
- // TODO(boliu): Check if context is lost here.
-
return did_swap_buffer_;
}
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.h b/content/browser/android/in_process/synchronous_compositor_output_surface.h
index a3a9066..3ab1498 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.h
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.h
@@ -61,7 +61,9 @@ class SynchronousCompositorOutputSurface
virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE;
// Partial SynchronousCompositor API implementation.
- bool InitializeHwDraw(scoped_refptr<cc::ContextProvider> offscreen_context);
+ bool InitializeHwDraw(
+ scoped_refptr<gfx::GLSurface> surface,
+ scoped_refptr<cc::ContextProvider> offscreen_context);
void ReleaseHwDraw();
bool DemandDrawHw(gfx::Size surface_size,
const gfx::Transform& transform,
diff --git a/content/public/browser/android/synchronous_compositor.h b/content/public/browser/android/synchronous_compositor.h
index 5223480..f559b973 100644
--- a/content/public/browser/android/synchronous_compositor.h
+++ b/content/public/browser/android/synchronous_compositor.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_PUBLIC_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_H_
#define CONTENT_PUBLIC_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_H_
+#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
@@ -12,6 +13,7 @@
class SkCanvas;
namespace gfx {
+class GLSurface;
class Transform;
};
@@ -40,8 +42,9 @@ class CONTENT_EXPORT SynchronousCompositor {
// Synchronously initialize compositor for hardware draw. Can only be called
// while compositor is in software only mode, either after compositor is
// first created or after ReleaseHwDraw is called. It is invalid to
- // DemandDrawHw before this returns true.
- virtual bool InitializeHwDraw() = 0;
+ // DemandDrawHw before this returns true. |surface| is the GLSurface that
+ // should be used to create the underlying hardware context.
+ virtual bool InitializeHwDraw(scoped_refptr<gfx::GLSurface> surface) = 0;
// Reverse of InitializeHwDraw above. Can only be called while hardware draw
// is already initialized. Brings compositor back to software only mode and
diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc
index 97f1715..cdbfc9f 100644
--- a/gpu/command_buffer/client/gl_in_process_context.cc
+++ b/gpu/command_buffer/client/gl_in_process_context.cc
@@ -53,16 +53,17 @@ class GLInProcessContextImpl
explicit GLInProcessContextImpl();
virtual ~GLInProcessContextImpl();
- bool Initialize(bool is_offscreen,
+ bool Initialize(scoped_refptr<gfx::GLSurface> surface,
+ bool is_offscreen,
bool share_resources,
gfx::AcceleratedWidget window,
const gfx::Size& size,
const char* allowed_extensions,
- const int32* attrib_list,
- gfx::GpuPreference gpu_preference,
- const base::Closure& context_lost_callback);
+ const GLInProcessContextAttribs& attribs,
+ gfx::GpuPreference gpu_preference);
// GLInProcessContext implementation:
+ virtual void SetContextLostCallback(const base::Closure& callback) OVERRIDE;
virtual void SignalSyncPoint(unsigned sync_point,
const base::Closure& callback) OVERRIDE;
virtual void SignalQuery(unsigned query, const base::Closure& callback)
@@ -79,7 +80,7 @@ class GLInProcessContextImpl
void Destroy();
void PollQueryCallbacks();
void CallQueryCallback(size_t index);
- void OnContextLost(const base::Closure& callback);
+ void OnContextLost();
void OnSignalSyncPoint(const base::Closure& callback);
scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_;
@@ -92,6 +93,7 @@ class GLInProcessContextImpl
unsigned int share_group_id_;
bool context_lost_;
+ base::Closure context_lost_callback_;
DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl);
};
@@ -147,9 +149,16 @@ gles2::GLES2Implementation* GLInProcessContextImpl::GetImplementation() {
return gles2_implementation_.get();
}
-void GLInProcessContextImpl::OnContextLost(const base::Closure& callback) {
+void GLInProcessContextImpl::SetContextLostCallback(
+ const base::Closure& callback) {
+ context_lost_callback_ = callback;
+}
+
+void GLInProcessContextImpl::OnContextLost() {
context_lost_ = true;
- callback.Run();
+ if (!context_lost_callback_.is_null()) {
+ context_lost_callback_.Run();
+ }
}
void GLInProcessContextImpl::OnSignalSyncPoint(const base::Closure& callback) {
@@ -159,47 +168,63 @@ void GLInProcessContextImpl::OnSignalSyncPoint(const base::Closure& callback) {
}
bool GLInProcessContextImpl::Initialize(
+ scoped_refptr<gfx::GLSurface> surface,
bool is_offscreen,
bool share_resources,
gfx::AcceleratedWidget window,
const gfx::Size& size,
const char* allowed_extensions,
- const int32* attrib_list,
- gfx::GpuPreference gpu_preference,
- const base::Closure& context_lost_callback) {
+ const GLInProcessContextAttribs& attribs,
+ gfx::GpuPreference gpu_preference) {
DCHECK(size.width() >= 0 && size.height() >= 0);
- std::vector<int32> attribs;
- while (attrib_list) {
- int32 attrib = *attrib_list++;
- switch (attrib) {
- // Known attributes
- case ALPHA_SIZE:
- case BLUE_SIZE:
- case GREEN_SIZE:
- case RED_SIZE:
- case DEPTH_SIZE:
- case STENCIL_SIZE:
- case SAMPLES:
- case SAMPLE_BUFFERS:
- attribs.push_back(attrib);
- attribs.push_back(*attrib_list++);
- break;
- case NONE:
- attribs.push_back(attrib);
- attrib_list = NULL;
- break;
- default:
- attribs.push_back(NONE);
- attrib_list = NULL;
- break;
- }
+ const int32 ALPHA_SIZE = 0x3021;
+ const int32 BLUE_SIZE = 0x3022;
+ const int32 GREEN_SIZE = 0x3023;
+ const int32 RED_SIZE = 0x3024;
+ const int32 DEPTH_SIZE = 0x3025;
+ const int32 STENCIL_SIZE = 0x3026;
+ const int32 SAMPLES = 0x3031;
+ const int32 SAMPLE_BUFFERS = 0x3032;
+ const int32 NONE = 0x3038;
+
+ std::vector<int32> attrib_vector;
+ if (attribs.alpha_size >= 0) {
+ attrib_vector.push_back(ALPHA_SIZE);
+ attrib_vector.push_back(attribs.alpha_size);
+ }
+ if (attribs.blue_size >= 0) {
+ attrib_vector.push_back(BLUE_SIZE);
+ attrib_vector.push_back(attribs.blue_size);
+ }
+ if (attribs.green_size >= 0) {
+ attrib_vector.push_back(GREEN_SIZE);
+ attrib_vector.push_back(attribs.green_size);
+ }
+ if (attribs.red_size >= 0) {
+ attrib_vector.push_back(RED_SIZE);
+ attrib_vector.push_back(attribs.red_size);
+ }
+ if (attribs.depth_size >= 0) {
+ attrib_vector.push_back(DEPTH_SIZE);
+ attrib_vector.push_back(attribs.depth_size);
+ }
+ if (attribs.stencil_size >= 0) {
+ attrib_vector.push_back(STENCIL_SIZE);
+ attrib_vector.push_back(attribs.stencil_size);
+ }
+ if (attribs.samples >= 0) {
+ attrib_vector.push_back(SAMPLES);
+ attrib_vector.push_back(attribs.samples);
+ }
+ if (attribs.sample_buffers >= 0) {
+ attrib_vector.push_back(SAMPLE_BUFFERS);
+ attrib_vector.push_back(attribs.sample_buffers);
}
+ attrib_vector.push_back(NONE);
base::Closure wrapped_callback =
- base::Bind(&GLInProcessContextImpl::OnContextLost,
- AsWeakPtr(),
- context_lost_callback);
+ base::Bind(&GLInProcessContextImpl::OnContextLost, AsWeakPtr());
command_buffer_.reset(new InProcessCommandBuffer());
scoped_ptr<base::AutoLock> scoped_shared_context_lock;
@@ -223,15 +248,16 @@ bool GLInProcessContextImpl::Initialize(
if (!share_group && !++share_group_id_)
++share_group_id_;
}
- if (!command_buffer_->Initialize(is_offscreen,
- share_resources,
- window,
- size,
- allowed_extensions,
- attribs,
- gpu_preference,
- wrapped_callback,
- share_group_id_)) {
+ if (!command_buffer_->Initialize(surface,
+ is_offscreen,
+ share_resources,
+ window,
+ size,
+ allowed_extensions,
+ attrib_vector,
+ gpu_preference,
+ wrapped_callback,
+ share_group_id_)) {
LOG(INFO) << "Failed to initialize InProcessCommmandBuffer";
return false;
}
@@ -337,6 +363,16 @@ void GLInProcessContextImpl::SignalQuery(
} // anonymous namespace
+GLInProcessContextAttribs::GLInProcessContextAttribs()
+ : alpha_size(-1),
+ blue_size(-1),
+ green_size(-1),
+ red_size(-1),
+ depth_size(-1),
+ stencil_size(-1),
+ samples(-1),
+ sample_buffers(-1) {}
+
// static
GLInProcessContext* GLInProcessContext::CreateContext(
bool is_offscreen,
@@ -344,20 +380,42 @@ GLInProcessContext* GLInProcessContext::CreateContext(
const gfx::Size& size,
bool share_resources,
const char* allowed_extensions,
- const int32* attrib_list,
- gfx::GpuPreference gpu_preference,
- const base::Closure& callback) {
+ const GLInProcessContextAttribs& attribs,
+ gfx::GpuPreference gpu_preference) {
scoped_ptr<GLInProcessContextImpl> context(
new GLInProcessContextImpl());
if (!context->Initialize(
+ NULL /* surface */,
is_offscreen,
share_resources,
window,
size,
allowed_extensions,
- attrib_list,
- gpu_preference,
- callback))
+ attribs,
+ gpu_preference))
+ return NULL;
+
+ return context.release();
+}
+
+// static
+GLInProcessContext* GLInProcessContext::CreateWithSurface(
+ scoped_refptr<gfx::GLSurface> surface,
+ bool share_resources,
+ const char* allowed_extensions,
+ const GLInProcessContextAttribs& attribs,
+ gfx::GpuPreference gpu_preference) {
+ scoped_ptr<GLInProcessContextImpl> context(
+ new GLInProcessContextImpl());
+ if (!context->Initialize(
+ surface,
+ surface->IsOffscreen(),
+ share_resources,
+ gfx::kNullAcceleratedWidget,
+ surface->GetSize(),
+ allowed_extensions,
+ attribs,
+ gpu_preference))
return NULL;
return context.release();
diff --git a/gpu/command_buffer/client/gl_in_process_context.h b/gpu/command_buffer/client/gl_in_process_context.h
index 2d0754b..09f8140 100644
--- a/gpu/command_buffer/client/gl_in_process_context.h
+++ b/gpu/command_buffer/client/gl_in_process_context.h
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "gles2_impl_export.h"
#include "ui/gfx/native_widget_types.h"
+#include "ui/gl/gl_surface.h"
#include "ui/gl/gpu_preference.h"
namespace gfx {
@@ -23,6 +24,20 @@ class GLES2Implementation;
class GpuMemoryBufferFactory;
+// The default uninitialized value is -1.
+struct GLES2_IMPL_EXPORT GLInProcessContextAttribs {
+ GLInProcessContextAttribs();
+
+ int32 alpha_size;
+ int32 blue_size;
+ int32 green_size;
+ int32 red_size;
+ int32 depth_size;
+ int32 stencil_size;
+ int32 samples;
+ int32 sample_buffers;
+};
+
class GLES2_IMPL_EXPORT GLInProcessContext {
public:
virtual ~GLInProcessContext() {}
@@ -30,20 +45,6 @@ class GLES2_IMPL_EXPORT GLInProcessContext {
// Must be called before any GLInProcessContext instances are created.
static void SetGpuMemoryBufferFactory(GpuMemoryBufferFactory* factory);
- // GLInProcessContext configuration attributes. These are the same as used by
- // EGL. Attributes are matched using a closest fit algorithm.
- enum Attribute {
- ALPHA_SIZE = 0x3021,
- BLUE_SIZE = 0x3022,
- GREEN_SIZE = 0x3023,
- RED_SIZE = 0x3024,
- DEPTH_SIZE = 0x3025,
- STENCIL_SIZE = 0x3026,
- SAMPLES = 0x3031,
- SAMPLE_BUFFERS = 0x3032,
- NONE = 0x3038 // Attrib list = terminator
- };
-
// Create a GLInProcessContext, if |is_offscreen| is true, renders to an
// offscreen context. |attrib_list| must be NULL or a NONE-terminated list
// of attribute/value pairs.
@@ -53,9 +54,21 @@ class GLES2_IMPL_EXPORT GLInProcessContext {
const gfx::Size& size,
bool share_resources,
const char* allowed_extensions,
- const int32* attrib_list,
- gfx::GpuPreference gpu_preference,
- const base::Closure& callback);
+ const GLInProcessContextAttribs& attribs,
+ gfx::GpuPreference gpu_preference);
+
+ // Create context with the provided GLSurface. All other arguments match
+ // CreateContext factory above. Can only be called if the command buffer
+ // service runs on the same thread as this client because GLSurface is not
+ // thread safe.
+ static GLInProcessContext* CreateWithSurface(
+ scoped_refptr<gfx::GLSurface> surface,
+ bool share_resources,
+ const char* allowed_extensions,
+ const GLInProcessContextAttribs& attribs,
+ gfx::GpuPreference gpu_preference);
+
+ virtual void SetContextLostCallback(const base::Closure& callback) = 0;
virtual void SignalSyncPoint(unsigned sync_point,
const base::Closure& callback) = 0;
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index 766a7e0..ccbfb32 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -20,6 +20,7 @@
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop_proxy.h"
+#include "base/sequence_checker.h"
#include "base/threading/thread.h"
#include "gpu/command_buffer/common/id_allocator.h"
#include "gpu/command_buffer/service/command_buffer_service.h"
@@ -32,7 +33,6 @@
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_image.h"
#include "ui/gl/gl_share_group.h"
-#include "ui/gl/gl_surface.h"
namespace gpu {
@@ -244,6 +244,7 @@ InProcessCommandBuffer::~InProcessCommandBuffer() {
}
bool InProcessCommandBuffer::IsContextLost() {
+ CheckSequencedThread();
if (context_lost_ || !command_buffer_) {
return true;
}
@@ -252,11 +253,13 @@ bool InProcessCommandBuffer::IsContextLost() {
}
void InProcessCommandBuffer::OnResizeView(gfx::Size size, float scale_factor) {
+ CheckSequencedThread();
DCHECK(!surface_->IsOffscreen());
surface_->Resize(size);
}
bool InProcessCommandBuffer::MakeCurrent() {
+ CheckSequencedThread();
command_buffer_lock_.AssertAcquired();
if (!context_lost_ && decoder_->MakeCurrent())
@@ -268,6 +271,7 @@ bool InProcessCommandBuffer::MakeCurrent() {
}
void InProcessCommandBuffer::PumpCommands() {
+ CheckSequencedThread();
command_buffer_lock_.AssertAcquired();
if (!MakeCurrent())
@@ -277,12 +281,14 @@ void InProcessCommandBuffer::PumpCommands() {
}
bool InProcessCommandBuffer::GetBufferChanged(int32 transfer_buffer_id) {
+ CheckSequencedThread();
command_buffer_lock_.AssertAcquired();
command_buffer_->SetGetBuffer(transfer_buffer_id);
return true;
}
bool InProcessCommandBuffer::Initialize(
+ scoped_refptr<gfx::GLSurface> surface,
bool is_offscreen,
bool share_resources,
gfx::AcceleratedWidget window,
@@ -297,8 +303,13 @@ bool InProcessCommandBuffer::Initialize(
context_lost_callback_ = WrapCallback(context_lost_callback);
share_group_id_ = share_group_id;
- base::WaitableEvent completion(true, false);
- bool result = false;
+ if (surface) {
+ // GPU thread must be the same as client thread due to GLSurface not being
+ // thread safe.
+ sequence_checker_.reset(new base::SequenceChecker);
+ surface_ = surface;
+ }
+
base::Callback<bool(void)> init_task =
base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread,
base::Unretained(this),
@@ -308,6 +319,9 @@ bool InProcessCommandBuffer::Initialize(
allowed_extensions,
attribs,
gpu_preference);
+
+ base::WaitableEvent completion(true, false);
+ bool result = false;
QueueTask(
base::Bind(&RunTaskWithResult<bool>, init_task, &result, &completion));
completion.Wait();
@@ -321,6 +335,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread(
const char* allowed_extensions,
const std::vector<int32>& attribs,
gfx::GpuPreference gpu_preference) {
+ CheckSequencedThread();
// Use one share group for all contexts.
CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group,
(new gfx::GLShareGroup));
@@ -377,10 +392,12 @@ bool InProcessCommandBuffer::InitializeOnGpuThread(
decoder_->set_engine(gpu_scheduler_.get());
- if (is_offscreen)
- surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size);
- else
- surface_ = gfx::GLSurface::CreateViewGLSurface(window);
+ if (!surface_) {
+ if (is_offscreen)
+ surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size);
+ else
+ surface_ = gfx::GLSurface::CreateViewGLSurface(window);
+ }
if (!surface_.get()) {
LOG(ERROR) << "Could not create GLSurface.";
@@ -448,6 +465,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread(
}
void InProcessCommandBuffer::Destroy() {
+ CheckSequencedThread();
base::WaitableEvent completion(true, false);
bool result = false;
base::Callback<bool(void)> destroy_task = base::Bind(
@@ -458,6 +476,7 @@ void InProcessCommandBuffer::Destroy() {
}
bool InProcessCommandBuffer::DestroyOnGpuThread() {
+ CheckSequencedThread();
command_buffer_.reset();
// Clean up GL resources if possible.
bool have_context = context_ && context_->MakeCurrent(surface_);
@@ -472,9 +491,15 @@ bool InProcessCommandBuffer::DestroyOnGpuThread() {
return true;
}
+void InProcessCommandBuffer::CheckSequencedThread() {
+ DCHECK(!sequence_checker_ ||
+ sequence_checker_->CalledOnValidSequencedThread());
+}
+
unsigned int InProcessCommandBuffer::CreateImageForGpuMemoryBuffer(
gfx::GpuMemoryBufferHandle buffer,
gfx::Size size) {
+ CheckSequencedThread();
unsigned int image_id;
{
// TODO: ID allocation should go through CommandBuffer
@@ -494,12 +519,14 @@ void InProcessCommandBuffer::CreateImageOnGpuThread(
gfx::GpuMemoryBufferHandle buffer,
gfx::Size size,
unsigned int image_id) {
+ CheckSequencedThread();
scoped_refptr<gfx::GLImage> gl_image =
gfx::GLImage::CreateGLImageForGpuMemoryBuffer(buffer, size);
decoder_->GetContextGroup()->image_manager()->AddImage(gl_image, image_id);
}
void InProcessCommandBuffer::RemoveImage(unsigned int image_id) {
+ CheckSequencedThread();
{
// TODO: ID allocation should go through CommandBuffer
base::AutoLock lock(command_buffer_lock_);
@@ -514,10 +541,12 @@ void InProcessCommandBuffer::RemoveImage(unsigned int image_id) {
}
void InProcessCommandBuffer::RemoveImageOnGpuThread(unsigned int image_id) {
+ CheckSequencedThread();
decoder_->GetContextGroup()->image_manager()->RemoveImage(image_id);
}
void InProcessCommandBuffer::OnContextLost() {
+ CheckSequencedThread();
if (!context_lost_callback_.is_null()) {
context_lost_callback_.Run();
context_lost_callback_.Reset();
@@ -535,6 +564,7 @@ void InProcessCommandBuffer::OnContextLost() {
}
CommandBuffer::State InProcessCommandBuffer::GetStateFast() {
+ CheckSequencedThread();
base::AutoLock lock(state_after_last_flush_lock_);
if (state_after_last_flush_.generation - last_state_.generation < 0x80000000U)
last_state_ = state_after_last_flush_;
@@ -542,19 +572,23 @@ CommandBuffer::State InProcessCommandBuffer::GetStateFast() {
}
CommandBuffer::State InProcessCommandBuffer::GetState() {
+ CheckSequencedThread();
return GetStateFast();
}
CommandBuffer::State InProcessCommandBuffer::GetLastState() {
+ CheckSequencedThread();
return last_state_;
}
int32 InProcessCommandBuffer::GetLastToken() {
+ CheckSequencedThread();
GetStateFast();
return last_state_.token;
}
void InProcessCommandBuffer::FlushOnGpuThread(int32 put_offset) {
+ CheckSequencedThread();
ScopedEvent handle_flush(&flush_event_);
base::AutoLock lock(command_buffer_lock_);
command_buffer_->Flush(put_offset);
@@ -568,6 +602,7 @@ void InProcessCommandBuffer::FlushOnGpuThread(int32 put_offset) {
}
void InProcessCommandBuffer::Flush(int32 put_offset) {
+ CheckSequencedThread();
if (last_state_.error != gpu::error::kNoError)
return;
@@ -583,6 +618,7 @@ void InProcessCommandBuffer::Flush(int32 put_offset) {
CommandBuffer::State InProcessCommandBuffer::FlushSync(int32 put_offset,
int32 last_known_get) {
+ CheckSequencedThread();
if (put_offset == last_known_get || last_state_.error != gpu::error::kNoError)
return last_state_;
@@ -598,6 +634,7 @@ CommandBuffer::State InProcessCommandBuffer::FlushSync(int32 put_offset,
}
void InProcessCommandBuffer::SetGetBuffer(int32 shm_id) {
+ CheckSequencedThread();
if (last_state_.error != gpu::error::kNoError)
return;
@@ -614,11 +651,13 @@ void InProcessCommandBuffer::SetGetBuffer(int32 shm_id) {
gpu::Buffer InProcessCommandBuffer::CreateTransferBuffer(size_t size,
int32* id) {
+ CheckSequencedThread();
base::AutoLock lock(command_buffer_lock_);
return command_buffer_->CreateTransferBuffer(size, id);
}
void InProcessCommandBuffer::DestroyTransferBuffer(int32 id) {
+ CheckSequencedThread();
base::Closure task = base::Bind(&CommandBuffer::DestroyTransferBuffer,
base::Unretained(command_buffer_.get()),
id);
@@ -637,10 +676,12 @@ uint32 InProcessCommandBuffer::InsertSyncPoint() {
}
void InProcessCommandBuffer::SignalSyncPoint(unsigned sync_point,
const base::Closure& callback) {
+ CheckSequencedThread();
QueueTask(WrapCallback(callback));
}
gpu::error::Error InProcessCommandBuffer::GetLastError() {
+ CheckSequencedThread();
return last_state_.error;
}
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h
index d2e103a..9bdbd49 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.h
+++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -17,8 +17,13 @@
#include "gpu/gpu_export.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/native_widget_types.h"
+#include "ui/gl/gl_surface.h"
#include "ui/gl/gpu_preference.h"
+namespace base {
+class SequenceChecker;
+}
+
namespace gfx {
class GLContext;
class GLImage;
@@ -57,7 +62,11 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer {
static void EnableVirtualizedContext();
- bool Initialize(bool is_offscreen,
+ // If |surface| is not NULL, use it directly; in this case, the command
+ // buffer gpu thread must be the same as the client thread. Otherwise create
+ // a new GLSurface.
+ bool Initialize(scoped_refptr<gfx::GLSurface> surface,
+ bool is_offscreen,
bool share_resources,
gfx::AcceleratedWidget window,
const gfx::Size& size,
@@ -118,6 +127,7 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer {
base::Closure WrapCallback(const base::Closure& callback);
State GetStateFast();
void QueueTask(const base::Closure& task) { queue_->QueueTask(task); }
+ void CheckSequencedThread();
// Callbacks:
void OnContextLost();
@@ -149,6 +159,10 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer {
State state_after_last_flush_;
base::Lock state_after_last_flush_lock_;
+ // Only used with explicit scheduling and the gpu thread is the same as
+ // the client thread.
+ scoped_ptr<base::SequenceChecker> sequence_checker_;
+
DISALLOW_COPY_AND_ASSIGN(InProcessCommandBuffer);
};
diff --git a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
index 57767ec..886e40f 100644
--- a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
+++ b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
@@ -73,7 +73,7 @@ WebGraphicsContext3DInProcessCommandBufferImpl::CreateViewContext(
scoped_ptr<WebKit::WebGraphicsContext3D> context;
if (gfx::GLSurface::InitializeOneOff()) {
context.reset(new WebGraphicsContext3DInProcessCommandBufferImpl(
- attributes, false, window));
+ scoped_ptr< ::gpu::GLInProcessContext>(), attributes, false, window));
}
return context.Pass();
}
@@ -83,12 +83,29 @@ scoped_ptr<WebKit::WebGraphicsContext3D>
WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext(
const WebKit::WebGraphicsContext3D::Attributes& attributes) {
return make_scoped_ptr(new WebGraphicsContext3DInProcessCommandBufferImpl(
- attributes, true, gfx::kNullAcceleratedWidget))
+ scoped_ptr< ::gpu::GLInProcessContext>(),
+ attributes,
+ true,
+ gfx::kNullAcceleratedWidget))
+ .PassAs<WebKit::WebGraphicsContext3D>();
+}
+
+scoped_ptr<WebKit::WebGraphicsContext3D>
+WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext(
+ scoped_ptr< ::gpu::GLInProcessContext> context,
+ const WebKit::WebGraphicsContext3D::Attributes& attributes) {
+ return make_scoped_ptr(
+ new WebGraphicsContext3DInProcessCommandBufferImpl(
+ context.Pass(),
+ attributes,
+ true /* is_offscreen. Not used. */,
+ gfx::kNullAcceleratedWidget /* window. Not used. */))
.PassAs<WebKit::WebGraphicsContext3D>();
}
WebGraphicsContext3DInProcessCommandBufferImpl::
WebGraphicsContext3DInProcessCommandBufferImpl(
+ scoped_ptr< ::gpu::GLInProcessContext> context,
const WebKit::WebGraphicsContext3D::Attributes& attributes,
bool is_offscreen,
gfx::AcceleratedWidget window)
@@ -96,6 +113,7 @@ WebGraphicsContext3DInProcessCommandBufferImpl::
window_(window),
initialized_(false),
initialize_failed_(false),
+ context_(context.Pass()),
gl_(NULL),
context_lost_callback_(NULL),
context_lost_reason_(GL_NO_ERROR),
@@ -108,6 +126,17 @@ WebGraphicsContext3DInProcessCommandBufferImpl::
~WebGraphicsContext3DInProcessCommandBufferImpl() {
}
+// static
+void WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes(
+ const WebKit::WebGraphicsContext3D::Attributes& attributes,
+ ::gpu::GLInProcessContextAttribs* output_attribs) {
+ output_attribs->alpha_size = attributes.alpha ? 8 : 0;
+ output_attribs->depth_size = attributes.depth ? 24 : 0;
+ output_attribs->stencil_size = attributes.stencil ? 8 : 0;
+ output_attribs->samples = attributes.antialias ? 4 : 0;
+ output_attribs->sample_buffers = attributes.antialias ? 1 : 0;
+}
+
bool WebGraphicsContext3DInProcessCommandBufferImpl::MaybeInitializeGL() {
if (initialized_)
return true;
@@ -118,46 +147,35 @@ bool WebGraphicsContext3DInProcessCommandBufferImpl::MaybeInitializeGL() {
// Ensure the gles2 library is initialized first in a thread safe way.
g_gles2_initializer.Get();
- // Convert WebGL context creation attributes into GLInProcessContext / EGL
- // size requests.
- const int alpha_size = attributes_.alpha ? 8 : 0;
- const int depth_size = attributes_.depth ? 24 : 0;
- const int stencil_size = attributes_.stencil ? 8 : 0;
- const int samples = attributes_.antialias ? 4 : 0;
- const int sample_buffers = attributes_.antialias ? 1 : 0;
- const int32 attribs[] = {
- GLInProcessContext::ALPHA_SIZE, alpha_size,
- GLInProcessContext::DEPTH_SIZE, depth_size,
- GLInProcessContext::STENCIL_SIZE, stencil_size,
- GLInProcessContext::SAMPLES, samples,
- GLInProcessContext::SAMPLE_BUFFERS, sample_buffers,
- GLInProcessContext::NONE,
- };
-
- const char* preferred_extensions = "*";
-
- // TODO(kbr): More work will be needed in this implementation to
- // properly support GPU switching. Like in the out-of-process
- // command buffer implementation, all previously created contexts
- // will need to be lost either when the first context requesting the
- // discrete GPU is created, or the last one is destroyed.
- gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
-
- base::Closure context_lost_callback =
- base::Bind(&WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost,
- base::Unretained(this));
-
- context_.reset(GLInProcessContext::CreateContext(
- is_offscreen_,
- window_,
- gfx::Size(1, 1),
- attributes_.shareResources,
- preferred_extensions,
- attribs,
- gpu_preference,
- context_lost_callback));
-
if (!context_) {
+ const char* preferred_extensions = "*";
+
+ // TODO(kbr): More work will be needed in this implementation to
+ // properly support GPU switching. Like in the out-of-process
+ // command buffer implementation, all previously created contexts
+ // will need to be lost either when the first context requesting the
+ // discrete GPU is created, or the last one is destroyed.
+ gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
+
+ ::gpu::GLInProcessContextAttribs attrib_struct;
+ ConvertAttributes(attributes_, &attrib_struct),
+
+ context_.reset(GLInProcessContext::CreateContext(
+ is_offscreen_,
+ window_,
+ gfx::Size(1, 1),
+ attributes_.shareResources,
+ preferred_extensions,
+ attrib_struct,
+ gpu_preference));
+ }
+
+ if (context_) {
+ base::Closure context_lost_callback = base::Bind(
+ &WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost,
+ base::Unretained(this));
+ context_->SetContextLostCallback(context_lost_callback);
+ } else {
initialize_failed_ = true;
return false;
}
diff --git a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
index 9ef3698..d3620b4 100644
--- a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
+++ b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
@@ -39,6 +39,7 @@ using WebKit::WGC3Dsizeiptr;
namespace gpu {
class GLInProcessContext;
+struct GLInProcessContextAttribs;
}
namespace webkit {
@@ -54,8 +55,18 @@ class WEBKIT_GPU_EXPORT WebGraphicsContext3DInProcessCommandBufferImpl
static scoped_ptr<WebKit::WebGraphicsContext3D> CreateOffscreenContext(
const WebKit::WebGraphicsContext3D::Attributes& attributes);
+ static scoped_ptr<WebKit::WebGraphicsContext3D> WrapContext(
+ scoped_ptr< ::gpu::GLInProcessContext> context,
+ const WebKit::WebGraphicsContext3D::Attributes& attributes);
+
virtual ~WebGraphicsContext3DInProcessCommandBufferImpl();
+ // Convert WebGL context creation attributes into GLInProcessContext / EGL
+ // size requests.
+ static void ConvertAttributes(
+ const WebKit::WebGraphicsContext3D::Attributes& attributes,
+ ::gpu::GLInProcessContextAttribs* output_attribs);
+
//----------------------------------------------------------------------
// WebGraphicsContext3D methods
virtual bool makeContextCurrent();
@@ -536,6 +547,7 @@ class WEBKIT_GPU_EXPORT WebGraphicsContext3DInProcessCommandBufferImpl
private:
WebGraphicsContext3DInProcessCommandBufferImpl(
+ scoped_ptr< ::gpu::GLInProcessContext> context,
const WebKit::WebGraphicsContext3D::Attributes& attributes,
bool is_offscreen,
gfx::AcceleratedWidget window);