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

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: 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 : context_(NULL),
40 gl_(NULL), 43 gl_(NULL),
41 #ifndef WTF_USE_THREADED_COMPOSITING 44 #ifndef WTF_USE_THREADED_COMPOSITING
42 web_view_(NULL), 45 web_view_(NULL),
43 #endif 46 #endif
44 #if defined(OS_MACOSX) 47 #if defined(OS_MACOSX)
45 plugin_handle_(NULL), 48 plugin_handle_(NULL),
46 #endif // defined(OS_MACOSX) 49 #endif // defined(OS_MACOSX)
47 context_lost_callback_(0), 50 context_lost_callback_(0),
48 context_lost_reason_(GL_NO_ERROR), 51 context_lost_reason_(GL_NO_ERROR),
49 swapbuffers_complete_callback_(0), 52 swapbuffers_complete_callback_(0),
50 cached_width_(0), 53 cached_width_(0),
51 cached_height_(0), 54 cached_height_(0),
52 bound_fbo_(0), 55 bound_fbo_(0),
53 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 56 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
54 } 57 }
55 58
56 WebGraphicsContext3DCommandBufferImpl:: 59 WebGraphicsContext3DCommandBufferImpl::
57 ~WebGraphicsContext3DCommandBufferImpl() { 60 ~WebGraphicsContext3DCommandBufferImpl() {
58 g_all_shared_contexts.Pointer()->erase(this); 61 {
62 base::AutoLock lock(g_all_shared_contexts_lock.Get());
63 g_all_shared_contexts.Pointer()->erase(this);
64 }
59 delete context_; 65 delete context_;
60 } 66 }
61 67
62 // This string should only be passed for WebGL contexts. Nothing ELSE!!! 68 // This string should only be passed for WebGL contexts. Nothing ELSE!!!
63 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of 69 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of
64 // a context should not pass this string. 70 // a context should not pass this string.
65 static const char* kWebGLPreferredGLExtensions = 71 static const char* kWebGLPreferredGLExtensions =
66 "GL_OES_packed_depth_stencil " 72 "GL_OES_packed_depth_stencil "
67 "GL_OES_depth24 " 73 "GL_OES_depth24 "
68 "GL_CHROMIUM_webglsl"; 74 "GL_CHROMIUM_webglsl";
69 75
70 bool WebGraphicsContext3DCommandBufferImpl::initialize( 76 bool WebGraphicsContext3DCommandBufferImpl::initialize(
71 WebGraphicsContext3D::Attributes attributes, 77 WebGraphicsContext3D::Attributes attributes,
72 WebKit::WebView* web_view, 78 WebKit::WebView* web_view,
73 bool render_directly_to_web_view) { 79 bool render_directly_to_web_view) {
80 DCHECK(!context_);
74 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize"); 81 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize");
75 RenderThread* render_thread = RenderThread::current(); 82 RenderThread* render_thread = RenderThread::current();
76 if (!render_thread) 83 if (!render_thread)
77 return false; 84 return false;
78 GpuChannelHost* host = render_thread->EstablishGpuChannelSync( 85 host_ = render_thread->EstablishGpuChannelSync(
79 content:: 86 content::
80 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE); 87 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE);
81 if (!host) 88 if (!host_)
82 return false; 89 return false;
83 DCHECK(host->state() == GpuChannelHost::kConnected); 90 DCHECK(host_->state() == GpuChannelHost::kConnected);
84 91
85 // Convert WebGL context creation attributes into RendererGLContext / EGL size 92 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( 93 UMA_HISTOGRAM_ENUMERATION(
108 "GPU.WebGraphicsContext3D_Init_CanLoseContext", 94 "GPU.WebGraphicsContext3D_Init_CanLoseContext",
109 attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context, 95 attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context,
110 4); 96 4);
111 if (attributes.canRecoverFromContextLoss == false) { 97 if (attributes.canRecoverFromContextLoss == false) {
112 if (gpu_info.can_lose_context) 98 if (gpu_info.can_lose_context)
113 return false; 99 return false;
114 } 100 }
115 101
116 GURL active_url;
117 if (web_view && web_view->mainFrame()) 102 if (web_view && web_view->mainFrame())
118 active_url = GURL(web_view->mainFrame()->document().url()); 103 active_url_ = GURL(web_view->mainFrame()->document().url());
119 104
120 RendererGLContext* share_group = NULL; 105 attributes_ = attributes;
121 if (attributes.shareResources) { 106 render_directly_to_web_view_ = render_directly_to_web_view;
122 share_group = g_all_shared_contexts.Pointer()->empty() ? 107 if (render_directly_to_web_view_) {
123 NULL : (*g_all_shared_contexts.Pointer()->begin())->context_; 108 RenderView* render_view = RenderView::FromWebView(web_view);
109 if (!render_view)
110 return false;
111 render_view_routing_id_ = render_view->routing_id();
112 #ifndef WTF_USE_THREADED_COMPOSITING
113 web_view_ = web_view;
114 #endif
115 }
116 return true;
117 }
118
119 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() {
120 if (context_)
121 return true;
122
123 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL");
124
125 // Convert WebGL context creation attributes into RendererGLContext / EGL size
126 // requests.
127 const int alpha_size = attributes_.alpha ? 8 : 0;
128 const int depth_size = attributes_.depth ? 24 : 0;
129 const int stencil_size = attributes_.stencil ? 8 : 0;
130 const int samples = attributes_.antialias ? 4 : 0;
131 const int sample_buffers = attributes_.antialias ? 1 : 0;
132 const int32 attribs[] = {
133 RendererGLContext::ALPHA_SIZE, alpha_size,
134 RendererGLContext::DEPTH_SIZE, depth_size,
135 RendererGLContext::STENCIL_SIZE, stencil_size,
136 RendererGLContext::SAMPLES, samples,
137 RendererGLContext::SAMPLE_BUFFERS, sample_buffers,
138 RendererGLContext::SHARE_RESOURCES, attributes_.shareResources ? 1 : 0,
139 RendererGLContext::BIND_GENERATES_RESOURCES, 0,
140 RendererGLContext::NONE,
141 };
142
143 const char* preferred_extensions = attributes_.noExtensions ?
144 kWebGLPreferredGLExtensions : "*";
145
146 // We need to lock g_all_shared_contexts until after RendererGLContext::Create
147 // to ensure that the context we picked for our share group isn't deleted.
148 // (There's also a lock in our destructor.)
149 {
150 base::AutoLock lock(g_all_shared_contexts_lock.Get());
151 RendererGLContext* share_group = NULL;
152 if (attributes_.shareResources) {
153 share_group = g_all_shared_contexts.Pointer()->empty() ?
154 NULL : (*g_all_shared_contexts.Pointer()->begin())->context_;
155 }
156
157 if (render_directly_to_web_view_) {
158 context_ = RendererGLContext::CreateViewContext(
159 host_,
160 render_view_routing_id_,
161 share_group,
162 preferred_extensions,
163 attribs,
164 active_url_);
165 } else {
166 context_ = RendererGLContext::CreateOffscreenContext(
167 host_,
168 gfx::Size(1, 1),
169 share_group,
170 preferred_extensions,
171 attribs,
172 active_url_);
173 }
124 } 174 }
125 175
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_) 176 if (!context_)
154 return false; 177 return false;
155 178
156 gl_ = context_->GetImplementation(); 179 gl_ = context_->GetImplementation();
157 context_->SetContextLostCallback( 180 context_->SetContextLostCallback(
158 NewCallback(this, 181 NewCallback(this,
159 &WebGraphicsContext3DCommandBufferImpl::OnContextLost)); 182 &WebGraphicsContext3DCommandBufferImpl::OnContextLost));
160 183
161 // TODO(gman): Remove this. 184 // TODO(gman): Remove this.
162 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 185 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
163 if (command_line.HasSwitch(switches::kDisableGLSLTranslator)) { 186 if (command_line.HasSwitch(switches::kDisableGLSLTranslator)) {
164 context_->DisableShaderTranslation(); 187 context_->DisableShaderTranslation();
165 } 188 }
166 189
167 // Set attributes_ from created offscreen context. 190 // Set attributes_ from created offscreen context.
168 { 191 {
169 attributes_ = attributes;
170 GLint alpha_bits = 0; 192 GLint alpha_bits = 0;
171 getIntegerv(GL_ALPHA_BITS, &alpha_bits); 193 getIntegerv(GL_ALPHA_BITS, &alpha_bits);
172 attributes_.alpha = alpha_bits > 0; 194 attributes_.alpha = alpha_bits > 0;
173 GLint depth_bits = 0; 195 GLint depth_bits = 0;
174 getIntegerv(GL_DEPTH_BITS, &depth_bits); 196 getIntegerv(GL_DEPTH_BITS, &depth_bits);
175 attributes_.depth = depth_bits > 0; 197 attributes_.depth = depth_bits > 0;
176 GLint stencil_bits = 0; 198 GLint stencil_bits = 0;
177 getIntegerv(GL_STENCIL_BITS, &stencil_bits); 199 getIntegerv(GL_STENCIL_BITS, &stencil_bits);
178 attributes_.stencil = stencil_bits > 0; 200 attributes_.stencil = stencil_bits > 0;
179 GLint samples = 0; 201 GLint samples = 0;
180 getIntegerv(GL_SAMPLES, &samples); 202 getIntegerv(GL_SAMPLES, &samples);
181 attributes_.antialias = samples > 0; 203 attributes_.antialias = samples > 0;
182 } 204 }
183 205
184 if (attributes.shareResources) 206 if (attributes_.shareResources) {
207 base::AutoLock lock(g_all_shared_contexts_lock.Get());
185 g_all_shared_contexts.Pointer()->insert(this); 208 g_all_shared_contexts.Pointer()->insert(this);
209 }
186 210
187 return true; 211 return true;
188 } 212 }
189 213
190 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() { 214 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() {
215 if (!MaybeInitializeGL())
216 return false;
191 return RendererGLContext::MakeCurrent(context_); 217 return RendererGLContext::MakeCurrent(context_);
192 } 218 }
193 219
194 int WebGraphicsContext3DCommandBufferImpl::width() { 220 int WebGraphicsContext3DCommandBufferImpl::width() {
195 return cached_width_; 221 return cached_width_;
196 } 222 }
197 223
198 int WebGraphicsContext3DCommandBufferImpl::height() { 224 int WebGraphicsContext3DCommandBufferImpl::height() {
199 return cached_height_; 225 return cached_height_;
200 } 226 }
201 227
202 bool WebGraphicsContext3DCommandBufferImpl::isGLES2Compliant() { 228 bool WebGraphicsContext3DCommandBufferImpl::isGLES2Compliant() {
203 return true; 229 return true;
204 } 230 }
205 231
206 bool WebGraphicsContext3DCommandBufferImpl::setParentContext( 232 bool WebGraphicsContext3DCommandBufferImpl::setParentContext(
207 WebGraphicsContext3D* parent_context) { 233 WebGraphicsContext3D* parent_context) {
208 WebGraphicsContext3DCommandBufferImpl* parent_context_impl = 234 WebGraphicsContext3DCommandBufferImpl* parent_context_impl =
209 static_cast<WebGraphicsContext3DCommandBufferImpl*>(parent_context); 235 static_cast<WebGraphicsContext3DCommandBufferImpl*>(parent_context);
210 return context_->SetParent( 236 return context_->SetParent(
211 parent_context_impl ? parent_context_impl->context() : NULL); 237 parent_context_impl ? parent_context_impl->context() : NULL);
212 } 238 }
213 239
214 WebGLId WebGraphicsContext3DCommandBufferImpl::getPlatformTextureId() { 240 WebGLId WebGraphicsContext3DCommandBufferImpl::getPlatformTextureId() {
215 DCHECK(context_);
216 return context_->GetParentTextureId(); 241 return context_->GetParentTextureId();
217 } 242 }
218 243
219 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() { 244 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() {
220 // Copies the contents of the off-screen render target into the texture 245 // Copies the contents of the off-screen render target into the texture
221 // used by the compositor. 246 // used by the compositor.
222 #ifndef WTF_USE_THREADED_COMPOSITING 247 #ifndef WTF_USE_THREADED_COMPOSITING
223 RenderView* renderview = 248 RenderView* renderview =
224 web_view_ ? RenderView::FromWebView(web_view_) : NULL; 249 web_view_ ? RenderView::FromWebView(web_view_) : NULL;
225 if (renderview) 250 if (renderview)
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin(); 684 std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin();
660 WGC3Denum err = *iter; 685 WGC3Denum err = *iter;
661 synthetic_errors_.erase(iter); 686 synthetic_errors_.erase(iter);
662 return err; 687 return err;
663 } 688 }
664 689
665 return gl_->GetError(); 690 return gl_->GetError();
666 } 691 }
667 692
668 bool WebGraphicsContext3DCommandBufferImpl::isContextLost() { 693 bool WebGraphicsContext3DCommandBufferImpl::isContextLost() {
669 return context_->IsCommandBufferContextLost() || 694 return !context_ || context_->IsCommandBufferContextLost() ||
670 context_lost_reason_ != GL_NO_ERROR; 695 context_lost_reason_ != GL_NO_ERROR;
671 } 696 }
672 697
673 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*) 698 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*)
674 699
675 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv, 700 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv,
676 GetFramebufferAttachmentParameteriv, 701 GetFramebufferAttachmentParameteriv,
677 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*) 702 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*)
678 703
679 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*) 704 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*)
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 } 1089 }
1065 #ifndef WTF_USE_THREADED_COMPOSITING 1090 #ifndef WTF_USE_THREADED_COMPOSITING
1066 RenderView* renderview = 1091 RenderView* renderview =
1067 web_view_ ? RenderView::FromWebView(web_view_) : NULL; 1092 web_view_ ? RenderView::FromWebView(web_view_) : NULL;
1068 if (renderview) 1093 if (renderview)
1069 renderview->OnViewContextSwapBuffersAborted(); 1094 renderview->OnViewContextSwapBuffersAborted();
1070 #endif 1095 #endif
1071 } 1096 }
1072 1097
1073 #endif // defined(ENABLE_GPU) 1098 #endif // defined(ENABLE_GPU)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698