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

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

Issue 9270025: Remove renderer dependencies from the GPU client classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add overrides Created 8 years, 10 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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)
6
7 #include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h" 5 #include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h"
8 6
9 #include "third_party/khronos/GLES2/gl2.h" 7 #include "third_party/khronos/GLES2/gl2.h"
10 #ifndef GL_GLEXT_PROTOTYPES 8 #ifndef GL_GLEXT_PROTOTYPES
11 #define GL_GLEXT_PROTOTYPES 1 9 #define GL_GLEXT_PROTOTYPES 1
12 #endif 10 #endif
13 #include "third_party/khronos/GLES2/gl2ext.h" 11 #include "third_party/khronos/GLES2/gl2ext.h"
14 12
15 #include <algorithm> 13 #include <algorithm>
16 #include <set> 14 #include <set>
17 15
18 #include "base/bind.h" 16 #include "base/bind.h"
19 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
20 #include "base/string_tokenizer.h" 18 #include "base/string_tokenizer.h"
21 #include "base/command_line.h" 19 #include "base/command_line.h"
22 #include "base/debug/trace_event.h" 20 #include "base/debug/trace_event.h"
23 #include "base/logging.h" 21 #include "base/logging.h"
24 #include "base/message_loop.h" 22 #include "base/message_loop.h"
25 #include "base/metrics/histogram.h" 23 #include "base/metrics/histogram.h"
26 #include "base/synchronization/lock.h" 24 #include "base/synchronization/lock.h"
27 #include "content/common/child_process.h"
28 #include "content/public/common/content_switches.h" 25 #include "content/public/common/content_switches.h"
29 #include "content/renderer/gpu/command_buffer_proxy.h" 26 #include "content/renderer/gpu/command_buffer_proxy.h"
30 #include "content/renderer/gpu/gpu_channel_host.h" 27 #include "content/renderer/gpu/gpu_channel_host.h"
31 #include "content/renderer/render_thread_impl.h"
32 #include "content/renderer/render_view_impl.h" 28 #include "content/renderer/render_view_impl.h"
33 #include "gpu/command_buffer/client/gles2_implementation.h" 29 #include "gpu/command_buffer/client/gles2_implementation.h"
34 #include "gpu/command_buffer/common/constants.h" 30 #include "gpu/command_buffer/common/constants.h"
35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
37 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
38 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h" 31 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h"
39 32
40 static base::LazyInstance<base::Lock>::Leaky 33 static base::LazyInstance<base::Lock>::Leaky
41 g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER; 34 g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER;
42 static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> > 35 static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> >
43 g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER; 36 g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER;
44 37
45 namespace { 38 namespace {
46 39
47 void ClearSharedContexts() { 40 void ClearSharedContexts() {
48 base::AutoLock lock(g_all_shared_contexts_lock.Get()); 41 base::AutoLock lock(g_all_shared_contexts_lock.Get());
49 g_all_shared_contexts.Pointer()->clear(); 42 g_all_shared_contexts.Pointer()->clear();
50 } 43 }
51 44
52 } // namespace anonymous 45 } // namespace anonymous
53 46
54 47
55 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl() 48 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
49 int surface_id,
50 const GURL& active_url,
51 const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client)
56 : initialize_failed_(false), 52 : initialize_failed_(false),
57 context_(NULL), 53 context_(NULL),
58 gl_(NULL), 54 gl_(NULL),
59 web_view_(NULL), 55 host_(NULL),
60 #if defined(OS_MACOSX) 56 surface_id_(surface_id),
61 plugin_handle_(NULL), 57 active_url_(active_url),
62 #endif // defined(OS_MACOSX) 58 swap_client_(swap_client),
63 context_lost_callback_(0), 59 context_lost_callback_(0),
64 context_lost_reason_(GL_NO_ERROR), 60 context_lost_reason_(GL_NO_ERROR),
65 swapbuffers_complete_callback_(0), 61 swapbuffers_complete_callback_(0),
66 gpu_preference_(gfx::PreferIntegratedGpu), 62 gpu_preference_(gfx::PreferIntegratedGpu),
67 cached_width_(0), 63 cached_width_(0),
68 cached_height_(0), 64 cached_height_(0),
69 bound_fbo_(0), 65 bound_fbo_(0),
70 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 66 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
71 } 67 }
72 68
73 WebGraphicsContext3DCommandBufferImpl:: 69 WebGraphicsContext3DCommandBufferImpl::
74 ~WebGraphicsContext3DCommandBufferImpl() { 70 ~WebGraphicsContext3DCommandBufferImpl() {
75 if (host_) { 71 if (host_) {
76 if (host_->WillGpuSwitchOccur(false, gpu_preference_)) { 72 if (host_->WillGpuSwitchOccur(false, gpu_preference_)) {
77 host_->ForciblyCloseChannel(); 73 host_->ForciblyCloseChannel();
78 ClearSharedContexts(); 74 ClearSharedContexts();
79 } 75 }
80 } 76 }
81 77
82 { 78 {
83 base::AutoLock lock(g_all_shared_contexts_lock.Get()); 79 base::AutoLock lock(g_all_shared_contexts_lock.Get());
84 g_all_shared_contexts.Pointer()->erase(this); 80 g_all_shared_contexts.Pointer()->erase(this);
85 } 81 }
86 delete context_; 82 delete context_;
87 } 83 }
88 84
89 bool WebGraphicsContext3DCommandBufferImpl::initialize( 85 bool WebGraphicsContext3DCommandBufferImpl::Initialize(
90 WebGraphicsContext3D::Attributes attributes, 86 const WebGraphicsContext3D::Attributes& attributes) {
91 WebKit::WebView* web_view,
92 bool render_directly_to_web_view) {
93 DCHECK(!context_); 87 DCHECK(!context_);
94 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize"); 88 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize");
95 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 89 GpuChannelHostFactory* factory = GpuChannelHostFactory::instance();
96 if (!render_thread) 90 if (!factory)
97 return false; 91 return false;
98 92
99 // The noExtensions and canRecoverFromContextLoss flags are 93 // The noExtensions and canRecoverFromContextLoss flags are
100 // currently used as hints that we are creating a context on 94 // currently used as hints that we are creating a context on
101 // behalf of WebGL or accelerated 2D canvas, respectively. 95 // behalf of WebGL or accelerated 2D canvas, respectively.
102 if (attributes.noExtensions || !attributes.canRecoverFromContextLoss) 96 if (attributes.noExtensions || !attributes.canRecoverFromContextLoss)
103 gpu_preference_ = gfx::PreferDiscreteGpu; 97 gpu_preference_ = gfx::PreferDiscreteGpu;
104 98
105 bool retry = false; 99 bool retry = false;
106 100
107 // Note similar code in Pepper PlatformContext3DImpl::Init. 101 // Note similar code in Pepper PlatformContext3DImpl::Init.
108 do { 102 do {
109 host_ = render_thread->EstablishGpuChannelSync( 103 host_ = factory->EstablishGpuChannelSync(
110 content:: 104 content::
111 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE); 105 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE);
112 if (!host_) 106 if (!host_)
113 return false; 107 return false;
114 DCHECK(host_->state() == GpuChannelHost::kConnected); 108 DCHECK(host_->state() == GpuChannelHost::kConnected);
115 109
116 if (!retry) { 110 if (!retry) {
117 // If the creation of this context requires all contexts for this 111 // If the creation of this context requires all contexts for this
118 // renderer to be destroyed on the GPU process side, then drop the 112 // renderer to be destroyed on the GPU process side, then drop the
119 // channel and recreate it. 113 // channel and recreate it.
(...skipping 10 matching lines...) Expand all
130 const content::GPUInfo& gpu_info = host_->gpu_info(); 124 const content::GPUInfo& gpu_info = host_->gpu_info();
131 UMA_HISTOGRAM_ENUMERATION( 125 UMA_HISTOGRAM_ENUMERATION(
132 "GPU.WebGraphicsContext3D_Init_CanLoseContext", 126 "GPU.WebGraphicsContext3D_Init_CanLoseContext",
133 attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context, 127 attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context,
134 4); 128 4);
135 if (attributes.canRecoverFromContextLoss == false) { 129 if (attributes.canRecoverFromContextLoss == false) {
136 if (gpu_info.can_lose_context) 130 if (gpu_info.can_lose_context)
137 return false; 131 return false;
138 } 132 }
139 133
140 if (web_view && web_view->mainFrame())
141 active_url_ = GURL(web_view->mainFrame()->document().url());
142
143 attributes_ = attributes; 134 attributes_ = attributes;
144 render_directly_to_web_view_ = render_directly_to_web_view;
145 if (render_directly_to_web_view_) {
146 RenderViewImpl* render_view = RenderViewImpl::FromWebView(web_view);
147 if (!render_view)
148 return false;
149 surface_id_ = render_view->surface_id();
150 web_view_ = web_view;
151 }
152 return true; 135 return true;
153 } 136 }
154 137
155 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() { 138 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() {
156 if (context_) 139 if (context_)
157 return true; 140 return true;
158 if (initialize_failed_) 141 if (initialize_failed_)
159 return false; 142 return false;
160 143
161 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL"); 144 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL");
162 145
163 // If the context is being initialized on something other than the main 146 // If the context is being initialized on something other than the main
164 // thread, then drop the web_view_ pointer so we don't accidentally 147 // thread, then make sure the swap_client_ pointer is NULL so we don't
165 // dereference it. 148 // accidentally dereference it.
166 MessageLoop* main_message_loop = 149 GpuChannelHostFactory* factory = GpuChannelHostFactory::instance();
167 ChildProcess::current()->main_thread()->message_loop(); 150 if (!factory || !factory->IsMainThread())
168 if (MessageLoop::current() != main_message_loop) 151 DCHECK(!swap_client_.get());
169 web_view_ = NULL;
170 152
171 // Convert WebGL context creation attributes into RendererGLContext / EGL size 153 // Convert WebGL context creation attributes into RendererGLContext / EGL size
172 // requests. 154 // requests.
173 const int alpha_size = attributes_.alpha ? 8 : 0; 155 const int alpha_size = attributes_.alpha ? 8 : 0;
174 const int depth_size = attributes_.depth ? 24 : 0; 156 const int depth_size = attributes_.depth ? 24 : 0;
175 const int stencil_size = attributes_.stencil ? 8 : 0; 157 const int stencil_size = attributes_.stencil ? 8 : 0;
176 const int samples = attributes_.antialias ? 4 : 0; 158 const int samples = attributes_.antialias ? 4 : 0;
177 const int sample_buffers = attributes_.antialias ? 1 : 0; 159 const int sample_buffers = attributes_.antialias ? 1 : 0;
178 const int32 attribs[] = { 160 const int32 attribs[] = {
179 RendererGLContext::ALPHA_SIZE, alpha_size, 161 RendererGLContext::ALPHA_SIZE, alpha_size,
(...skipping 12 matching lines...) Expand all
192 // to ensure that the context we picked for our share group isn't deleted. 174 // to ensure that the context we picked for our share group isn't deleted.
193 // (There's also a lock in our destructor.) 175 // (There's also a lock in our destructor.)
194 { 176 {
195 base::AutoLock lock(g_all_shared_contexts_lock.Get()); 177 base::AutoLock lock(g_all_shared_contexts_lock.Get());
196 RendererGLContext* share_group = NULL; 178 RendererGLContext* share_group = NULL;
197 if (attributes_.shareResources) { 179 if (attributes_.shareResources) {
198 share_group = g_all_shared_contexts.Pointer()->empty() ? 180 share_group = g_all_shared_contexts.Pointer()->empty() ?
199 NULL : (*g_all_shared_contexts.Pointer()->begin())->context_; 181 NULL : (*g_all_shared_contexts.Pointer()->begin())->context_;
200 } 182 }
201 183
202 if (render_directly_to_web_view_) { 184 if (surface_id_) {
203 context_ = RendererGLContext::CreateViewContext( 185 context_ = RendererGLContext::CreateViewContext(
204 host_, 186 host_,
205 surface_id_, 187 surface_id_,
206 share_group, 188 share_group,
207 preferred_extensions, 189 preferred_extensions,
208 attribs, 190 attribs,
209 active_url_, 191 active_url_,
210 gpu_preference_); 192 gpu_preference_);
211 } else { 193 } else {
212 context_ = RendererGLContext::CreateOffscreenContext( 194 context_ = RendererGLContext::CreateOffscreenContext(
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 parent_context_impl ? parent_context_impl->context() : NULL); 272 parent_context_impl ? parent_context_impl->context() : NULL);
291 } 273 }
292 274
293 WebGLId WebGraphicsContext3DCommandBufferImpl::getPlatformTextureId() { 275 WebGLId WebGraphicsContext3DCommandBufferImpl::getPlatformTextureId() {
294 return context_->GetParentTextureId(); 276 return context_->GetParentTextureId();
295 } 277 }
296 278
297 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() { 279 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() {
298 // Copies the contents of the off-screen render target into the texture 280 // Copies the contents of the off-screen render target into the texture
299 // used by the compositor. 281 // used by the compositor.
300 RenderViewImpl* renderview = 282 if (swap_client_.get())
301 web_view_ ? RenderViewImpl::FromWebView(web_view_) : NULL; 283 swap_client_->OnViewContextSwapBuffersPosted();
302 if (renderview)
303 renderview->OnViewContextSwapBuffersPosted();
304 context_->SwapBuffers(); 284 context_->SwapBuffers();
305 context_->Echo(base::Bind( 285 context_->Echo(base::Bind(
306 &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete, 286 &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete,
307 weak_ptr_factory_.GetWeakPtr())); 287 weak_ptr_factory_.GetWeakPtr()));
308 #if defined(OS_MACOSX) 288 #if defined(OS_MACOSX)
309 // It appears that making the compositor's on-screen context current on 289 // It appears that making the compositor's on-screen context current on
310 // other platforms implies this flush. TODO(kbr): this means that the 290 // other platforms implies this flush. TODO(kbr): this means that the
311 // TOUCH build and, in the future, other platforms might need this. 291 // TOUCH build and, in the future, other platforms might need this.
312 gl_->Flush(); 292 gl_->Flush();
313 #endif 293 #endif
314 } 294 }
315 295
316 void WebGraphicsContext3DCommandBufferImpl::postSubBufferCHROMIUM( 296 void WebGraphicsContext3DCommandBufferImpl::postSubBufferCHROMIUM(
317 int x, int y, int width, int height) { 297 int x, int y, int width, int height) {
318 // Same flow control as WebGraphicsContext3DCommandBufferImpl::prepareTexture 298 // Same flow control as WebGraphicsContext3DCommandBufferImpl::prepareTexture
319 // (see above). 299 // (see above).
320 RenderViewImpl* renderview = 300 if (swap_client_.get())
321 web_view_ ? RenderViewImpl::FromWebView(web_view_) : NULL; 301 swap_client_->OnViewContextSwapBuffersPosted();
322 if (renderview)
323 renderview->OnViewContextSwapBuffersPosted();
324 gl_->PostSubBufferCHROMIUM(x, y, width, height); 302 gl_->PostSubBufferCHROMIUM(x, y, width, height);
325 context_->Echo(base::Bind( 303 context_->Echo(base::Bind(
326 &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete, 304 &WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete,
327 weak_ptr_factory_.GetWeakPtr())); 305 weak_ptr_factory_.GetWeakPtr()));
328 } 306 }
329 307
330 void WebGraphicsContext3DCommandBufferImpl::reshape(int width, int height) { 308 void WebGraphicsContext3DCommandBufferImpl::reshape(int width, int height) {
331 cached_width_ = width; 309 cached_width_ = width;
332 cached_height_ = height; 310 cached_height_ = height;
333 311
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 1102
1125 void WebGraphicsContext3DCommandBufferImpl::deleteShader(WebGLId shader) { 1103 void WebGraphicsContext3DCommandBufferImpl::deleteShader(WebGLId shader) {
1126 gl_->DeleteShader(shader); 1104 gl_->DeleteShader(shader);
1127 } 1105 }
1128 1106
1129 void WebGraphicsContext3DCommandBufferImpl::deleteTexture(WebGLId texture) { 1107 void WebGraphicsContext3DCommandBufferImpl::deleteTexture(WebGLId texture) {
1130 gl_->DeleteTextures(1, &texture); 1108 gl_->DeleteTextures(1, &texture);
1131 } 1109 }
1132 1110
1133 void WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete() { 1111 void WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete() {
1112 typedef WebGraphicsContext3DSwapBuffersClient WGC3DSwapClient;
1134 // This may be called after tear-down of the RenderView. 1113 // This may be called after tear-down of the RenderView.
1135 RenderViewImpl* renderview = 1114 if (swap_client_.get()) {
1136 web_view_ ? RenderViewImpl::FromWebView(web_view_) : NULL; 1115 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
1137 if (renderview) { 1116 &WGC3DSwapClient::OnViewContextSwapBuffersComplete, swap_client_));
1138 MessageLoop::current()->PostTask(
1139 FROM_HERE,
1140 base::Bind(&RenderViewImpl::OnViewContextSwapBuffersComplete,
1141 renderview));
1142 } 1117 }
1143 1118
1144 if (swapbuffers_complete_callback_) 1119 if (swapbuffers_complete_callback_)
1145 swapbuffers_complete_callback_->onSwapBuffersComplete(); 1120 swapbuffers_complete_callback_->onSwapBuffersComplete();
1146 } 1121 }
1147 1122
1148 void WebGraphicsContext3DCommandBufferImpl::setContextLostCallback( 1123 void WebGraphicsContext3DCommandBufferImpl::setContextLostCallback(
1149 WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) { 1124 WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) {
1150 context_lost_callback_ = cb; 1125 context_lost_callback_ = cb;
1151 } 1126 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 } // anonymous namespace 1171 } // anonymous namespace
1197 1172
1198 void WebGraphicsContext3DCommandBufferImpl::OnContextLost( 1173 void WebGraphicsContext3DCommandBufferImpl::OnContextLost(
1199 RendererGLContext::ContextLostReason reason) { 1174 RendererGLContext::ContextLostReason reason) {
1200 context_lost_reason_ = convertReason(reason); 1175 context_lost_reason_ = convertReason(reason);
1201 if (context_lost_callback_) { 1176 if (context_lost_callback_) {
1202 context_lost_callback_->onContextLost(); 1177 context_lost_callback_->onContextLost();
1203 } 1178 }
1204 if (attributes_.shareResources) 1179 if (attributes_.shareResources)
1205 ClearSharedContexts(); 1180 ClearSharedContexts();
1206 RenderViewImpl* renderview = 1181 if (swap_client_.get())
1207 web_view_ ? RenderViewImpl::FromWebView(web_view_) : NULL; 1182 swap_client_->OnViewContextSwapBuffersAborted();
1208 if (renderview)
1209 renderview->OnViewContextSwapBuffersAborted();
1210 } 1183 }
1211
1212 #endif // defined(ENABLE_GPU)
OLDNEW
« no previous file with comments | « content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h ('k') | content/renderer/render_thread_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698