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

Side by Side Diff: content/browser/android/in_process/synchronous_compositor_impl.cc

Issue 23618031: [Android WebView] Clean up global GL resource pt.1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address joth's comments Created 7 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 #include "content/browser/android/in_process/synchronous_compositor_impl.h" 5 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
6 6
7 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/synchronization/lock.h" 9 #include "base/synchronization/lock.h"
10 #include "cc/input/input_handler.h" 10 #include "cc/input/input_handler.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 69
70 scoped_refptr<cc::ContextProvider> context_provider_; 70 scoped_refptr<cc::ContextProvider> context_provider_;
71 gpu::GLInProcessContext* gl_in_process_context_; 71 gpu::GLInProcessContext* gl_in_process_context_;
72 72
73 DISALLOW_COPY_AND_ASSIGN(VideoContextProvider); 73 DISALLOW_COPY_AND_ASSIGN(VideoContextProvider);
74 }; 74 };
75 75
76 class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { 76 class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
77 public: 77 public:
78 SynchronousCompositorFactoryImpl() 78 SynchronousCompositorFactoryImpl()
79 : wrapped_gl_context_for_main_thread_(NULL) { 79 : wrapped_gl_context_for_main_thread_(NULL),
80 num_hardware_compositors_(0) {
80 SynchronousCompositorFactory::SetInstance(this); 81 SynchronousCompositorFactory::SetInstance(this);
81 } 82 }
82 83
83 // SynchronousCompositorFactory 84 // SynchronousCompositorFactory
84 virtual scoped_refptr<base::MessageLoopProxy> 85 virtual scoped_refptr<base::MessageLoopProxy>
85 GetCompositorMessageLoop() OVERRIDE { 86 GetCompositorMessageLoop() OVERRIDE {
86 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); 87 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
87 } 88 }
88 89
89 virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface( 90 virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 if (!context.get()) 129 if (!context.get())
129 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(); 130 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>();
130 131
131 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>( 132 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(
132 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext( 133 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext(
133 context.Pass(), attributes)); 134 context.Pass(), attributes));
134 } 135 }
135 136
136 virtual scoped_refptr<cc::ContextProvider> 137 virtual scoped_refptr<cc::ContextProvider>
137 GetOffscreenContextProviderForMainThread() OVERRIDE { 138 GetOffscreenContextProviderForMainThread() OVERRIDE {
138 if (!offscreen_context_for_main_thread_.get() || 139 // This check only guarantees the main thread context is created after
139 offscreen_context_for_main_thread_->DestroyedOnMainThread()) { 140 // a compositor did successfully initialize hardware draw in the past.
141 // In particular this does not guarantee that the main thread context
142 // will fail creation when all compositors release hardware draw.
143 bool failed = !CanCreateMainThreadContext();
144 if (!failed &&
145 (!offscreen_context_for_main_thread_.get() ||
146 offscreen_context_for_main_thread_->DestroyedOnMainThread())) {
140 offscreen_context_for_main_thread_ = 147 offscreen_context_for_main_thread_ =
141 webkit::gpu::ContextProviderInProcess::Create( 148 webkit::gpu::ContextProviderInProcess::Create(
142 CreateOffscreenContext()); 149 CreateOffscreenContext());
143 if (offscreen_context_for_main_thread_.get() && 150 failed = !offscreen_context_for_main_thread_.get() ||
144 !offscreen_context_for_main_thread_->BindToCurrentThread()) { 151 !offscreen_context_for_main_thread_->BindToCurrentThread();
145 offscreen_context_for_main_thread_ = NULL; 152 }
146 wrapped_gl_context_for_main_thread_ = NULL; 153
147 } 154 if (failed) {
155 offscreen_context_for_main_thread_ = NULL;
156 wrapped_gl_context_for_main_thread_ = NULL;
148 } 157 }
149 return offscreen_context_for_main_thread_; 158 return offscreen_context_for_main_thread_;
150 } 159 }
151 160
152 // This is called on both renderer main thread (offscreen context creation 161 // This is called on both renderer main thread (offscreen context creation
153 // path shared between cross-process and in-process platforms) and renderer 162 // path shared between cross-process and in-process platforms) and renderer
154 // compositor impl thread (InitializeHwDraw) in order to support Android 163 // compositor impl thread (InitializeHwDraw) in order to support Android
155 // WebView synchronously enable and disable hardware mode multiple times in 164 // WebView synchronously enable and disable hardware mode multiple times in
156 // the same task. This is ok because in-process WGC3D creation may happen on 165 // the same task. This is ok because in-process WGC3D creation may happen on
157 // any thread and is lightweight. 166 // any thread and is lightweight.
158 virtual scoped_refptr<cc::ContextProvider> 167 virtual scoped_refptr<cc::ContextProvider>
159 GetOffscreenContextProviderForCompositorThread() OVERRIDE { 168 GetOffscreenContextProviderForCompositorThread() OVERRIDE {
160 base::AutoLock lock(offscreen_context_for_compositor_thread_creation_lock_); 169 base::AutoLock lock(offscreen_context_for_compositor_thread_lock_);
161 if (!offscreen_context_for_compositor_thread_.get() || 170 if (!offscreen_context_for_compositor_thread_.get() ||
162 offscreen_context_for_compositor_thread_->DestroyedOnMainThread()) { 171 offscreen_context_for_compositor_thread_->DestroyedOnMainThread()) {
163 offscreen_context_for_compositor_thread_ = 172 offscreen_context_for_compositor_thread_ =
164 webkit::gpu::ContextProviderInProcess::CreateOffscreen(); 173 webkit::gpu::ContextProviderInProcess::CreateOffscreen();
165 } 174 }
166 return offscreen_context_for_compositor_thread_; 175 return offscreen_context_for_compositor_thread_;
167 } 176 }
168 177
169 virtual scoped_ptr<StreamTextureFactory> CreateStreamTextureFactory( 178 virtual scoped_ptr<StreamTextureFactory> CreateStreamTextureFactory(
170 int view_id) OVERRIDE { 179 int view_id) OVERRIDE {
171 scoped_refptr<VideoContextProvider> context_provider = 180 scoped_refptr<VideoContextProvider> context_provider;
172 new VideoContextProvider(offscreen_context_for_main_thread_, 181 if (CanCreateMainThreadContext()) {
173 wrapped_gl_context_for_main_thread_); 182 context_provider =
183 new VideoContextProvider(offscreen_context_for_main_thread_,
184 wrapped_gl_context_for_main_thread_);
185 }
174 return make_scoped_ptr(new StreamTextureFactorySynchronousImpl( 186 return make_scoped_ptr(new StreamTextureFactorySynchronousImpl(
175 context_provider.get(), view_id)) 187 context_provider.get(), view_id))
176 .PassAs<StreamTextureFactory>(); 188 .PassAs<StreamTextureFactory>();
177 } 189 }
178 190
191 void CompositorInitializedHardwareDraw(SynchronousCompositorImpl* compositor);
192 void CompositorReleasedHardwareDraw(SynchronousCompositorImpl* compositor);
193
179 private: 194 private:
195 void ReleaseGlobalHardwareResources();
196 bool CanCreateMainThreadContext();
197
180 SynchronousInputEventFilter synchronous_input_event_filter_; 198 SynchronousInputEventFilter synchronous_input_event_filter_;
181 199
182 // Only guards construction of |offscreen_context_for_compositor_thread_|, 200 // Only guards construction and destruction of
183 // not usage. 201 // |offscreen_context_for_compositor_thread_|, not usage.
184 base::Lock offscreen_context_for_compositor_thread_creation_lock_; 202 base::Lock offscreen_context_for_compositor_thread_lock_;
185 scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_; 203 scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_;
186 // This is a pointer to the context owned by 204 // This is a pointer to the context owned by
187 // |offscreen_context_for_main_thread_|. 205 // |offscreen_context_for_main_thread_|.
188 gpu::GLInProcessContext* wrapped_gl_context_for_main_thread_; 206 gpu::GLInProcessContext* wrapped_gl_context_for_main_thread_;
189 scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_; 207 scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_;
208
209 // |num_hardware_compositor_lock_| is updated on UI thread only but can be
210 // read on renderer main thread.
211 base::Lock num_hardware_compositor_lock_;
212 unsigned int num_hardware_compositors_;
190 }; 213 };
191 214
215 void SynchronousCompositorFactoryImpl::CompositorInitializedHardwareDraw(
216 SynchronousCompositorImpl* compositor) {
217 base::AutoLock lock(num_hardware_compositor_lock_);
218 num_hardware_compositors_++;
219 }
220
221 void SynchronousCompositorFactoryImpl::CompositorReleasedHardwareDraw(
222 SynchronousCompositorImpl* compositor) {
223 bool should_release_resources = false;
224 {
225 base::AutoLock lock(num_hardware_compositor_lock_);
226 DCHECK_GT(num_hardware_compositors_, 0u);
227 num_hardware_compositors_--;
228 should_release_resources = num_hardware_compositors_ == 0u;
229 }
230 if (should_release_resources)
231 ReleaseGlobalHardwareResources();
232 }
233
234 void SynchronousCompositorFactoryImpl::ReleaseGlobalHardwareResources() {
235 {
236 base::AutoLock lock(offscreen_context_for_compositor_thread_lock_);
237 offscreen_context_for_compositor_thread_ = NULL;
238 }
239
240 // TODO(boliu): Properly clean up command buffer server of main thread
241 // context here.
242 }
243
244 bool SynchronousCompositorFactoryImpl::CanCreateMainThreadContext() {
245 base::AutoLock lock(num_hardware_compositor_lock_);
246 return num_hardware_compositors_ > 0;
247 }
248
192 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = 249 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
193 LAZY_INSTANCE_INITIALIZER; 250 LAZY_INSTANCE_INITIALIZER;
194 251
195 } // namespace 252 } // namespace
196 253
197 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); 254 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl);
198 255
199 // static 256 // static
200 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id, 257 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id,
201 int routing_id) { 258 int routing_id) {
(...skipping 30 matching lines...) Expand all
232 void SynchronousCompositorImpl::SetClient( 289 void SynchronousCompositorImpl::SetClient(
233 SynchronousCompositorClient* compositor_client) { 290 SynchronousCompositorClient* compositor_client) {
234 DCHECK(CalledOnValidThread()); 291 DCHECK(CalledOnValidThread());
235 compositor_client_ = compositor_client; 292 compositor_client_ = compositor_client;
236 } 293 }
237 294
238 bool SynchronousCompositorImpl::InitializeHwDraw( 295 bool SynchronousCompositorImpl::InitializeHwDraw(
239 scoped_refptr<gfx::GLSurface> surface) { 296 scoped_refptr<gfx::GLSurface> surface) {
240 DCHECK(CalledOnValidThread()); 297 DCHECK(CalledOnValidThread());
241 DCHECK(output_surface_); 298 DCHECK(output_surface_);
242 return output_surface_->InitializeHwDraw( 299 bool success = output_surface_->InitializeHwDraw(
243 surface, 300 surface,
244 g_factory.Get().GetOffscreenContextProviderForCompositorThread()); 301 g_factory.Get().GetOffscreenContextProviderForCompositorThread());
302 if (success)
303 g_factory.Get().CompositorInitializedHardwareDraw(this);
304 return success;
245 } 305 }
246 306
247 void SynchronousCompositorImpl::ReleaseHwDraw() { 307 void SynchronousCompositorImpl::ReleaseHwDraw() {
248 DCHECK(CalledOnValidThread()); 308 DCHECK(CalledOnValidThread());
249 DCHECK(output_surface_); 309 DCHECK(output_surface_);
250 return output_surface_->ReleaseHwDraw(); 310 output_surface_->ReleaseHwDraw();
311 g_factory.Get().CompositorReleasedHardwareDraw(this);
251 } 312 }
252 313
253 bool SynchronousCompositorImpl::DemandDrawHw( 314 bool SynchronousCompositorImpl::DemandDrawHw(
254 gfx::Size surface_size, 315 gfx::Size surface_size,
255 const gfx::Transform& transform, 316 const gfx::Transform& transform,
256 gfx::Rect viewport, 317 gfx::Rect viewport,
257 gfx::Rect clip, 318 gfx::Rect clip,
258 bool stencil_enabled) { 319 bool stencil_enabled) {
259 DCHECK(CalledOnValidThread()); 320 DCHECK(CalledOnValidThread());
260 DCHECK(output_surface_); 321 DCHECK(output_surface_);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 g_factory.Get(); // Ensure it's initialized. 434 g_factory.Get(); // Ensure it's initialized.
374 SynchronousCompositorImpl::CreateForWebContents(contents); 435 SynchronousCompositorImpl::CreateForWebContents(contents);
375 } 436 }
376 if (SynchronousCompositorImpl* instance = 437 if (SynchronousCompositorImpl* instance =
377 SynchronousCompositorImpl::FromWebContents(contents)) { 438 SynchronousCompositorImpl::FromWebContents(contents)) {
378 instance->SetClient(client); 439 instance->SetClient(client);
379 } 440 }
380 } 441 }
381 442
382 } // namespace content 443 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698