Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(305)

Side by Side Diff: content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc

Issue 7860028: Retry 3 to split WebGraphicsContext3DCommandBufferImpl::initialize() into two stages. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fold thread fixes into this patch. Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #if defined(ENABLE_GPU) 5 #if defined(ENABLE_GPU)
6 6
7 #include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h" 7 #include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h"
8 8
9 #include "gpu/GLES2/gl2.h" 9 #include "gpu/GLES2/gl2.h"
10 #ifndef GL_GLEXT_PROTOTYPES 10 #ifndef GL_GLEXT_PROTOTYPES
11 #define GL_GLEXT_PROTOTYPES 1 11 #define GL_GLEXT_PROTOTYPES 1
12 #endif 12 #endif
13 #include "gpu/GLES2/gl2ext.h" 13 #include "gpu/GLES2/gl2ext.h"
14 14
15 #include <algorithm> 15 #include <algorithm>
16 #include <set> 16 #include <set>
17 17
18 #include "base/lazy_instance.h" 18 #include "base/lazy_instance.h"
19 #include "base/string_tokenizer.h" 19 #include "base/string_tokenizer.h"
20 #include "base/command_line.h" 20 #include "base/command_line.h"
21 #include "base/debug/trace_event.h" 21 #include "base/debug/trace_event.h"
22 #include "base/logging.h" 22 #include "base/logging.h"
23 #include "base/metrics/histogram.h" 23 #include "base/metrics/histogram.h"
24 #include "base/synchronization/lock.h"
24 #include "content/common/content_switches.h" 25 #include "content/common/content_switches.h"
25 #include "content/renderer/gpu/gpu_channel_host.h" 26 #include "content/renderer/gpu/gpu_channel_host.h"
26 #include "content/renderer/render_thread.h" 27 #include "content/renderer/render_thread.h"
27 #include "content/renderer/render_view.h" 28 #include "content/renderer/render_view.h"
28 #include "gpu/command_buffer/client/gles2_implementation.h" 29 #include "gpu/command_buffer/client/gles2_implementation.h"
29 #include "gpu/command_buffer/common/constants.h" 30 #include "gpu/command_buffer/common/constants.h"
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
33 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h" 34 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h"
34 35
36 static base::LazyInstance<base::Lock>
37 g_all_shared_contexts_lock(base::LINKER_INITIALIZED);
35 static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> > 38 static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> >
36 g_all_shared_contexts(base::LINKER_INITIALIZED); 39 g_all_shared_contexts(base::LINKER_INITIALIZED);
37 40
38 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl() 41 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl()
39 : context_(NULL), 42 : initialize_failed_(false),
43 context_(NULL),
40 gl_(NULL), 44 gl_(NULL),
41 #ifndef WTF_USE_THREADED_COMPOSITING 45 #ifndef WTF_USE_THREADED_COMPOSITING
42 web_view_(NULL), 46 web_view_(NULL),
43 #endif 47 #endif
44 #if defined(OS_MACOSX) 48 #if defined(OS_MACOSX)
45 plugin_handle_(NULL), 49 plugin_handle_(NULL),
46 #endif // defined(OS_MACOSX) 50 #endif // defined(OS_MACOSX)
47 context_lost_callback_(0), 51 context_lost_callback_(0),
48 context_lost_reason_(GL_NO_ERROR), 52 context_lost_reason_(GL_NO_ERROR),
49 swapbuffers_complete_callback_(0), 53 swapbuffers_complete_callback_(0),
50 cached_width_(0), 54 cached_width_(0),
51 cached_height_(0), 55 cached_height_(0),
52 bound_fbo_(0), 56 bound_fbo_(0),
53 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 57 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
54 } 58 }
55 59
56 WebGraphicsContext3DCommandBufferImpl:: 60 WebGraphicsContext3DCommandBufferImpl::
57 ~WebGraphicsContext3DCommandBufferImpl() { 61 ~WebGraphicsContext3DCommandBufferImpl() {
58 g_all_shared_contexts.Pointer()->erase(this); 62 {
63 base::AutoLock lock(g_all_shared_contexts_lock.Get());
64 g_all_shared_contexts.Pointer()->erase(this);
65 }
59 delete context_; 66 delete context_;
60 } 67 }
61 68
62 // This string should only be passed for WebGL contexts. Nothing ELSE!!! 69 // This string should only be passed for WebGL contexts. Nothing ELSE!!!
63 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of 70 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of
64 // a context should not pass this string. 71 // a context should not pass this string.
65 static const char* kWebGLPreferredGLExtensions = 72 static const char* kWebGLPreferredGLExtensions =
66 "GL_OES_packed_depth_stencil " 73 "GL_OES_packed_depth_stencil "
67 "GL_OES_depth24 " 74 "GL_OES_depth24 "
68 "GL_CHROMIUM_webglsl"; 75 "GL_CHROMIUM_webglsl";
69 76
70 bool WebGraphicsContext3DCommandBufferImpl::initialize( 77 bool WebGraphicsContext3DCommandBufferImpl::initialize(
71 WebGraphicsContext3D::Attributes attributes, 78 WebGraphicsContext3D::Attributes attributes,
72 WebKit::WebView* web_view, 79 WebKit::WebView* web_view,
73 bool render_directly_to_web_view) { 80 bool render_directly_to_web_view) {
81 DCHECK(!context_);
74 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize"); 82 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize");
75 RenderThread* render_thread = RenderThread::current(); 83 RenderThread* render_thread = RenderThread::current();
76 if (!render_thread) 84 if (!render_thread)
77 return false; 85 return false;
78 GpuChannelHost* host = render_thread->EstablishGpuChannelSync( 86 host_ = render_thread->EstablishGpuChannelSync(
79 content:: 87 content::
80 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE); 88 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE);
81 if (!host) 89 if (!host_)
82 return false; 90 return false;
83 DCHECK(host->state() == GpuChannelHost::kConnected); 91 DCHECK(host_->state() == GpuChannelHost::kConnected);
84 92
85 // Convert WebGL context creation attributes into RendererGLContext / EGL size 93 const GPUInfo& gpu_info = host_->gpu_info();
86 // requests.
87 const int alpha_size = attributes.alpha ? 8 : 0;
88 const int depth_size = attributes.depth ? 24 : 0;
89 const int stencil_size = attributes.stencil ? 8 : 0;
90 const int samples = attributes.antialias ? 4 : 0;
91 const int sample_buffers = attributes.antialias ? 1 : 0;
92 const int32 attribs[] = {
93 RendererGLContext::ALPHA_SIZE, alpha_size,
94 RendererGLContext::DEPTH_SIZE, depth_size,
95 RendererGLContext::STENCIL_SIZE, stencil_size,
96 RendererGLContext::SAMPLES, samples,
97 RendererGLContext::SAMPLE_BUFFERS, sample_buffers,
98 RendererGLContext::SHARE_RESOURCES, attributes.shareResources ? 1 : 0,
99 RendererGLContext::BIND_GENERATES_RESOURCES, 0,
100 RendererGLContext::NONE,
101 };
102
103 const char* preferred_extensions = attributes.noExtensions ?
104 kWebGLPreferredGLExtensions : "*";
105
106 const GPUInfo& gpu_info = host->gpu_info();
107 UMA_HISTOGRAM_ENUMERATION( 94 UMA_HISTOGRAM_ENUMERATION(
108 "GPU.WebGraphicsContext3D_Init_CanLoseContext", 95 "GPU.WebGraphicsContext3D_Init_CanLoseContext",
109 attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context, 96 attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context,
110 4); 97 4);
111 if (attributes.canRecoverFromContextLoss == false) { 98 if (attributes.canRecoverFromContextLoss == false) {
112 if (gpu_info.can_lose_context) 99 if (gpu_info.can_lose_context)
113 return false; 100 return false;
114 } 101 }
115 102
116 GURL active_url;
117 if (web_view && web_view->mainFrame()) 103 if (web_view && web_view->mainFrame())
118 active_url = GURL(web_view->mainFrame()->document().url()); 104 active_url_ = GURL(web_view->mainFrame()->document().url());
119 105
120 RendererGLContext* share_group = NULL; 106 attributes_ = attributes;
121 if (attributes.shareResources) { 107 render_directly_to_web_view_ = render_directly_to_web_view;
122 share_group = g_all_shared_contexts.Pointer()->empty() ? 108 if (render_directly_to_web_view_) {
123 NULL : (*g_all_shared_contexts.Pointer()->begin())->context_; 109 RenderView* render_view = RenderView::FromWebView(web_view);
110 if (!render_view)
111 return false;
112 render_view_routing_id_ = render_view->routing_id();
113 #ifndef WTF_USE_THREADED_COMPOSITING
114 web_view_ = web_view;
115 #endif
116 }
117 return true;
118 }
119
120 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() {
121 if (context_)
122 return true;
123 if (initialize_failed_)
124 return false;
125
126 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL");
127
128 // Convert WebGL context creation attributes into RendererGLContext / EGL size
129 // requests.
130 const int alpha_size = attributes_.alpha ? 8 : 0;
131 const int depth_size = attributes_.depth ? 24 : 0;
132 const int stencil_size = attributes_.stencil ? 8 : 0;
133 const int samples = attributes_.antialias ? 4 : 0;
134 const int sample_buffers = attributes_.antialias ? 1 : 0;
135 const int32 attribs[] = {
136 RendererGLContext::ALPHA_SIZE, alpha_size,
137 RendererGLContext::DEPTH_SIZE, depth_size,
138 RendererGLContext::STENCIL_SIZE, stencil_size,
139 RendererGLContext::SAMPLES, samples,
140 RendererGLContext::SAMPLE_BUFFERS, sample_buffers,
141 RendererGLContext::SHARE_RESOURCES, attributes_.shareResources ? 1 : 0,
142 RendererGLContext::BIND_GENERATES_RESOURCES, 0,
143 RendererGLContext::NONE,
144 };
145
146 const char* preferred_extensions = attributes_.noExtensions ?
147 kWebGLPreferredGLExtensions : "*";
148
149 // We need to lock g_all_shared_contexts until after RendererGLContext::Create
150 // to ensure that the context we picked for our share group isn't deleted.
151 // (There's also a lock in our destructor.)
152 {
153 base::AutoLock lock(g_all_shared_contexts_lock.Get());
154 RendererGLContext* share_group = NULL;
155 if (attributes_.shareResources) {
156 share_group = g_all_shared_contexts.Pointer()->empty() ?
157 NULL : (*g_all_shared_contexts.Pointer()->begin())->context_;
158 }
159
160 if (render_directly_to_web_view_) {
161 context_ = RendererGLContext::CreateViewContext(
162 host_,
163 render_view_routing_id_,
164 share_group,
165 preferred_extensions,
166 attribs,
167 active_url_);
168 } else {
169 context_ = RendererGLContext::CreateOffscreenContext(
170 host_,
171 gfx::Size(1, 1),
172 share_group,
173 preferred_extensions,
174 attribs,
175 active_url_);
176 }
124 } 177 }
125 178
126 render_directly_to_web_view_ = render_directly_to_web_view;
127 if (render_directly_to_web_view) {
128 #ifndef WTF_USE_THREADED_COMPOSITING
129 RenderView* renderview = RenderView::FromWebView(web_view);
130 if (!renderview)
131 return false;
132 web_view_ = web_view;
133 #endif
134 context_ = RendererGLContext::CreateViewContext(
135 host,
136 renderview->routing_id(),
137 share_group,
138 preferred_extensions,
139 attribs,
140 active_url);
141 } else {
142 context_ = RendererGLContext::CreateOffscreenContext(
143 host,
144 gfx::Size(1, 1),
145 share_group,
146 preferred_extensions,
147 attribs,
148 active_url);
149 #ifndef WTF_USE_THREADED_COMPOSITING
150 web_view_ = NULL;
151 #endif
152 }
153 if (!context_) 179 if (!context_)
154 return false; 180 return false;
155 181
156 gl_ = context_->GetImplementation(); 182 gl_ = context_->GetImplementation();
157 context_->SetContextLostCallback( 183 context_->SetContextLostCallback(
158 NewCallback(this, 184 NewCallback(this,
159 &WebGraphicsContext3DCommandBufferImpl::OnContextLost)); 185 &WebGraphicsContext3DCommandBufferImpl::OnContextLost));
160 186
161 // TODO(gman): Remove this. 187 // TODO(gman): Remove this.
162 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 188 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
163 if (command_line.HasSwitch(switches::kDisableGLSLTranslator)) { 189 if (command_line.HasSwitch(switches::kDisableGLSLTranslator)) {
164 context_->DisableShaderTranslation(); 190 context_->DisableShaderTranslation();
165 } 191 }
166 192
167 // Set attributes_ from created offscreen context. 193 // Set attributes_ from created offscreen context.
168 { 194 {
169 attributes_ = attributes;
170 GLint alpha_bits = 0; 195 GLint alpha_bits = 0;
171 getIntegerv(GL_ALPHA_BITS, &alpha_bits); 196 getIntegerv(GL_ALPHA_BITS, &alpha_bits);
172 attributes_.alpha = alpha_bits > 0; 197 attributes_.alpha = alpha_bits > 0;
173 GLint depth_bits = 0; 198 GLint depth_bits = 0;
174 getIntegerv(GL_DEPTH_BITS, &depth_bits); 199 getIntegerv(GL_DEPTH_BITS, &depth_bits);
175 attributes_.depth = depth_bits > 0; 200 attributes_.depth = depth_bits > 0;
176 GLint stencil_bits = 0; 201 GLint stencil_bits = 0;
177 getIntegerv(GL_STENCIL_BITS, &stencil_bits); 202 getIntegerv(GL_STENCIL_BITS, &stencil_bits);
178 attributes_.stencil = stencil_bits > 0; 203 attributes_.stencil = stencil_bits > 0;
179 GLint samples = 0; 204 GLint samples = 0;
180 getIntegerv(GL_SAMPLES, &samples); 205 getIntegerv(GL_SAMPLES, &samples);
181 attributes_.antialias = samples > 0; 206 attributes_.antialias = samples > 0;
182 } 207 }
183 208
184 if (attributes.shareResources) 209 if (attributes_.shareResources) {
210 base::AutoLock lock(g_all_shared_contexts_lock.Get());
185 g_all_shared_contexts.Pointer()->insert(this); 211 g_all_shared_contexts.Pointer()->insert(this);
212 }
186 213
187 return true; 214 return true;
188 } 215 }
189 216
190 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() { 217 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() {
218 if (!MaybeInitializeGL())
219 return false;
191 return RendererGLContext::MakeCurrent(context_); 220 return RendererGLContext::MakeCurrent(context_);
192 } 221 }
193 222
194 int WebGraphicsContext3DCommandBufferImpl::width() { 223 int WebGraphicsContext3DCommandBufferImpl::width() {
195 return cached_width_; 224 return cached_width_;
196 } 225 }
197 226
198 int WebGraphicsContext3DCommandBufferImpl::height() { 227 int WebGraphicsContext3DCommandBufferImpl::height() {
199 return cached_height_; 228 return cached_height_;
200 } 229 }
201 230
202 bool WebGraphicsContext3DCommandBufferImpl::isGLES2Compliant() { 231 bool WebGraphicsContext3DCommandBufferImpl::isGLES2Compliant() {
203 return true; 232 return true;
204 } 233 }
205 234
206 bool WebGraphicsContext3DCommandBufferImpl::setParentContext( 235 bool WebGraphicsContext3DCommandBufferImpl::setParentContext(
207 WebGraphicsContext3D* parent_context) { 236 WebGraphicsContext3D* parent_context) {
208 WebGraphicsContext3DCommandBufferImpl* parent_context_impl = 237 WebGraphicsContext3DCommandBufferImpl* parent_context_impl =
209 static_cast<WebGraphicsContext3DCommandBufferImpl*>(parent_context); 238 static_cast<WebGraphicsContext3DCommandBufferImpl*>(parent_context);
210 return context_->SetParent( 239 return context_->SetParent(
211 parent_context_impl ? parent_context_impl->context() : NULL); 240 parent_context_impl ? parent_context_impl->context() : NULL);
212 } 241 }
213 242
214 WebGLId WebGraphicsContext3DCommandBufferImpl::getPlatformTextureId() { 243 WebGLId WebGraphicsContext3DCommandBufferImpl::getPlatformTextureId() {
215 DCHECK(context_);
216 return context_->GetParentTextureId(); 244 return context_->GetParentTextureId();
217 } 245 }
218 246
219 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() { 247 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() {
220 // Copies the contents of the off-screen render target into the texture 248 // Copies the contents of the off-screen render target into the texture
221 // used by the compositor. 249 // used by the compositor.
222 #ifndef WTF_USE_THREADED_COMPOSITING 250 #ifndef WTF_USE_THREADED_COMPOSITING
223 RenderView* renderview = 251 RenderView* renderview =
224 web_view_ ? RenderView::FromWebView(web_view_) : NULL; 252 web_view_ ? RenderView::FromWebView(web_view_) : NULL;
225 if (renderview) 253 if (renderview)
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin(); 687 std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin();
660 WGC3Denum err = *iter; 688 WGC3Denum err = *iter;
661 synthetic_errors_.erase(iter); 689 synthetic_errors_.erase(iter);
662 return err; 690 return err;
663 } 691 }
664 692
665 return gl_->GetError(); 693 return gl_->GetError();
666 } 694 }
667 695
668 bool WebGraphicsContext3DCommandBufferImpl::isContextLost() { 696 bool WebGraphicsContext3DCommandBufferImpl::isContextLost() {
669 return context_->IsCommandBufferContextLost() || 697 return initialize_failed_ ||
698 (context_ && context_->IsCommandBufferContextLost()) ||
670 context_lost_reason_ != GL_NO_ERROR; 699 context_lost_reason_ != GL_NO_ERROR;
671 } 700 }
672 701
673 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*) 702 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*)
674 703
675 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv, 704 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv,
676 GetFramebufferAttachmentParameteriv, 705 GetFramebufferAttachmentParameteriv,
677 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*) 706 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*)
678 707
679 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*) 708 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*)
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 } 1093 }
1065 #ifndef WTF_USE_THREADED_COMPOSITING 1094 #ifndef WTF_USE_THREADED_COMPOSITING
1066 RenderView* renderview = 1095 RenderView* renderview =
1067 web_view_ ? RenderView::FromWebView(web_view_) : NULL; 1096 web_view_ ? RenderView::FromWebView(web_view_) : NULL;
1068 if (renderview) 1097 if (renderview)
1069 renderview->OnViewContextSwapBuffersAborted(); 1098 renderview->OnViewContextSwapBuffersAborted();
1070 #endif 1099 #endif
1071 } 1100 }
1072 1101
1073 #endif // defined(ENABLE_GPU) 1102 #endif // defined(ENABLE_GPU)
OLDNEW
« no previous file with comments | « content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h ('k') | content/renderer/pepper_plugin_delegate_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698