| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |