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

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

Issue 7713015: Split WebGraphicsContext3DCommandBufferImpl::initialize() into two stages. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Renamed to MaybeInitializeGL, clarified threading contract, added some asserts Created 9 years, 4 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/message_loop.h"
23 #include "base/metrics/histogram.h" 24 #include "base/metrics/histogram.h"
25 #include "base/synchronization/lock.h"
24 #include "content/common/content_switches.h" 26 #include "content/common/content_switches.h"
25 #include "content/renderer/gpu/gpu_channel_host.h" 27 #include "content/renderer/gpu/gpu_channel_host.h"
26 #include "content/renderer/render_thread.h" 28 #include "content/renderer/render_thread.h"
27 #include "content/renderer/render_view.h" 29 #include "content/renderer/render_view.h"
28 #include "gpu/command_buffer/client/gles2_implementation.h" 30 #include "gpu/command_buffer/client/gles2_implementation.h"
29 #include "gpu/command_buffer/common/constants.h" 31 #include "gpu/command_buffer/common/constants.h"
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
33 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h" 35 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h"
34 36
37 static base::LazyInstance<base::Lock>
38 g_all_contexts_lock(base::LINKER_INITIALIZED);
35 static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> > 39 static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> >
36 g_all_contexts(base::LINKER_INITIALIZED); 40 g_all_contexts(base::LINKER_INITIALIZED);
37 41
38 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl() 42 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl()
39 : context_(NULL), 43 : context_(NULL),
40 gl_(NULL), 44 gl_(NULL),
45 #ifndef NDEBUG
46 gl_message_loop_(NULL),
47 #endif
41 #ifndef WTF_USE_THREADED_COMPOSITING 48 #ifndef WTF_USE_THREADED_COMPOSITING
42 web_view_(NULL), 49 web_view_(NULL),
43 #endif 50 #endif
44 #if defined(OS_MACOSX) 51 #if defined(OS_MACOSX)
45 plugin_handle_(NULL), 52 plugin_handle_(NULL),
46 #endif // defined(OS_MACOSX) 53 #endif // defined(OS_MACOSX)
47 context_lost_callback_(0), 54 context_lost_callback_(0),
48 context_lost_reason_(GL_NO_ERROR), 55 context_lost_reason_(GL_NO_ERROR),
49 swapbuffers_complete_callback_(0), 56 swapbuffers_complete_callback_(0),
50 cached_width_(0), 57 cached_width_(0),
51 cached_height_(0), 58 cached_height_(0),
52 bound_fbo_(0) { 59 bound_fbo_(0) {
53 } 60 }
54 61
55 WebGraphicsContext3DCommandBufferImpl:: 62 WebGraphicsContext3DCommandBufferImpl::
56 ~WebGraphicsContext3DCommandBufferImpl() { 63 ~WebGraphicsContext3DCommandBufferImpl() {
57 g_all_contexts.Pointer()->erase(this); 64 {
58 delete context_; 65 base::AutoLock lock(g_all_contexts_lock.Get());
66 g_all_contexts.Pointer()->erase(this);
67 }
68 if (context_) {
69 DLOG_ASSERT(MessageLoop::current() == gl_message_loop_);
70 delete context_;
71 }
59 } 72 }
60 73
61 // This string should only be passed for WebGL contexts. Nothing ELSE!!! 74 // This string should only be passed for WebGL contexts. Nothing ELSE!!!
62 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of 75 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of
63 // a context should not pass this string. 76 // a context should not pass this string.
64 static const char* kWebGLPreferredGLExtensions = 77 static const char* kWebGLPreferredGLExtensions =
65 "GL_OES_packed_depth_stencil " 78 "GL_OES_packed_depth_stencil "
66 "GL_OES_depth24 " 79 "GL_OES_depth24 "
67 "GL_CHROMIUM_webglsl"; 80 "GL_CHROMIUM_webglsl";
68 81
69 bool WebGraphicsContext3DCommandBufferImpl::initialize( 82 bool WebGraphicsContext3DCommandBufferImpl::initialize(
70 WebGraphicsContext3D::Attributes attributes, 83 WebGraphicsContext3D::Attributes attributes,
71 WebKit::WebView* web_view, 84 WebKit::WebView* web_view,
72 bool render_directly_to_web_view) { 85 bool render_directly_to_web_view) {
86 DCHECK(!context_);
73 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize"); 87 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize");
74 webkit_glue::BindSkiaToCommandBufferGL(); 88 webkit_glue::BindSkiaToCommandBufferGL();
75 RenderThread* render_thread = RenderThread::current(); 89 RenderThread* render_thread = RenderThread::current();
76 if (!render_thread) 90 if (!render_thread)
77 return false; 91 return false;
78 GpuChannelHost* host = render_thread->EstablishGpuChannelSync( 92 host_ = render_thread->EstablishGpuChannelSync(
79 content:: 93 content::
80 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE); 94 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE);
81 if (!host) 95 if (!host_)
82 return false; 96 return false;
83 DCHECK(host->state() == GpuChannelHost::kConnected); 97 DCHECK(host_->state() == GpuChannelHost::kConnected);
98
99 const GPUInfo& gpu_info = host_->gpu_info();
100 UMA_HISTOGRAM_ENUMERATION(
101 "GPU.WebGraphicsContext3D_Init_CanLoseContext",
102 attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context,
103 4);
104 if (attributes.canRecoverFromContextLoss == false) {
105 if (gpu_info.can_lose_context)
106 return false;
107 }
108
109 if (web_view && web_view->mainFrame())
110 active_url_ = GURL(web_view->mainFrame()->document().url());
111
112 attributes_ = attributes;
113 render_directly_to_web_view_ = render_directly_to_web_view;
114 if (render_directly_to_web_view_) {
115 RenderView* renderview = RenderView::FromWebView(web_view);
116 if (!renderview)
117 return false;
118 render_view_routing_id_ = renderview->routing_id(),
119 #ifndef WTF_USE_THREADED_COMPOSITING
120 web_view_ = web_view;
121 } else {
122 web_view_ = NULL;
123 #endif
124 }
125 return true;
126 }
127
128 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() {
129 if (context_) {
130 DLOG_ASSERT(MessageLoop::current() == gl_message_loop_);
131 return true;
132 }
133 #ifndef NDEBUG
134 gl_message_loop_ = MessageLoop::current();
135 #endif
136 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL");
84 137
85 // Convert WebGL context creation attributes into RendererGLContext / EGL size 138 // Convert WebGL context creation attributes into RendererGLContext / EGL size
86 // requests. 139 // requests.
87 const int alpha_size = attributes.alpha ? 8 : 0; 140 const int alpha_size = attributes_.alpha ? 8 : 0;
88 const int depth_size = attributes.depth ? 24 : 0; 141 const int depth_size = attributes_.depth ? 24 : 0;
89 const int stencil_size = attributes.stencil ? 8 : 0; 142 const int stencil_size = attributes_.stencil ? 8 : 0;
90 const int samples = attributes.antialias ? 4 : 0; 143 const int samples = attributes_.antialias ? 4 : 0;
91 const int sample_buffers = attributes.antialias ? 1 : 0; 144 const int sample_buffers = attributes_.antialias ? 1 : 0;
92 const int32 attribs[] = { 145 const int32 attribs[] = {
93 RendererGLContext::ALPHA_SIZE, alpha_size, 146 RendererGLContext::ALPHA_SIZE, alpha_size,
94 RendererGLContext::DEPTH_SIZE, depth_size, 147 RendererGLContext::DEPTH_SIZE, depth_size,
95 RendererGLContext::STENCIL_SIZE, stencil_size, 148 RendererGLContext::STENCIL_SIZE, stencil_size,
96 RendererGLContext::SAMPLES, samples, 149 RendererGLContext::SAMPLES, samples,
97 RendererGLContext::SAMPLE_BUFFERS, sample_buffers, 150 RendererGLContext::SAMPLE_BUFFERS, sample_buffers,
98 RendererGLContext::NONE, 151 RendererGLContext::NONE,
99 }; 152 };
100 153
101 const char* preferred_extensions = attributes.noExtensions ?
102 kWebGLPreferredGLExtensions : "*";
103
104 const GPUInfo& gpu_info = host->gpu_info();
105 UMA_HISTOGRAM_ENUMERATION(
106 "GPU.WebGraphicsContext3D_Init_CanLoseContext",
107 attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context,
108 4);
109 if (attributes.canRecoverFromContextLoss == false) {
110 if (gpu_info.can_lose_context)
111 return false;
112 }
113
114 GURL active_url;
115 if (web_view && web_view->mainFrame())
116 active_url = GURL(web_view->mainFrame()->document().url());
117
118 // HACK: Assume this is a WebGL context by looking for the noExtensions 154 // HACK: Assume this is a WebGL context by looking for the noExtensions
119 // attribute. WebGL contexts must not go in the share group because they 155 // attribute. WebGL contexts must not go in the share group because they
120 // rely on destruction of the context to clean up owned resources. Putting 156 // rely on destruction of the context to clean up owned resources. Putting
121 // them in a share group would prevent this from happening. 157 // them in a share group would prevent this from happening.
158 base::AutoLock lock(g_all_contexts_lock.Get());
122 RendererGLContext* share_group = NULL; 159 RendererGLContext* share_group = NULL;
123 if (!attributes.noExtensions) { 160 if (!attributes_.noExtensions) {
124 share_group = g_all_contexts.Pointer()->empty() ? 161 share_group = g_all_contexts.Pointer()->empty() ?
125 NULL : (*g_all_contexts.Pointer()->begin())->context_; 162 NULL : (*g_all_contexts.Pointer()->begin())->context_;
126 } 163 }
127 164
128 render_directly_to_web_view_ = render_directly_to_web_view; 165 const char* preferred_extensions = attributes_.noExtensions ?
129 if (render_directly_to_web_view) { 166 kWebGLPreferredGLExtensions : "*";
130 #ifndef WTF_USE_THREADED_COMPOSITING 167
131 RenderView* renderview = RenderView::FromWebView(web_view); 168 if (render_directly_to_web_view_) {
132 if (!renderview)
133 return false;
134 web_view_ = web_view;
135 #endif
136 context_ = RendererGLContext::CreateViewContext( 169 context_ = RendererGLContext::CreateViewContext(
137 host, 170 host_,
138 renderview->routing_id(), 171 render_view_routing_id_,
139 !attributes.noExtensions, 172 !attributes_.noExtensions,
140 share_group, 173 share_group,
141 preferred_extensions, 174 preferred_extensions,
142 attribs, 175 attribs,
143 active_url); 176 active_url_);
144 if (context_) { 177 if (context_) {
145 context_->SetSwapBuffersCallback( 178 context_->SetSwapBuffersCallback(
146 NewCallback(this, 179 NewCallback(this,
147 &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete)); 180 &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete));
148 } 181 }
149 } else { 182 } else {
150 context_ = RendererGLContext::CreateOffscreenContext( 183 context_ = RendererGLContext::CreateOffscreenContext(
151 host, 184 host_,
152 gfx::Size(1, 1), 185 gfx::Size(1, 1),
153 !attributes.noExtensions, 186 !attributes_.noExtensions,
154 share_group, 187 share_group,
155 preferred_extensions, 188 preferred_extensions,
156 attribs, 189 attribs,
157 active_url); 190 active_url_);
158 #ifndef WTF_USE_THREADED_COMPOSITING
159 web_view_ = NULL;
160 #endif
161 } 191 }
162 if (!context_) 192 if (!context_)
163 return false; 193 return false;
164 194
165 gl_ = context_->GetImplementation(); 195 gl_ = context_->GetImplementation();
166 context_->SetContextLostCallback( 196 context_->SetContextLostCallback(
167 NewCallback(this, 197 NewCallback(this,
168 &WebGraphicsContext3DCommandBufferImpl::OnContextLost)); 198 &WebGraphicsContext3DCommandBufferImpl::OnContextLost));
169 199
170 // TODO(gman): Remove this. 200 // TODO(gman): Remove this.
171 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 201 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
172 if (command_line.HasSwitch(switches::kDisableGLSLTranslator)) { 202 if (command_line.HasSwitch(switches::kDisableGLSLTranslator)) {
173 context_->DisableShaderTranslation(); 203 context_->DisableShaderTranslation();
174 } 204 }
175 205
176 // Set attributes_ from created offscreen context. 206 // Set attributes_ from created offscreen context.
177 { 207 {
178 attributes_ = attributes;
179 GLint alpha_bits = 0; 208 GLint alpha_bits = 0;
180 getIntegerv(GL_ALPHA_BITS, &alpha_bits); 209 getIntegerv(GL_ALPHA_BITS, &alpha_bits);
181 attributes_.alpha = alpha_bits > 0; 210 attributes_.alpha = alpha_bits > 0;
182 GLint depth_bits = 0; 211 GLint depth_bits = 0;
183 getIntegerv(GL_DEPTH_BITS, &depth_bits); 212 getIntegerv(GL_DEPTH_BITS, &depth_bits);
184 attributes_.depth = depth_bits > 0; 213 attributes_.depth = depth_bits > 0;
185 GLint stencil_bits = 0; 214 GLint stencil_bits = 0;
186 getIntegerv(GL_STENCIL_BITS, &stencil_bits); 215 getIntegerv(GL_STENCIL_BITS, &stencil_bits);
187 attributes_.stencil = stencil_bits > 0; 216 attributes_.stencil = stencil_bits > 0;
188 GLint samples = 0; 217 GLint samples = 0;
189 getIntegerv(GL_SAMPLES, &samples); 218 getIntegerv(GL_SAMPLES, &samples);
190 attributes_.antialias = samples > 0; 219 attributes_.antialias = samples > 0;
191 } 220 }
192 221
193 if (!attributes.noExtensions) 222 if (!attributes_.noExtensions)
194 g_all_contexts.Pointer()->insert(this); 223 g_all_contexts.Pointer()->insert(this);
195 224
196 return true; 225 return true;
197 } 226 }
198 227
199 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() { 228 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() {
229 if (!MaybeInitializeGL()) {
nduca 2011/08/25 02:10:01 remove {'s since oneliner
lain Merrick 2011/08/25 19:55:16 Done.
230 return false;
231 }
200 return RendererGLContext::MakeCurrent(context_); 232 return RendererGLContext::MakeCurrent(context_);
201 } 233 }
202 234
203 int WebGraphicsContext3DCommandBufferImpl::width() { 235 int WebGraphicsContext3DCommandBufferImpl::width() {
204 return cached_width_; 236 return cached_width_;
205 } 237 }
206 238
207 int WebGraphicsContext3DCommandBufferImpl::height() { 239 int WebGraphicsContext3DCommandBufferImpl::height() {
208 return cached_height_; 240 return cached_height_;
209 } 241 }
210 242
211 bool WebGraphicsContext3DCommandBufferImpl::isGLES2Compliant() { 243 bool WebGraphicsContext3DCommandBufferImpl::isGLES2Compliant() {
212 return true; 244 return true;
213 } 245 }
214 246
215 bool WebGraphicsContext3DCommandBufferImpl::setParentContext( 247 bool WebGraphicsContext3DCommandBufferImpl::setParentContext(
216 WebGraphicsContext3D* parent_context) { 248 WebGraphicsContext3D* parent_context) {
217 WebGraphicsContext3DCommandBufferImpl* parent_context_impl = 249 WebGraphicsContext3DCommandBufferImpl* parent_context_impl =
218 static_cast<WebGraphicsContext3DCommandBufferImpl*>(parent_context); 250 static_cast<WebGraphicsContext3DCommandBufferImpl*>(parent_context);
219 return context_->SetParent( 251 return context_->SetParent(
220 parent_context_impl ? parent_context_impl->context() : NULL); 252 parent_context_impl ? parent_context_impl->context() : NULL);
221 } 253 }
222 254
223 WebGLId WebGraphicsContext3DCommandBufferImpl::getPlatformTextureId() { 255 WebGLId WebGraphicsContext3DCommandBufferImpl::getPlatformTextureId() {
224 DCHECK(context_);
225 return context_->GetParentTextureId(); 256 return context_->GetParentTextureId();
226 } 257 }
227 258
228 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() { 259 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() {
229 // Copies the contents of the off-screen render target into the texture 260 // Copies the contents of the off-screen render target into the texture
230 // used by the compositor. 261 // used by the compositor.
231 #ifndef WTF_USE_THREADED_COMPOSITING 262 #ifndef WTF_USE_THREADED_COMPOSITING
232 RenderView* renderview = 263 RenderView* renderview =
233 web_view_ ? RenderView::FromWebView(web_view_) : NULL; 264 web_view_ ? RenderView::FromWebView(web_view_) : NULL;
234 if (renderview) 265 if (renderview)
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 } 1090 }
1060 #ifndef WTF_USE_THREADED_COMPOSITING 1091 #ifndef WTF_USE_THREADED_COMPOSITING
1061 RenderView* renderview = 1092 RenderView* renderview =
1062 web_view_ ? RenderView::FromWebView(web_view_) : NULL; 1093 web_view_ ? RenderView::FromWebView(web_view_) : NULL;
1063 if (renderview) 1094 if (renderview)
1064 renderview->OnViewContextSwapBuffersAborted(); 1095 renderview->OnViewContextSwapBuffersAborted();
1065 #endif 1096 #endif
1066 } 1097 }
1067 1098
1068 #endif // defined(ENABLE_GPU) 1099 #endif // defined(ENABLE_GPU)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698