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

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: Do not fail video if cannot create context 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
« no previous file with comments | « no previous file | content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 if (!context.get()) 131 if (!context.get())
131 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(); 132 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>();
132 133
133 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>( 134 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(
134 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext( 135 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext(
135 context.Pass(), attributes)); 136 context.Pass(), attributes));
136 } 137 }
137 138
138 virtual scoped_refptr<cc::ContextProvider> 139 virtual scoped_refptr<cc::ContextProvider>
139 GetOffscreenContextProviderForMainThread() OVERRIDE { 140 GetOffscreenContextProviderForMainThread() OVERRIDE {
140 if (!offscreen_context_for_main_thread_.get() || 141 bool can_create_context = CanCreateMainThreadContext();
141 offscreen_context_for_main_thread_->DestroyedOnMainThread()) { 142 if (can_create_context &&
143 (!offscreen_context_for_main_thread_.get() ||
144 offscreen_context_for_main_thread_->DestroyedOnMainThread())) {
142 offscreen_context_for_main_thread_ = 145 offscreen_context_for_main_thread_ =
143 webkit::gpu::ContextProviderInProcess::Create( 146 webkit::gpu::ContextProviderInProcess::Create(
144 CreateOffscreenContext()); 147 CreateOffscreenContext());
145 if (offscreen_context_for_main_thread_.get() && 148 }
146 !offscreen_context_for_main_thread_->BindToCurrentThread()) { 149
147 offscreen_context_for_main_thread_ = NULL; 150 if (!can_create_context ||
joth 2013/09/05 20:47:12 splicing the can_create_context into both expressi
boliu 2013/09/05 23:21:25 Done.
148 wrapped_gl_context_for_main_thread_ = NULL; 151 (offscreen_context_for_main_thread_.get() &&
149 } 152 !offscreen_context_for_main_thread_->BindToCurrentThread())) {
153 offscreen_context_for_main_thread_ = NULL;
154 wrapped_gl_context_for_main_thread_ = NULL;
150 } 155 }
151 return offscreen_context_for_main_thread_; 156 return offscreen_context_for_main_thread_;
152 } 157 }
153 158
154 // This is called on both renderer main thread (offscreen context creation 159 // This is called on both renderer main thread (offscreen context creation
155 // path shared between cross-process and in-process platforms) and renderer 160 // path shared between cross-process and in-process platforms) and renderer
156 // compositor impl thread (InitializeHwDraw) in order to support Android 161 // compositor impl thread (InitializeHwDraw) in order to support Android
157 // WebView synchronously enable and disable hardware mode multiple times in 162 // WebView synchronously enable and disable hardware mode multiple times in
158 // the same task. This is ok because in-process WGC3D creation may happen on 163 // the same task. This is ok because in-process WGC3D creation may happen on
159 // any thread and is lightweight. 164 // any thread and is lightweight.
160 virtual scoped_refptr<cc::ContextProvider> 165 virtual scoped_refptr<cc::ContextProvider>
161 GetOffscreenContextProviderForCompositorThread() OVERRIDE { 166 GetOffscreenContextProviderForCompositorThread() OVERRIDE {
162 base::AutoLock lock(offscreen_context_for_compositor_thread_creation_lock_); 167 base::AutoLock lock(offscreen_context_for_compositor_thread_lock_);
163 if (!offscreen_context_for_compositor_thread_.get() || 168 if (!offscreen_context_for_compositor_thread_.get() ||
164 offscreen_context_for_compositor_thread_->DestroyedOnMainThread()) { 169 offscreen_context_for_compositor_thread_->DestroyedOnMainThread()) {
165 offscreen_context_for_compositor_thread_ = 170 offscreen_context_for_compositor_thread_ =
166 webkit::gpu::ContextProviderInProcess::CreateOffscreen(); 171 webkit::gpu::ContextProviderInProcess::CreateOffscreen();
167 } 172 }
168 return offscreen_context_for_compositor_thread_; 173 return offscreen_context_for_compositor_thread_;
169 } 174 }
170 175
171 virtual scoped_ptr<StreamTextureFactory> CreateStreamTextureFactory( 176 virtual scoped_ptr<StreamTextureFactory> CreateStreamTextureFactory(
172 int view_id) OVERRIDE { 177 int view_id) OVERRIDE {
173 scoped_refptr<VideoContextProvider> context_provider = 178 scoped_refptr<VideoContextProvider> context_provider;
174 new VideoContextProvider(offscreen_context_for_main_thread_, 179 if (CanCreateMainThreadContext()) {
175 wrapped_gl_context_for_main_thread_); 180 context_provider =
181 new VideoContextProvider(offscreen_context_for_main_thread_,
182 wrapped_gl_context_for_main_thread_);
183 }
176 return make_scoped_ptr(new StreamTextureFactorySynchronousImpl( 184 return make_scoped_ptr(new StreamTextureFactorySynchronousImpl(
177 context_provider.get(), view_id)) 185 context_provider.get(), view_id))
178 .PassAs<StreamTextureFactory>(); 186 .PassAs<StreamTextureFactory>();
179 } 187 }
180 188
189 void CompositorInitializedHardwareDraw(SynchronousCompositorImpl* compositor);
190 void CompositorReleasedHardwareDraw(SynchronousCompositorImpl* compositor);
191
181 private: 192 private:
193 void ReleaseGlobalHardwareResources();
194 bool CanCreateMainThreadContext();
195
182 SynchronousInputEventFilter synchronous_input_event_filter_; 196 SynchronousInputEventFilter synchronous_input_event_filter_;
183 197
184 // Only guards construction of |offscreen_context_for_compositor_thread_|, 198 // Only guards construction and destruction of
185 // not usage. 199 // |offscreen_context_for_compositor_thread_|, not usage.
186 base::Lock offscreen_context_for_compositor_thread_creation_lock_; 200 base::Lock offscreen_context_for_compositor_thread_lock_;
187 scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_; 201 scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_;
188 // This is a pointer to the context owned by 202 // This is a pointer to the context owned by
189 // |offscreen_context_for_main_thread_|. 203 // |offscreen_context_for_main_thread_|.
190 gpu::GLInProcessContext* wrapped_gl_context_for_main_thread_; 204 gpu::GLInProcessContext* wrapped_gl_context_for_main_thread_;
191 scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_; 205 scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_;
206
207 base::Lock num_hardware_compositor_lock_;
joth 2013/09/05 20:47:12 comment that num_hardware_compositors_ is always u
boliu 2013/09/05 23:21:25 Both done
208 unsigned int num_hardware_compositors_;
192 }; 209 };
193 210
211 void SynchronousCompositorFactoryImpl::CompositorInitializedHardwareDraw(
212 SynchronousCompositorImpl* compositor) {
213 base::AutoLock lock(num_hardware_compositor_lock_);
214 num_hardware_compositors_++;
215 }
216
217 void SynchronousCompositorFactoryImpl::CompositorReleasedHardwareDraw(
218 SynchronousCompositorImpl* compositor) {
219 bool should_release_resources = false;
220 {
221 base::AutoLock lock(num_hardware_compositor_lock_);
222 DCHECK_GT(num_hardware_compositors_, 0u);
223 num_hardware_compositors_--;
224 should_release_resources = num_hardware_compositors_ == 0u;
225 }
226 if (should_release_resources)
227 ReleaseGlobalHardwareResources();
228 }
229
230 void SynchronousCompositorFactoryImpl::ReleaseGlobalHardwareResources() {
231 {
232 base::AutoLock lock(offscreen_context_for_compositor_thread_lock_);
233 offscreen_context_for_compositor_thread_ = NULL;
234 }
235
236 // TODO(boliu): Properly clean up command buffer server of main thread
237 // context here.
238 }
239
240 bool SynchronousCompositorFactoryImpl::CanCreateMainThreadContext() {
241 base::AutoLock lock(num_hardware_compositor_lock_);
242 return num_hardware_compositors_ > 0;
243 }
244
194 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = 245 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
195 LAZY_INSTANCE_INITIALIZER; 246 LAZY_INSTANCE_INITIALIZER;
196 247
197 } // namespace 248 } // namespace
198 249
199 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); 250 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl);
200 251
201 // static 252 // static
202 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id, 253 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id,
203 int routing_id) { 254 int routing_id) {
(...skipping 30 matching lines...) Expand all
234 void SynchronousCompositorImpl::SetClient( 285 void SynchronousCompositorImpl::SetClient(
235 SynchronousCompositorClient* compositor_client) { 286 SynchronousCompositorClient* compositor_client) {
236 DCHECK(CalledOnValidThread()); 287 DCHECK(CalledOnValidThread());
237 compositor_client_ = compositor_client; 288 compositor_client_ = compositor_client;
238 } 289 }
239 290
240 bool SynchronousCompositorImpl::InitializeHwDraw( 291 bool SynchronousCompositorImpl::InitializeHwDraw(
241 scoped_refptr<gfx::GLSurface> surface) { 292 scoped_refptr<gfx::GLSurface> surface) {
242 DCHECK(CalledOnValidThread()); 293 DCHECK(CalledOnValidThread());
243 DCHECK(output_surface_); 294 DCHECK(output_surface_);
244 return output_surface_->InitializeHwDraw( 295 bool success = output_surface_->InitializeHwDraw(
245 surface, 296 surface,
246 g_factory.Get().GetOffscreenContextProviderForCompositorThread()); 297 g_factory.Get().GetOffscreenContextProviderForCompositorThread());
298 if (success)
299 g_factory.Get().CompositorInitializedHardwareDraw(this);
300 return success;
247 } 301 }
248 302
249 void SynchronousCompositorImpl::ReleaseHwDraw() { 303 void SynchronousCompositorImpl::ReleaseHwDraw() {
250 DCHECK(CalledOnValidThread()); 304 DCHECK(CalledOnValidThread());
251 DCHECK(output_surface_); 305 DCHECK(output_surface_);
252 return output_surface_->ReleaseHwDraw(); 306 output_surface_->ReleaseHwDraw();
307 g_factory.Get().CompositorReleasedHardwareDraw(this);
253 } 308 }
254 309
255 bool SynchronousCompositorImpl::DemandDrawHw( 310 bool SynchronousCompositorImpl::DemandDrawHw(
256 gfx::Size view_size, 311 gfx::Size view_size,
257 const gfx::Transform& transform, 312 const gfx::Transform& transform,
258 gfx::Rect damage_area, 313 gfx::Rect damage_area,
259 bool stencil_enabled) { 314 bool stencil_enabled) {
260 DCHECK(CalledOnValidThread()); 315 DCHECK(CalledOnValidThread());
261 DCHECK(output_surface_); 316 DCHECK(output_surface_);
262 317
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 g_factory.Get(); // Ensure it's initialized. 429 g_factory.Get(); // Ensure it's initialized.
375 SynchronousCompositorImpl::CreateForWebContents(contents); 430 SynchronousCompositorImpl::CreateForWebContents(contents);
376 } 431 }
377 if (SynchronousCompositorImpl* instance = 432 if (SynchronousCompositorImpl* instance =
378 SynchronousCompositorImpl::FromWebContents(contents)) { 433 SynchronousCompositorImpl::FromWebContents(contents)) {
379 instance->SetClient(client); 434 instance->SetClient(client);
380 } 435 }
381 } 436 }
382 437
383 } // namespace content 438 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698