| Index: content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc
|
| diff --git a/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc b/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc
|
| index fb4cdb352914feaf3ebc39189e7608d886cc2b86..c61a79afd21aa6534c9d785fa9b503ad3efbe93d 100644
|
| --- a/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc
|
| +++ b/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc
|
| @@ -21,6 +21,7 @@
|
| #include "base/debug/trace_event.h"
|
| #include "base/logging.h"
|
| #include "base/metrics/histogram.h"
|
| +#include "base/synchronization/lock.h"
|
| #include "content/common/content_switches.h"
|
| #include "content/renderer/gpu/gpu_channel_host.h"
|
| #include "content/renderer/render_thread.h"
|
| @@ -32,11 +33,14 @@
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
|
| #include "webkit/glue/gl_bindings_skia_cmd_buffer.h"
|
|
|
| +static base::LazyInstance<base::Lock>
|
| + g_all_shared_contexts_lock(base::LINKER_INITIALIZED);
|
| static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> >
|
| g_all_shared_contexts(base::LINKER_INITIALIZED);
|
|
|
| WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl()
|
| - : context_(NULL),
|
| + : initialize_failed_(false),
|
| + context_(NULL),
|
| gl_(NULL),
|
| #ifndef WTF_USE_THREADED_COMPOSITING
|
| web_view_(NULL),
|
| @@ -55,7 +59,10 @@ WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl()
|
|
|
| WebGraphicsContext3DCommandBufferImpl::
|
| ~WebGraphicsContext3DCommandBufferImpl() {
|
| - g_all_shared_contexts.Pointer()->erase(this);
|
| + {
|
| + base::AutoLock lock(g_all_shared_contexts_lock.Get());
|
| + g_all_shared_contexts.Pointer()->erase(this);
|
| + }
|
| delete context_;
|
| }
|
|
|
| @@ -71,39 +78,19 @@ bool WebGraphicsContext3DCommandBufferImpl::initialize(
|
| WebGraphicsContext3D::Attributes attributes,
|
| WebKit::WebView* web_view,
|
| bool render_directly_to_web_view) {
|
| + DCHECK(!context_);
|
| TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize");
|
| RenderThread* render_thread = RenderThread::current();
|
| if (!render_thread)
|
| return false;
|
| - GpuChannelHost* host = render_thread->EstablishGpuChannelSync(
|
| + host_ = render_thread->EstablishGpuChannelSync(
|
| content::
|
| CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE);
|
| - if (!host)
|
| + if (!host_)
|
| return false;
|
| - DCHECK(host->state() == GpuChannelHost::kConnected);
|
| -
|
| - // Convert WebGL context creation attributes into RendererGLContext / 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[] = {
|
| - RendererGLContext::ALPHA_SIZE, alpha_size,
|
| - RendererGLContext::DEPTH_SIZE, depth_size,
|
| - RendererGLContext::STENCIL_SIZE, stencil_size,
|
| - RendererGLContext::SAMPLES, samples,
|
| - RendererGLContext::SAMPLE_BUFFERS, sample_buffers,
|
| - RendererGLContext::SHARE_RESOURCES, attributes.shareResources ? 1 : 0,
|
| - RendererGLContext::BIND_GENERATES_RESOURCES, 0,
|
| - RendererGLContext::NONE,
|
| - };
|
| -
|
| - const char* preferred_extensions = attributes.noExtensions ?
|
| - kWebGLPreferredGLExtensions : "*";
|
| + DCHECK(host_->state() == GpuChannelHost::kConnected);
|
|
|
| - const GPUInfo& gpu_info = host->gpu_info();
|
| + const GPUInfo& gpu_info = host_->gpu_info();
|
| UMA_HISTOGRAM_ENUMERATION(
|
| "GPU.WebGraphicsContext3D_Init_CanLoseContext",
|
| attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context,
|
| @@ -113,43 +100,82 @@ bool WebGraphicsContext3DCommandBufferImpl::initialize(
|
| return false;
|
| }
|
|
|
| - GURL active_url;
|
| if (web_view && web_view->mainFrame())
|
| - active_url = GURL(web_view->mainFrame()->document().url());
|
| -
|
| - RendererGLContext* share_group = NULL;
|
| - if (attributes.shareResources) {
|
| - share_group = g_all_shared_contexts.Pointer()->empty() ?
|
| - NULL : (*g_all_shared_contexts.Pointer()->begin())->context_;
|
| - }
|
| + active_url_ = GURL(web_view->mainFrame()->document().url());
|
|
|
| + attributes_ = attributes;
|
| render_directly_to_web_view_ = render_directly_to_web_view;
|
| - if (render_directly_to_web_view) {
|
| -#ifndef WTF_USE_THREADED_COMPOSITING
|
| - RenderView* renderview = RenderView::FromWebView(web_view);
|
| - if (!renderview)
|
| + if (render_directly_to_web_view_) {
|
| + RenderView* render_view = RenderView::FromWebView(web_view);
|
| + if (!render_view)
|
| return false;
|
| - web_view_ = web_view;
|
| -#endif
|
| - context_ = RendererGLContext::CreateViewContext(
|
| - host,
|
| - renderview->routing_id(),
|
| - share_group,
|
| - preferred_extensions,
|
| - attribs,
|
| - active_url);
|
| - } else {
|
| - context_ = RendererGLContext::CreateOffscreenContext(
|
| - host,
|
| - gfx::Size(1, 1),
|
| - share_group,
|
| - preferred_extensions,
|
| - attribs,
|
| - active_url);
|
| + render_view_routing_id_ = render_view->routing_id();
|
| #ifndef WTF_USE_THREADED_COMPOSITING
|
| - web_view_ = NULL;
|
| + web_view_ = web_view;
|
| #endif
|
| }
|
| + return true;
|
| +}
|
| +
|
| +bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() {
|
| + if (context_)
|
| + return true;
|
| + if (initialize_failed_)
|
| + return false;
|
| +
|
| + TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL");
|
| +
|
| + // Convert WebGL context creation attributes into RendererGLContext / 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[] = {
|
| + RendererGLContext::ALPHA_SIZE, alpha_size,
|
| + RendererGLContext::DEPTH_SIZE, depth_size,
|
| + RendererGLContext::STENCIL_SIZE, stencil_size,
|
| + RendererGLContext::SAMPLES, samples,
|
| + RendererGLContext::SAMPLE_BUFFERS, sample_buffers,
|
| + RendererGLContext::SHARE_RESOURCES, attributes_.shareResources ? 1 : 0,
|
| + RendererGLContext::BIND_GENERATES_RESOURCES, 0,
|
| + RendererGLContext::NONE,
|
| + };
|
| +
|
| + const char* preferred_extensions = attributes_.noExtensions ?
|
| + kWebGLPreferredGLExtensions : "*";
|
| +
|
| + // We need to lock g_all_shared_contexts until after RendererGLContext::Create
|
| + // to ensure that the context we picked for our share group isn't deleted.
|
| + // (There's also a lock in our destructor.)
|
| + {
|
| + base::AutoLock lock(g_all_shared_contexts_lock.Get());
|
| + RendererGLContext* share_group = NULL;
|
| + if (attributes_.shareResources) {
|
| + share_group = g_all_shared_contexts.Pointer()->empty() ?
|
| + NULL : (*g_all_shared_contexts.Pointer()->begin())->context_;
|
| + }
|
| +
|
| + if (render_directly_to_web_view_) {
|
| + context_ = RendererGLContext::CreateViewContext(
|
| + host_,
|
| + render_view_routing_id_,
|
| + share_group,
|
| + preferred_extensions,
|
| + attribs,
|
| + active_url_);
|
| + } else {
|
| + context_ = RendererGLContext::CreateOffscreenContext(
|
| + host_,
|
| + gfx::Size(1, 1),
|
| + share_group,
|
| + preferred_extensions,
|
| + attribs,
|
| + active_url_);
|
| + }
|
| + }
|
| +
|
| if (!context_)
|
| return false;
|
|
|
| @@ -166,7 +192,6 @@ bool WebGraphicsContext3DCommandBufferImpl::initialize(
|
|
|
| // Set attributes_ from created offscreen context.
|
| {
|
| - attributes_ = attributes;
|
| GLint alpha_bits = 0;
|
| getIntegerv(GL_ALPHA_BITS, &alpha_bits);
|
| attributes_.alpha = alpha_bits > 0;
|
| @@ -181,13 +206,17 @@ bool WebGraphicsContext3DCommandBufferImpl::initialize(
|
| attributes_.antialias = samples > 0;
|
| }
|
|
|
| - if (attributes.shareResources)
|
| + if (attributes_.shareResources) {
|
| + base::AutoLock lock(g_all_shared_contexts_lock.Get());
|
| g_all_shared_contexts.Pointer()->insert(this);
|
| + }
|
|
|
| return true;
|
| }
|
|
|
| bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() {
|
| + if (!MaybeInitializeGL())
|
| + return false;
|
| return RendererGLContext::MakeCurrent(context_);
|
| }
|
|
|
| @@ -212,7 +241,6 @@ bool WebGraphicsContext3DCommandBufferImpl::setParentContext(
|
| }
|
|
|
| WebGLId WebGraphicsContext3DCommandBufferImpl::getPlatformTextureId() {
|
| - DCHECK(context_);
|
| return context_->GetParentTextureId();
|
| }
|
|
|
| @@ -666,7 +694,8 @@ WGC3Denum WebGraphicsContext3DCommandBufferImpl::getError() {
|
| }
|
|
|
| bool WebGraphicsContext3DCommandBufferImpl::isContextLost() {
|
| - return context_->IsCommandBufferContextLost() ||
|
| + return initialize_failed_ ||
|
| + (context_ && context_->IsCommandBufferContextLost()) ||
|
| context_lost_reason_ != GL_NO_ERROR;
|
| }
|
|
|
|
|