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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp

Issue 2123623002: Reland: Make 2D canvas disable gpu acceleration when getImageData is called (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix tests Created 4 years, 5 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 else 164 else
165 accelerate = hint == PreferAcceleration || hint == PreferAccelerationAft erVisibilityChange; 165 accelerate = hint == PreferAcceleration || hint == PreferAccelerationAft erVisibilityChange;
166 166
167 if (accelerate && (!m_contextProvider || m_contextProvider->contextGL()->Get GraphicsResetStatusKHR() != GL_NO_ERROR)) 167 if (accelerate && (!m_contextProvider || m_contextProvider->contextGL()->Get GraphicsResetStatusKHR() != GL_NO_ERROR))
168 accelerate = false; 168 accelerate = false;
169 return accelerate; 169 return accelerate;
170 } 170 }
171 171
172 bool Canvas2DLayerBridge::isAccelerated() const 172 bool Canvas2DLayerBridge::isAccelerated() const
173 { 173 {
174 if (m_accelerationMode == DisableAcceleration)
175 return false;
174 if (isHibernating()) 176 if (isHibernating())
175 return false; 177 return false;
176 if (m_softwareRenderingWhileHidden) 178 if (m_softwareRenderingWhileHidden)
177 return false; 179 return false;
178 if (m_layer) // We don't check m_surface, so this returns true if context wa s lost (m_surface is null) with restoration pending. 180 if (m_layer) // We don't check m_surface, so this returns true if context wa s lost (m_surface is null) with restoration pending.
179 return true; 181 return true;
180 if (m_surface) // && !m_layer is implied 182 if (m_surface) // && !m_layer is implied
181 return false; 183 return false;
182 184
183 // Whether or not to accelerate is not yet resolved, determine whether immed iate presentation 185 // Whether or not to accelerate is not yet resolved, determine whether immed iate presentation
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 { 459 {
458 if (!m_surfaceCreationFailedAtLeastOnce) { 460 if (!m_surfaceCreationFailedAtLeastOnce) {
459 // Only count the failure once per instance so that the histogram may 461 // Only count the failure once per instance so that the histogram may
460 // reflect the proportion of Canvas2DLayerBridge instances with surface 462 // reflect the proportion of Canvas2DLayerBridge instances with surface
461 // allocation failures. 463 // allocation failures.
462 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCa nvasSurfaceCreationFailed); 464 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCa nvasSurfaceCreationFailed);
463 m_surfaceCreationFailedAtLeastOnce = true; 465 m_surfaceCreationFailedAtLeastOnce = true;
464 } 466 }
465 } 467 }
466 468
469 void Canvas2DLayerBridge::disableAcceleration()
470 {
471 DCHECK(isAccelerated());
472 bool surfaceIsAccelerated;
473 RefPtr<SkSurface> newSurface = createSkSurface(nullptr, m_size, m_msaaSample Count, m_opacityMode, &surfaceIsAccelerated);
474 if (newSurface) {
475 DCHECK(!surfaceIsAccelerated);
476 flush();
477 SkPaint copyPaint;
478 copyPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
479 m_surface->draw(newSurface->getCanvas(), 0, 0, &copyPaint); // GPU readb ack here
480 m_accelerationMode = DisableAcceleration; // Acceleration gets permanent ly disabled
481 GraphicsLayer::unregisterContentsLayer(m_layer->layer());
482 m_layer->clearTexture();
483 m_layer->layer()->removeFromParent();
484 m_surface = newSurface;
485 if (m_imageBuffer)
486 m_imageBuffer->didDisableAcceleration();
487 }
488 }
489
467 SkSurface* Canvas2DLayerBridge::getOrCreateSurface(AccelerationHint hint) 490 SkSurface* Canvas2DLayerBridge::getOrCreateSurface(AccelerationHint hint)
468 { 491 {
469 if (m_surface) 492 if (m_surface) {
493 // Note: in layout tests, canvas2dFixedRenderingMode is set to true to i nhibit
494 // mode switching so that we continue to get test coverage for GPU accel eration
495 // despite the use of getImageData in tests
496 if (hint == ForceNoAcceleration && isAccelerated() && !RuntimeEnabledFea tures::canvas2dFixedRenderingModeEnabled())
497 disableAcceleration();
470 return m_surface.get(); 498 return m_surface.get();
499 }
471 500
472 if (m_layer && !isHibernating() && hint == PreferAcceleration) { 501 if (m_layer && !isHibernating() && hint == PreferAcceleration && m_accelerat ionMode != DisableAcceleration) {
473 return nullptr; // re-creation will happen through restore() 502 return nullptr; // re-creation will happen through restore()
474 } 503 }
475 504
476 bool wantAcceleration = shouldAccelerate(hint); 505 bool wantAcceleration = shouldAccelerate(hint);
477 bool surfaceIsAccelerated;
478 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && isHidden() && wantAccelerati on) { 506 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && isHidden() && wantAccelerati on) {
479 wantAcceleration = false; 507 wantAcceleration = false;
480 m_softwareRenderingWhileHidden = true; 508 m_softwareRenderingWhileHidden = true;
481 } 509 }
482 510
511 bool surfaceIsAccelerated;
483 m_surface = createSkSurface(wantAcceleration ? m_contextProvider->grContext( ) : nullptr, m_size, m_msaaSampleCount, m_opacityMode, &surfaceIsAccelerated); 512 m_surface = createSkSurface(wantAcceleration ? m_contextProvider->grContext( ) : nullptr, m_size, m_msaaSampleCount, m_opacityMode, &surfaceIsAccelerated);
484 513
485 if (!m_surface) 514 if (!m_surface)
486 reportSurfaceCreationFailure(); 515 reportSurfaceCreationFailure();
487 516
488 if (m_surface && surfaceIsAccelerated && !m_layer) { 517 if (m_surface && surfaceIsAccelerated && !m_layer) {
489 m_layer = wrapUnique(Platform::current()->compositorSupport()->createExt ernalTextureLayer(this)); 518 m_layer = wrapUnique(Platform::current()->compositorSupport()->createExt ernalTextureLayer(this));
490 m_layer->setOpaque(m_opacityMode == Opaque); 519 m_layer->setOpaque(m_opacityMode == Opaque);
491 m_layer->setBlendBackgroundColor(m_opacityMode != Opaque); 520 m_layer->setBlendBackgroundColor(m_opacityMode != Opaque);
492 GraphicsLayer::registerContentsLayer(m_layer->layer()); 521 GraphicsLayer::registerContentsLayer(m_layer->layer());
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 m_logger->reportHibernationEvent(HibernationEndedWithTeardown); 602 m_logger->reportHibernationEvent(HibernationEndedWithTeardown);
574 m_hibernationImage.clear(); 603 m_hibernationImage.clear();
575 m_recorder.reset(); 604 m_recorder.reset();
576 m_imageBuffer = nullptr; 605 m_imageBuffer = nullptr;
577 m_destructionInProgress = true; 606 m_destructionInProgress = true;
578 setIsHidden(true); 607 setIsHidden(true);
579 m_surface.clear(); 608 m_surface.clear();
580 609
581 unregisterTaskObserver(); 610 unregisterTaskObserver();
582 611
583 if (m_layer) { 612 if (m_layer && m_accelerationMode != DisableAcceleration) {
584 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); 613 GraphicsLayer::unregisterContentsLayer(m_layer->layer());
585 m_layer->clearTexture(); 614 m_layer->clearTexture();
586 // Orphaning the layer is required to trigger the recration of a new lay er 615 // Orphaning the layer is required to trigger the recration of a new lay er
587 // in the case where destruction is caused by a canvas resize. Test: 616 // in the case where destruction is caused by a canvas resize. Test:
588 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html 617 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html
589 m_layer->layer()->removeFromParent(); 618 m_layer->layer()->removeFromParent();
590 } 619 }
591 620
592 DCHECK(!m_bytesAllocated); 621 DCHECK(!m_bytesAllocated);
593 } 622 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 gpu::gles2::GLES2Interface* gl = contextGL(); 731 gpu::gles2::GLES2Interface* gl = contextGL();
703 if (isAccelerated() && gl) 732 if (isAccelerated() && gl)
704 gl->Flush(); 733 gl->Flush();
705 } 734 }
706 735
707 736
708 gpu::gles2::GLES2Interface* Canvas2DLayerBridge::contextGL() 737 gpu::gles2::GLES2Interface* Canvas2DLayerBridge::contextGL()
709 { 738 {
710 // Check on m_layer is necessary because contextGL() may be called during 739 // Check on m_layer is necessary because contextGL() may be called during
711 // the destruction of m_layer 740 // the destruction of m_layer
712 if (m_layer && !m_destructionInProgress) { 741 if (m_layer && m_accelerationMode != DisableAcceleration && !m_destructionIn Progress) {
713 // Call checkSurfaceValid to ensure rate limiter is disabled if context is lost. 742 // Call checkSurfaceValid to ensure rate limiter is disabled if context is lost.
714 if (!checkSurfaceValid()) 743 if (!checkSurfaceValid())
715 return nullptr; 744 return nullptr;
716 } 745 }
717 return m_contextProvider ? m_contextProvider->contextGL() : nullptr; 746 return m_contextProvider ? m_contextProvider->contextGL() : nullptr;
718 } 747 }
719 748
720 bool Canvas2DLayerBridge::checkSurfaceValid() 749 bool Canvas2DLayerBridge::checkSurfaceValid()
721 { 750 {
722 DCHECK(!m_destructionInProgress); 751 DCHECK(!m_destructionInProgress);
723 if (m_destructionInProgress) 752 if (m_destructionInProgress)
724 return false; 753 return false;
725 if (isHibernating()) 754 if (isHibernating())
726 return true; 755 return true;
727 if (!m_layer) 756 if (!m_layer || m_accelerationMode == DisableAcceleration)
728 return true; 757 return true;
729 if (!m_surface) 758 if (!m_surface)
730 return false; 759 return false;
731 if (m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERR OR) { 760 if (m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERR OR) {
732 m_surface.clear(); 761 m_surface.clear();
733 for (auto mailboxInfo = m_mailboxes.begin(); mailboxInfo != m_mailboxes. end(); ++mailboxInfo) { 762 for (auto mailboxInfo = m_mailboxes.begin(); mailboxInfo != m_mailboxes. end(); ++mailboxInfo) {
734 if (mailboxInfo->m_image) 763 if (mailboxInfo->m_image)
735 mailboxInfo->m_image.clear(); 764 mailboxInfo->m_image.clear();
736 } 765 }
737 if (m_imageBuffer) 766 if (m_imageBuffer)
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 // to postpone destruction until the end of this function. 897 // to postpone destruction until the end of this function.
869 selfRef = this; 898 selfRef = this;
870 } 899 }
871 900
872 // The destruction of 'releasedMailboxInfo' will: 901 // The destruction of 'releasedMailboxInfo' will:
873 // 1) Release the self reference held by the mailboxInfo, which may trigger 902 // 1) Release the self reference held by the mailboxInfo, which may trigger
874 // the self-destruction of this Canvas2DLayerBridge 903 // the self-destruction of this Canvas2DLayerBridge
875 // 2) Release the SkImage, which will return the texture to skia's scratch 904 // 2) Release the SkImage, which will return the texture to skia's scratch
876 // texture pool. 905 // texture pool.
877 m_mailboxes.remove(releasedMailboxInfo); 906 m_mailboxes.remove(releasedMailboxInfo);
907
908 if (m_mailboxes.isEmpty() && m_accelerationMode == DisableAcceleration)
909 m_layer.reset();
878 } 910 }
879 911
880 WebLayer* Canvas2DLayerBridge::layer() const 912 WebLayer* Canvas2DLayerBridge::layer() const
881 { 913 {
882 DCHECK(!m_destructionInProgress); 914 DCHECK(!m_destructionInProgress);
883 DCHECK(m_layer); 915 DCHECK(m_layer);
884 return m_layer->layer(); 916 return m_layer->layer();
885 } 917 }
886 918
887 void Canvas2DLayerBridge::didDraw(const FloatRect& rect) 919 void Canvas2DLayerBridge::didDraw(const FloatRect& rect)
(...skipping 13 matching lines...) Expand all
901 } 933 }
902 934
903 void Canvas2DLayerBridge::prepareSurfaceForPaintingIfNeeded() 935 void Canvas2DLayerBridge::prepareSurfaceForPaintingIfNeeded()
904 { 936 {
905 getOrCreateSurface(PreferAcceleration); 937 getOrCreateSurface(PreferAcceleration);
906 } 938 }
907 939
908 void Canvas2DLayerBridge::finalizeFrame(const FloatRect &dirtyRect) 940 void Canvas2DLayerBridge::finalizeFrame(const FloatRect &dirtyRect)
909 { 941 {
910 DCHECK(!m_destructionInProgress); 942 DCHECK(!m_destructionInProgress);
911 if (m_layer) 943 if (m_layer && m_accelerationMode != DisableAcceleration)
912 m_layer->layer()->invalidateRect(enclosingIntRect(dirtyRect)); 944 m_layer->layer()->invalidateRect(enclosingIntRect(dirtyRect));
913 if (m_rateLimiter) 945 if (m_rateLimiter)
914 m_rateLimiter->reset(); 946 m_rateLimiter->reset();
915 m_renderingTaskCompletedForCurrentFrame = false; 947 m_renderingTaskCompletedForCurrentFrame = false;
916 } 948 }
917 949
918 void Canvas2DLayerBridge::didProcessTask() 950 void Canvas2DLayerBridge::didProcessTask()
919 { 951 {
920 TRACE_EVENT0("cc", "Canvas2DLayerBridge::didProcessTask"); 952 TRACE_EVENT0("cc", "Canvas2DLayerBridge::didProcessTask");
921 DCHECK(m_isRegisteredTaskObserver); 953 DCHECK(m_isRegisteredTaskObserver);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 #endif // USE_IOSURFACE_FOR_2D_CANVAS 1028 #endif // USE_IOSURFACE_FOR_2D_CANVAS
997 } 1029 }
998 1030
999 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) 1031 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event)
1000 { 1032 {
1001 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount)); 1033 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount));
1002 hibernationHistogram.count(event); 1034 hibernationHistogram.count(event);
1003 } 1035 }
1004 1036
1005 } // namespace blink 1037 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698