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

Side by Side Diff: content/browser/renderer_host/compositor_impl_android.cc

Issue 903933005: Android: Fix GPU recovery issues (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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
« no previous file with comments | « content/browser/renderer_host/compositor_impl_android.h ('k') | 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 (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 #include "content/browser/renderer_host/compositor_impl_android.h" 5 #include "content/browser/renderer_host/compositor_impl_android.h"
6 6
7 #include <android/bitmap.h> 7 #include <android/bitmap.h>
8 #include <android/native_window_jni.h> 8 #include <android/native_window_jni.h>
9 9
10 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 surface_id_(0), 174 surface_id_(0),
175 client_(client), 175 client_(client),
176 root_window_(root_window), 176 root_window_(root_window),
177 did_post_swapbuffers_(false), 177 did_post_swapbuffers_(false),
178 ignore_schedule_composite_(false), 178 ignore_schedule_composite_(false),
179 needs_composite_(false), 179 needs_composite_(false),
180 needs_animate_(false), 180 needs_animate_(false),
181 will_composite_immediately_(false), 181 will_composite_immediately_(false),
182 composite_on_vsync_trigger_(DO_NOT_COMPOSITE), 182 composite_on_vsync_trigger_(DO_NOT_COMPOSITE),
183 pending_swapbuffers_(0U), 183 pending_swapbuffers_(0U),
184 defer_composite_for_gpu_channel_(false), 184 num_successive_context_creation_failures_(0),
185 weak_factory_(this) { 185 weak_factory_(this) {
186 DCHECK(client); 186 DCHECK(client);
187 DCHECK(root_window); 187 DCHECK(root_window);
188 root_window->AttachCompositor(this); 188 root_window->AttachCompositor(this);
189 } 189 }
190 190
191 CompositorImpl::~CompositorImpl() { 191 CompositorImpl::~CompositorImpl() {
192 root_window_->DetachCompositor(); 192 root_window_->DetachCompositor();
193 // Clean-up any surface references. 193 // Clean-up any surface references.
194 SetSurface(NULL); 194 SetSurface(NULL);
195 } 195 }
196 196
197 void CompositorImpl::PostComposite(CompositingTrigger trigger) { 197 void CompositorImpl::PostComposite(CompositingTrigger trigger) {
198 DCHECK(needs_composite_); 198 DCHECK(needs_composite_);
199 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); 199 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY);
200 200
201 if (defer_composite_for_gpu_channel_ || will_composite_immediately_ || 201 if (will_composite_immediately_ ||
202 (trigger == COMPOSITE_EVENTUALLY && WillComposite())) { 202 (trigger == COMPOSITE_EVENTUALLY && WillComposite())) {
203 // We will already composite soon enough. 203 // We will already composite soon enough.
204 DCHECK(WillComposite()); 204 DCHECK(WillComposite());
205 return; 205 return;
206 } 206 }
207 207
208 if (DidCompositeThisFrame()) { 208 if (DidCompositeThisFrame()) {
209 DCHECK(!WillCompositeThisFrame()); 209 DCHECK(!WillCompositeThisFrame());
210 if (composite_on_vsync_trigger_ != COMPOSITE_IMMEDIATELY) { 210 if (composite_on_vsync_trigger_ != COMPOSITE_IMMEDIATELY) {
211 composite_on_vsync_trigger_ = trigger; 211 composite_on_vsync_trigger_ = trigger;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 if (current_composite_task_) 247 if (current_composite_task_)
248 current_composite_task_->Cancel(); 248 current_composite_task_->Cancel();
249 249
250 // Unretained because we cancel the task on shutdown. 250 // Unretained because we cancel the task on shutdown.
251 current_composite_task_.reset(new base::CancelableClosure( 251 current_composite_task_.reset(new base::CancelableClosure(
252 base::Bind(&CompositorImpl::Composite, base::Unretained(this), trigger))); 252 base::Bind(&CompositorImpl::Composite, base::Unretained(this), trigger)));
253 base::MessageLoop::current()->PostDelayedTask( 253 base::MessageLoop::current()->PostDelayedTask(
254 FROM_HERE, current_composite_task_->callback(), delay); 254 FROM_HERE, current_composite_task_->callback(), delay);
255 } 255 }
256 256
257 void CompositorImpl::OnGpuChannelEstablished() {
258 defer_composite_for_gpu_channel_ = false;
259
260 if (host_)
261 PostComposite(COMPOSITE_IMMEDIATELY);
262 }
263
264 void CompositorImpl::Composite(CompositingTrigger trigger) { 257 void CompositorImpl::Composite(CompositingTrigger trigger) {
265 if (trigger == COMPOSITE_IMMEDIATELY) 258 if (trigger == COMPOSITE_IMMEDIATELY)
266 will_composite_immediately_ = false; 259 will_composite_immediately_ = false;
267 260
268 BrowserGpuChannelHostFactory* factory =
269 BrowserGpuChannelHostFactory::instance();
270 if (!factory->GetGpuChannel() || factory->GetGpuChannel()->IsLost()) {
271 CauseForGpuLaunch cause =
272 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
273 factory->EstablishGpuChannel(
274 cause, base::Bind(&CompositorImpl::OnGpuChannelEstablished,
275 weak_factory_.GetWeakPtr()));
276 DCHECK(!defer_composite_for_gpu_channel_);
277 defer_composite_for_gpu_channel_ = true;
278 current_composite_task_.reset();
279 return;
280 }
281
282 DCHECK(host_); 261 DCHECK(host_);
283 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY); 262 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY);
284 DCHECK(needs_composite_); 263 DCHECK(needs_composite_);
285 DCHECK(!DidCompositeThisFrame()); 264 DCHECK(!DidCompositeThisFrame());
286 265
287 DCHECK_LE(pending_swapbuffers_, kMaxSwapBuffers); 266 DCHECK_LE(pending_swapbuffers_, kMaxSwapBuffers);
288 if (pending_swapbuffers_ == kMaxSwapBuffers) { 267 // Swap Ack accounting is unreliable if the OutputSurface was lost.
268 // In that case still attempt to composite, which will cause creation of a
269 // new OutputSurface and reset pending_swapbuffers_.
270 if (pending_swapbuffers_ == kMaxSwapBuffers &&
271 !host_->output_surface_lost()) {
289 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit"); 272 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit");
290 return; 273 return;
291 } 274 }
292 275
293 // Reset state before Layout+Composite since that might create more 276 // Reset state before Layout+Composite since that might create more
294 // requests to Composite that we need to respect. 277 // requests to Composite that we need to respect.
295 needs_composite_ = false; 278 needs_composite_ = false;
296 279
297 // Only allow compositing once per vsync. 280 // Only allow compositing once per vsync.
298 current_composite_task_->Cancel(); 281 current_composite_task_->Cancel();
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 SetWindowSurface(window); 365 SetWindowSurface(window);
383 ANativeWindow_release(window); 366 ANativeWindow_release(window);
384 RegisterViewSurface(surface_id_, j_surface.obj()); 367 RegisterViewSurface(surface_id_, j_surface.obj());
385 } 368 }
386 } 369 }
387 370
388 void CompositorImpl::CreateLayerTreeHost() { 371 void CompositorImpl::CreateLayerTreeHost() {
389 DCHECK(!host_); 372 DCHECK(!host_);
390 DCHECK(!WillCompositeThisFrame()); 373 DCHECK(!WillCompositeThisFrame());
391 needs_composite_ = false; 374 needs_composite_ = false;
392 defer_composite_for_gpu_channel_ = false;
393 pending_swapbuffers_ = 0; 375 pending_swapbuffers_ = 0;
394 cc::LayerTreeSettings settings; 376 cc::LayerTreeSettings settings;
395 settings.renderer_settings.refresh_rate = 60.0; 377 settings.renderer_settings.refresh_rate = 60.0;
396 settings.renderer_settings.allow_antialiasing = false; 378 settings.renderer_settings.allow_antialiasing = false;
397 settings.renderer_settings.highp_threshold_min = 2048; 379 settings.renderer_settings.highp_threshold_min = 2048;
398 settings.impl_side_painting = false; 380 settings.impl_side_painting = false;
399 settings.calculate_top_controls_position = false; 381 settings.calculate_top_controls_position = false;
400 382
401 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 383 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
402 settings.initial_debug_state.SetRecordRenderingStats( 384 settings.initial_debug_state.SetRecordRenderingStats(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 } 422 }
441 if (readback_pending) { 423 if (readback_pending) {
442 ignore_schedule_composite_ = true; 424 ignore_schedule_composite_ = true;
443 host_->Composite(base::TimeTicks::Now()); 425 host_->Composite(base::TimeTicks::Now());
444 ignore_schedule_composite_ = false; 426 ignore_schedule_composite_ = false;
445 } 427 }
446 if (WillComposite()) 428 if (WillComposite())
447 CancelComposite(); 429 CancelComposite();
448 ui_resource_provider_.SetLayerTreeHost(NULL); 430 ui_resource_provider_.SetLayerTreeHost(NULL);
449 host_.reset(); 431 host_.reset();
432 output_surface_task_for_host_.reset();
450 display_client_.reset(); 433 display_client_.reset();
451 if (current_composite_task_) { 434 if (current_composite_task_) {
452 current_composite_task_->Cancel(); 435 current_composite_task_->Cancel();
453 current_composite_task_.reset(); 436 current_composite_task_.reset();
454 } 437 }
455 } else if (!host_) { 438 } else if (!host_) {
456 CreateLayerTreeHost(); 439 CreateLayerTreeHost();
457 ui_resource_provider_.SetLayerTreeHost(host_.get()); 440 ui_resource_provider_.SetLayerTreeHost(host_.get());
458 } 441 }
459 } 442 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 NULL)); 506 NULL));
524 } 507 }
525 508
526 void CompositorImpl::Layout() { 509 void CompositorImpl::Layout() {
527 ignore_schedule_composite_ = true; 510 ignore_schedule_composite_ = true;
528 client_->Layout(); 511 client_->Layout();
529 ignore_schedule_composite_ = false; 512 ignore_schedule_composite_ = false;
530 } 513 }
531 514
532 void CompositorImpl::RequestNewOutputSurface() { 515 void CompositorImpl::RequestNewOutputSurface() {
533 // SetVisible(false) can happen (destroying the host_) between when this
534 // function is posted and when it is handled. An output surface will get
535 // re-requested when the host is recreated.
536 if (!host_.get())
537 return;
538
539 BrowserGpuChannelHostFactory* factory = 516 BrowserGpuChannelHostFactory* factory =
540 BrowserGpuChannelHostFactory::instance(); 517 BrowserGpuChannelHostFactory::instance();
541 if (!factory->GetGpuChannel() || factory->GetGpuChannel()->IsLost()) { 518 if (!factory->GetGpuChannel() || factory->GetGpuChannel()->IsLost()) {
542 CauseForGpuLaunch cause = 519 CauseForGpuLaunch cause =
543 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE; 520 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
544 factory->EstablishGpuChannel( 521 output_surface_task_for_host_.reset(new base::CancelableClosure(base::Bind(
545 cause, 522 &CompositorImpl::CreateOutputSurface, base::Unretained(this))));
546 base::Bind(&CompositorImpl::CreateOutputSurface, 523 factory->EstablishGpuChannel(cause,
547 weak_factory_.GetWeakPtr())); 524 output_surface_task_for_host_->callback());
548 return; 525 return;
549 } 526 }
550 527
551 CreateOutputSurface(); 528 CreateOutputSurface();
552 } 529 }
553 530
531 void CompositorImpl::DidInitializeOutputSurface() {
532 num_successive_context_creation_failures_ = 0;
533 }
534
554 void CompositorImpl::DidFailToInitializeOutputSurface() { 535 void CompositorImpl::DidFailToInitializeOutputSurface() {
555 RequestNewOutputSurface(); 536 RequestNewOutputSurface();
537 LOG(ERROR) << "Failed to init OutputSurface for compositor.";
538 LOG_IF(FATAL, ++num_successive_context_creation_failures_ >= 3)
539 << "Too many context creation failures. Giving up... ";
556 } 540 }
557 541
558 void CompositorImpl::CreateOutputSurface() { 542 void CompositorImpl::CreateOutputSurface() {
559 // This function will get called again when the compositor becomes visible.
560 if (!host_.get())
561 return;
562
563 blink::WebGraphicsContext3D::Attributes attrs; 543 blink::WebGraphicsContext3D::Attributes attrs;
564 attrs.shareResources = true; 544 attrs.shareResources = true;
565 attrs.noAutomaticFlushes = true; 545 attrs.noAutomaticFlushes = true;
566 pending_swapbuffers_ = 0; 546 pending_swapbuffers_ = 0;
567 547
568 DCHECK(window_); 548 DCHECK(window_);
569 DCHECK(surface_id_); 549 DCHECK(surface_id_);
570 550
571 scoped_refptr<ContextProviderCommandBuffer> context_provider; 551 scoped_refptr<ContextProviderCommandBuffer> context_provider;
572 BrowserGpuChannelHostFactory* factory = 552 BrowserGpuChannelHostFactory* factory =
573 BrowserGpuChannelHostFactory::instance(); 553 BrowserGpuChannelHostFactory::instance();
574 scoped_refptr<GpuChannelHost> gpu_channel_host = factory->GetGpuChannel(); 554 scoped_refptr<GpuChannelHost> gpu_channel_host = factory->GetGpuChannel();
575 if (gpu_channel_host.get() && !gpu_channel_host->IsLost()) { 555 if (gpu_channel_host.get() && !gpu_channel_host->IsLost()) {
576 context_provider = ContextProviderCommandBuffer::Create( 556 context_provider = ContextProviderCommandBuffer::Create(
577 CreateGpuProcessViewContext(gpu_channel_host, attrs, surface_id_), 557 CreateGpuProcessViewContext(gpu_channel_host, attrs, surface_id_),
578 "BrowserCompositor"); 558 "BrowserCompositor");
579 } 559 }
580 if (!context_provider.get()) { 560 if (!context_provider.get()) {
581 LOG(ERROR) << "Failed to create 3D context for compositor."; 561 LOG(ERROR) << "Failed to create 3D context for compositor.";
562 LOG_IF(FATAL, ++num_successive_context_creation_failures_ >= 3)
563 << "Too many context creation failures. Giving up... ";
564 output_surface_task_for_host_.reset(new base::CancelableClosure(base::Bind(
565 &CompositorImpl::RequestNewOutputSurface, base::Unretained(this))));
582 base::MessageLoopProxy::current()->PostTask( 566 base::MessageLoopProxy::current()->PostTask(
583 FROM_HERE, base::Bind(&CompositorImpl::RequestNewOutputSurface, 567 FROM_HERE, output_surface_task_for_host_->callback());
584 weak_factory_.GetWeakPtr()));
585 return; 568 return;
586 } 569 }
587 570
588 scoped_ptr<cc::OutputSurface> real_output_surface( 571 scoped_ptr<cc::OutputSurface> real_output_surface(
589 new OutputSurfaceWithoutParent(context_provider, 572 new OutputSurfaceWithoutParent(context_provider,
590 weak_factory_.GetWeakPtr())); 573 weak_factory_.GetWeakPtr()));
591 574
592 cc::SurfaceManager* manager = GetSurfaceManager(); 575 cc::SurfaceManager* manager = GetSurfaceManager();
593 if (manager) { 576 if (manager) {
594 display_client_.reset(new cc::OnscreenDisplayClient( 577 display_client_.reset(new cc::OnscreenDisplayClient(
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 682
700 void CompositorImpl::SetNeedsAnimate() { 683 void CompositorImpl::SetNeedsAnimate() {
701 needs_animate_ = true; 684 needs_animate_ = true;
702 if (!host_) 685 if (!host_)
703 return; 686 return;
704 687
705 host_->SetNeedsAnimate(); 688 host_->SetNeedsAnimate();
706 } 689 }
707 690
708 } // namespace content 691 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/compositor_impl_android.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698