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

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: 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 | no next file » | 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_compositor_(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 ||
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_);
no sievers 2013/09/04 22:27:09 Does this also need to check if we actually have a
boliu 2013/09/04 23:05:57 Aha, yes, I did give this some thought. cc should
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 new VideoContextProvider(offscreen_context_for_main_thread_,
175 wrapped_gl_context_for_main_thread_); 180 wrapped_gl_context_for_main_thread_);
176 return make_scoped_ptr(new StreamTextureFactorySynchronousImpl( 181 return make_scoped_ptr(new StreamTextureFactorySynchronousImpl(
177 context_provider.get(), view_id)) 182 context_provider.get(), view_id))
178 .PassAs<StreamTextureFactory>(); 183 .PassAs<StreamTextureFactory>();
179 } 184 }
180 185
186 void CompositorInitializedHardwareDraw(SynchronousCompositorImpl* compositor);
187 void CompositorReleasedHardwareDraw(SynchronousCompositorImpl* compositor);
188
181 private: 189 private:
190 void ReleaseGlobalHardwareResources();
191 bool CanCreateMainThreadContext();
192
182 SynchronousInputEventFilter synchronous_input_event_filter_; 193 SynchronousInputEventFilter synchronous_input_event_filter_;
183 194
184 // Only guards construction of |offscreen_context_for_compositor_thread_|, 195 // Only guards construction and destruction of
185 // not usage. 196 // |offscreen_context_for_compositor_thread_|, not usage.
186 base::Lock offscreen_context_for_compositor_thread_creation_lock_; 197 base::Lock offscreen_context_for_compositor_thread_lock_;
187 scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_; 198 scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_;
188 // This is a pointer to the context owned by 199 // This is a pointer to the context owned by
189 // |offscreen_context_for_main_thread_|. 200 // |offscreen_context_for_main_thread_|.
190 gpu::GLInProcessContext* wrapped_gl_context_for_main_thread_; 201 gpu::GLInProcessContext* wrapped_gl_context_for_main_thread_;
191 scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_; 202 scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_;
203
204 base::Lock num_hardware_compositor_lock_;
205 unsigned int num_hardware_compositor_;
no sievers 2013/09/04 22:27:09 nit: num_hardware_compositors
boliu 2013/09/04 23:05:57 Done.
192 }; 206 };
193 207
208 void SynchronousCompositorFactoryImpl::CompositorInitializedHardwareDraw(
209 SynchronousCompositorImpl* compositor) {
210 base::AutoLock lock(num_hardware_compositor_lock_);
211 num_hardware_compositor_++;
212 }
213
214 void SynchronousCompositorFactoryImpl::CompositorReleasedHardwareDraw(
215 SynchronousCompositorImpl* compositor) {
216 bool should_release_resources = false;
217 {
218 base::AutoLock lock(num_hardware_compositor_lock_);
219 DCHECK_GT(num_hardware_compositor_, 0u);
220 num_hardware_compositor_--;
221 should_release_resources = num_hardware_compositor_ == 0u;
222 }
223 if (should_release_resources)
224 ReleaseGlobalHardwareResources();
225 }
226
227 void SynchronousCompositorFactoryImpl::ReleaseGlobalHardwareResources() {
228 {
229 base::AutoLock lock(offscreen_context_for_compositor_thread_lock_);
230 offscreen_context_for_compositor_thread_ = NULL;
231 }
232
233 // TODO(boliu): Properly clean up command buffer server of main thread
234 // context here.
235 }
236
237 bool SynchronousCompositorFactoryImpl::CanCreateMainThreadContext() {
238 base::AutoLock lock(num_hardware_compositor_lock_);
239 return num_hardware_compositor_ > 0;
240 }
241
194 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = 242 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
195 LAZY_INSTANCE_INITIALIZER; 243 LAZY_INSTANCE_INITIALIZER;
196 244
197 } // namespace 245 } // namespace
198 246
199 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); 247 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl);
200 248
201 // static 249 // static
202 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id, 250 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id,
203 int routing_id) { 251 int routing_id) {
(...skipping 30 matching lines...) Expand all
234 void SynchronousCompositorImpl::SetClient( 282 void SynchronousCompositorImpl::SetClient(
235 SynchronousCompositorClient* compositor_client) { 283 SynchronousCompositorClient* compositor_client) {
236 DCHECK(CalledOnValidThread()); 284 DCHECK(CalledOnValidThread());
237 compositor_client_ = compositor_client; 285 compositor_client_ = compositor_client;
238 } 286 }
239 287
240 bool SynchronousCompositorImpl::InitializeHwDraw( 288 bool SynchronousCompositorImpl::InitializeHwDraw(
241 scoped_refptr<gfx::GLSurface> surface) { 289 scoped_refptr<gfx::GLSurface> surface) {
242 DCHECK(CalledOnValidThread()); 290 DCHECK(CalledOnValidThread());
243 DCHECK(output_surface_); 291 DCHECK(output_surface_);
244 return output_surface_->InitializeHwDraw( 292 bool success = output_surface_->InitializeHwDraw(
245 surface, 293 surface,
246 g_factory.Get().GetOffscreenContextProviderForCompositorThread()); 294 g_factory.Get().GetOffscreenContextProviderForCompositorThread());
295 if (success)
296 g_factory.Get().CompositorInitializedHardwareDraw(this);
297 return success;
247 } 298 }
248 299
249 void SynchronousCompositorImpl::ReleaseHwDraw() { 300 void SynchronousCompositorImpl::ReleaseHwDraw() {
250 DCHECK(CalledOnValidThread()); 301 DCHECK(CalledOnValidThread());
251 DCHECK(output_surface_); 302 DCHECK(output_surface_);
252 return output_surface_->ReleaseHwDraw(); 303 output_surface_->ReleaseHwDraw();
304 g_factory.Get().CompositorReleasedHardwareDraw(this);
253 } 305 }
254 306
255 bool SynchronousCompositorImpl::DemandDrawHw( 307 bool SynchronousCompositorImpl::DemandDrawHw(
256 gfx::Size surface_size, 308 gfx::Size surface_size,
257 const gfx::Transform& transform, 309 const gfx::Transform& transform,
258 gfx::Rect viewport, 310 gfx::Rect viewport,
259 gfx::Rect clip, 311 gfx::Rect clip,
260 bool stencil_enabled) { 312 bool stencil_enabled) {
261 DCHECK(CalledOnValidThread()); 313 DCHECK(CalledOnValidThread());
262 DCHECK(output_surface_); 314 DCHECK(output_surface_);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 g_factory.Get(); // Ensure it's initialized. 435 g_factory.Get(); // Ensure it's initialized.
384 SynchronousCompositorImpl::CreateForWebContents(contents); 436 SynchronousCompositorImpl::CreateForWebContents(contents);
385 } 437 }
386 if (SynchronousCompositorImpl* instance = 438 if (SynchronousCompositorImpl* instance =
387 SynchronousCompositorImpl::FromWebContents(contents)) { 439 SynchronousCompositorImpl::FromWebContents(contents)) {
388 instance->SetClient(client); 440 instance->SetClient(client);
389 } 441 }
390 } 442 }
391 443
392 } // namespace content 444 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698