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

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

Issue 2700833002: Simplify rate limiter logic in Canvas2DLayerBridge (Closed)
Patch Set: make more readable Created 3 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 | « third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.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 /* 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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 m_logger(WTF::wrapUnique(new Logger)), 134 m_logger(WTF::wrapUnique(new Logger)),
135 m_weakPtrFactory(this), 135 m_weakPtrFactory(this),
136 m_imageBuffer(0), 136 m_imageBuffer(0),
137 m_msaaSampleCount(msaaSampleCount), 137 m_msaaSampleCount(msaaSampleCount),
138 m_bytesAllocated(0), 138 m_bytesAllocated(0),
139 m_haveRecordedDrawCommands(false), 139 m_haveRecordedDrawCommands(false),
140 m_destructionInProgress(false), 140 m_destructionInProgress(false),
141 m_filterQuality(kLow_SkFilterQuality), 141 m_filterQuality(kLow_SkFilterQuality),
142 m_isHidden(false), 142 m_isHidden(false),
143 m_isDeferralEnabled(true), 143 m_isDeferralEnabled(true),
144 m_isRegisteredTaskObserver(false),
145 m_renderingTaskCompletedForCurrentFrame(false),
146 m_softwareRenderingWhileHidden(false), 144 m_softwareRenderingWhileHidden(false),
147 m_lastImageId(0), 145 m_lastImageId(0),
148 m_lastFilter(GL_LINEAR), 146 m_lastFilter(GL_LINEAR),
149 m_accelerationMode(accelerationMode), 147 m_accelerationMode(accelerationMode),
150 m_opacityMode(opacityMode), 148 m_opacityMode(opacityMode),
151 m_size(size), 149 m_size(size),
152 m_colorSpace(colorSpace), 150 m_colorSpace(colorSpace),
153 m_skSurfacesUseColorSpace(skSurfacesUseColorSpace), 151 m_skSurfacesUseColorSpace(skSurfacesUseColorSpace),
154 m_colorType(colorType) { 152 m_colorType(colorType) {
155 DCHECK(m_contextProvider); 153 DCHECK(m_contextProvider);
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 m_logger->reportHibernationEvent(HibernationAbortedDueGpuContextLoss); 488 m_logger->reportHibernationEvent(HibernationAbortedDueGpuContextLoss);
491 return; 489 return;
492 } 490 }
493 491
494 if (!isAccelerated()) { 492 if (!isAccelerated()) {
495 m_logger->reportHibernationEvent( 493 m_logger->reportHibernationEvent(
496 HibernationAbortedDueToSwitchToUnacceleratedRendering); 494 HibernationAbortedDueToSwitchToUnacceleratedRendering);
497 return; 495 return;
498 } 496 }
499 497
500 TRACE_EVENT0("cc", "Canvas2DLayerBridge::hibernate"); 498 TRACE_EVENT0("blink", "Canvas2DLayerBridge::hibernate");
501 sk_sp<PaintSurface> tempHibernationSurface = 499 sk_sp<PaintSurface> tempHibernationSurface =
502 PaintSurface::MakeRasterN32Premul(m_size.width(), m_size.height()); 500 PaintSurface::MakeRasterN32Premul(m_size.width(), m_size.height());
503 if (!tempHibernationSurface) { 501 if (!tempHibernationSurface) {
504 m_logger->reportHibernationEvent(HibernationAbortedDueToAllocationFailure); 502 m_logger->reportHibernationEvent(HibernationAbortedDueToAllocationFailure);
505 return; 503 return;
506 } 504 }
507 // No HibernationEvent reported on success. This is on purppose to avoid 505 // No HibernationEvent reported on success. This is on purppose to avoid
508 // non-complementary stats. Each HibernationScheduled event is paired with 506 // non-complementary stats. Each HibernationScheduled event is paired with
509 // exactly one failure or exit event. 507 // exactly one failure or exit event.
510 flushRecordingOnly(); 508 flushRecordingOnly();
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 return; 660 return;
663 if (isHibernating()) 661 if (isHibernating())
664 m_logger->reportHibernationEvent(HibernationEndedWithTeardown); 662 m_logger->reportHibernationEvent(HibernationEndedWithTeardown);
665 m_hibernationImage.reset(); 663 m_hibernationImage.reset();
666 m_recorder.reset(); 664 m_recorder.reset();
667 m_imageBuffer = nullptr; 665 m_imageBuffer = nullptr;
668 m_destructionInProgress = true; 666 m_destructionInProgress = true;
669 setIsHidden(true); 667 setIsHidden(true);
670 m_surface.reset(); 668 m_surface.reset();
671 669
672 unregisterTaskObserver();
673
674 if (m_layer && m_accelerationMode != DisableAcceleration) { 670 if (m_layer && m_accelerationMode != DisableAcceleration) {
675 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); 671 GraphicsLayer::unregisterContentsLayer(m_layer->layer());
676 m_layer->clearTexture(); 672 m_layer->clearTexture();
677 // Orphaning the layer is required to trigger the recration of a new layer 673 // Orphaning the layer is required to trigger the recration of a new layer
678 // in the case where destruction is caused by a canvas resize. Test: 674 // in the case where destruction is caused by a canvas resize. Test:
679 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html 675 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html
680 m_layer->layer()->removeFromParent(); 676 m_layer->layer()->removeFromParent();
681 } 677 }
682 678
683 DCHECK(!m_bytesAllocated); 679 DCHECK(!m_bytesAllocated);
684 } 680 }
685 681
686 void Canvas2DLayerBridge::unregisterTaskObserver() {
687 if (m_isRegisteredTaskObserver) {
688 Platform::current()->currentThread()->removeTaskObserver(this);
689 m_isRegisteredTaskObserver = false;
690 }
691 }
692
693 void Canvas2DLayerBridge::setFilterQuality(SkFilterQuality filterQuality) { 682 void Canvas2DLayerBridge::setFilterQuality(SkFilterQuality filterQuality) {
694 DCHECK(!m_destructionInProgress); 683 DCHECK(!m_destructionInProgress);
695 m_filterQuality = filterQuality; 684 m_filterQuality = filterQuality;
696 if (m_layer) 685 if (m_layer)
697 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); 686 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality);
698 } 687 }
699 688
700 void Canvas2DLayerBridge::setIsHidden(bool hidden) { 689 void Canvas2DLayerBridge::setIsHidden(bool hidden) {
701 bool newHiddenValue = hidden || m_destructionInProgress; 690 bool newHiddenValue = hidden || m_destructionInProgress;
702 if (m_isHidden == newHiddenValue) 691 if (m_isHidden == newHiddenValue)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 } 754 }
766 755
767 void Canvas2DLayerBridge::skipQueuedDrawCommands() { 756 void Canvas2DLayerBridge::skipQueuedDrawCommands() {
768 if (m_haveRecordedDrawCommands) { 757 if (m_haveRecordedDrawCommands) {
769 m_recorder->finishRecordingAsPicture(); 758 m_recorder->finishRecordingAsPicture();
770 startRecording(); 759 startRecording();
771 m_haveRecordedDrawCommands = false; 760 m_haveRecordedDrawCommands = false;
772 } 761 }
773 762
774 if (m_isDeferralEnabled) { 763 if (m_isDeferralEnabled) {
775 unregisterTaskObserver();
776 if (m_rateLimiter) 764 if (m_rateLimiter)
777 m_rateLimiter->reset(); 765 m_rateLimiter->reset();
778 } 766 }
779 } 767 }
780 768
781 void Canvas2DLayerBridge::flushRecordingOnly() { 769 void Canvas2DLayerBridge::flushRecordingOnly() {
782 DCHECK(!m_destructionInProgress); 770 DCHECK(!m_destructionInProgress);
783 771
784 if (m_haveRecordedDrawCommands && getOrCreateSurface()) { 772 if (m_haveRecordedDrawCommands && getOrCreateSurface()) {
785 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flushRecordingOnly"); 773 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flushRecordingOnly");
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { 881 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) {
894 if (m_destructionInProgress) { 882 if (m_destructionInProgress) {
895 // It can be hit in the following sequence. 883 // It can be hit in the following sequence.
896 // 1. Canvas draws something. 884 // 1. Canvas draws something.
897 // 2. The compositor begins the frame. 885 // 2. The compositor begins the frame.
898 // 3. Javascript makes a context be lost. 886 // 3. Javascript makes a context be lost.
899 // 4. Here. 887 // 4. Here.
900 return false; 888 return false;
901 } 889 }
902 890
891 m_framesSinceLastCommit = 0;
892 if (m_rateLimiter) {
893 m_rateLimiter->reset();
894 }
895
903 // If the context is lost, we don't know if we should be producing GPU or 896 // If the context is lost, we don't know if we should be producing GPU or
904 // software frames, until we get a new context, since the compositor will 897 // software frames, until we get a new context, since the compositor will
905 // be trying to get a new context and may change modes. 898 // be trying to get a new context and may change modes.
906 if (!m_contextProvider || 899 if (!m_contextProvider ||
907 m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() != 900 m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() !=
908 GL_NO_ERROR) 901 GL_NO_ERROR)
909 return false; 902 return false;
910 903
911 DCHECK(isAccelerated() || isHibernating() || m_softwareRenderingWhileHidden); 904 DCHECK(isAccelerated() || isHibernating() || m_softwareRenderingWhileHidden);
912 905
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 if (m_isDeferralEnabled) { 1021 if (m_isDeferralEnabled) {
1029 m_haveRecordedDrawCommands = true; 1022 m_haveRecordedDrawCommands = true;
1030 IntRect pixelBounds = enclosingIntRect(rect); 1023 IntRect pixelBounds = enclosingIntRect(rect);
1031 m_recordingPixelCount += pixelBounds.width() * pixelBounds.height(); 1024 m_recordingPixelCount += pixelBounds.width() * pixelBounds.height();
1032 if (m_recordingPixelCount >= 1025 if (m_recordingPixelCount >=
1033 (m_size.width() * m_size.height() * 1026 (m_size.width() * m_size.height() *
1034 ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThreshold)) { 1027 ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThreshold)) {
1035 disableDeferral(DisableDeferralReasonExpensiveOverdrawHeuristic); 1028 disableDeferral(DisableDeferralReasonExpensiveOverdrawHeuristic);
1036 } 1029 }
1037 } 1030 }
1038 if (!m_isRegisteredTaskObserver) {
1039 Platform::current()->currentThread()->addTaskObserver(this);
1040 m_isRegisteredTaskObserver = true;
1041 }
1042 m_didDrawSinceLastFlush = true; 1031 m_didDrawSinceLastFlush = true;
1043 m_didDrawSinceLastGpuFlush = true; 1032 m_didDrawSinceLastGpuFlush = true;
1044 } 1033 }
1045 1034
1046 void Canvas2DLayerBridge::finalizeFrame() { 1035 void Canvas2DLayerBridge::finalizeFrame() {
1036 TRACE_EVENT0("blink", "Canvas2DLayerBridge::finalizeFrame");
1047 DCHECK(!m_destructionInProgress); 1037 DCHECK(!m_destructionInProgress);
1048 1038
1049 // Make sure surface is ready for painting: fix the rendering mode now 1039 // Make sure surface is ready for painting: fix the rendering mode now
1050 // because it will be too late during the paint invalidation phase. 1040 // because it will be too late during the paint invalidation phase.
1051 getOrCreateSurface(PreferAcceleration); 1041 getOrCreateSurface(PreferAcceleration);
1052 1042
1053 if (m_rateLimiter) 1043 ++m_framesSinceLastCommit;
1054 m_rateLimiter->reset();
1055 m_renderingTaskCompletedForCurrentFrame = false;
1056 }
1057 1044
1058 void Canvas2DLayerBridge::doPaintInvalidation(const FloatRect& dirtyRect) { 1045 if (m_framesSinceLastCommit >= 2) {
1059 DCHECK(!m_destructionInProgress);
1060 if (m_layer && m_accelerationMode != DisableAcceleration)
1061 m_layer->layer()->invalidateRect(enclosingIntRect(dirtyRect));
1062 }
1063
1064 void Canvas2DLayerBridge::didProcessTask() {
1065 TRACE_EVENT0("cc", "Canvas2DLayerBridge::didProcessTask");
1066 DCHECK(m_isRegisteredTaskObserver);
1067 // If m_renderTaskProcessedForCurrentFrame is already set to true,
1068 // it means that rendering tasks are not synchronized with the compositor
1069 // (i.e. not using requestAnimationFrame), so we are at risk of posting
1070 // a multi-frame backlog to the GPU
1071 if (m_renderingTaskCompletedForCurrentFrame) {
1072 if (isAccelerated()) { 1046 if (isAccelerated()) {
1073 flushGpu(); 1047 flushGpu();
1074 if (!m_rateLimiter) { 1048 if (!m_rateLimiter) {
1075 m_rateLimiter = 1049 m_rateLimiter =
1076 SharedContextRateLimiter::create(MaxCanvasAnimationBacklog); 1050 SharedContextRateLimiter::create(MaxCanvasAnimationBacklog);
1077 } 1051 }
1078 } else { 1052 } else {
1079 flush(); 1053 flush();
1080 } 1054 }
1081 } 1055 }
1082 1056
1083 if (m_rateLimiter) { 1057 if (m_rateLimiter) {
1084 m_rateLimiter->tick(); 1058 m_rateLimiter->tick();
1085 } 1059 }
1086
1087 m_renderingTaskCompletedForCurrentFrame = true;
1088 unregisterTaskObserver();
1089 } 1060 }
1090 1061
1091 void Canvas2DLayerBridge::willProcessTask() { 1062 void Canvas2DLayerBridge::doPaintInvalidation(const FloatRect& dirtyRect) {
1092 NOTREACHED(); 1063 DCHECK(!m_destructionInProgress);
1064 if (m_layer && m_accelerationMode != DisableAcceleration)
1065 m_layer->layer()->invalidateRect(enclosingIntRect(dirtyRect));
1093 } 1066 }
1094 1067
1095 sk_sp<SkImage> Canvas2DLayerBridge::newImageSnapshot(AccelerationHint hint, 1068 sk_sp<SkImage> Canvas2DLayerBridge::newImageSnapshot(AccelerationHint hint,
1096 SnapshotReason) { 1069 SnapshotReason) {
1097 if (isHibernating()) 1070 if (isHibernating())
1098 return m_hibernationImage; 1071 return m_hibernationImage;
1099 if (!checkSurfaceValid()) 1072 if (!checkSurfaceValid())
1100 return nullptr; 1073 return nullptr;
1101 if (!getOrCreateSurface(hint)) 1074 if (!getOrCreateSurface(hint))
1102 return nullptr; 1075 return nullptr;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 default; 1108 default;
1136 1109
1137 void Canvas2DLayerBridge::Logger::reportHibernationEvent( 1110 void Canvas2DLayerBridge::Logger::reportHibernationEvent(
1138 HibernationEvent event) { 1111 HibernationEvent event) {
1139 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, 1112 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram,
1140 ("Canvas.HibernationEvents", HibernationEventCount)); 1113 ("Canvas.HibernationEvents", HibernationEventCount));
1141 hibernationHistogram.count(event); 1114 hibernationHistogram.count(event);
1142 } 1115 }
1143 1116
1144 } // namespace blink 1117 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698