| Index: third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp
|
| diff --git a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp
|
| index 191cb3f1a7c5bac2805170bdb25460bb5352dbe1..59a09aa7199bfc95c262b024743e64c157552584 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp
|
| @@ -33,7 +33,7 @@ RecordingImageBufferSurface::RecordingImageBufferSurface(const IntSize& size, Pa
|
| RecordingImageBufferSurface::~RecordingImageBufferSurface()
|
| { }
|
|
|
| -bool RecordingImageBufferSurface::initializeCurrentFrame()
|
| +void RecordingImageBufferSurface::initializeCurrentFrame()
|
| {
|
| static SkRTreeFactory rTreeFactory;
|
| m_currentFrame = adoptPtr(new SkPictureRecorder);
|
| @@ -44,7 +44,6 @@ bool RecordingImageBufferSurface::initializeCurrentFrame()
|
| m_didRecordDrawCommandsInCurrentFrame = false;
|
| m_currentFrameHasExpensiveOp = false;
|
| m_currentFramePixelCount = 0;
|
| - return true;
|
| }
|
|
|
| void RecordingImageBufferSurface::setImageBuffer(ImageBuffer* imageBuffer)
|
| @@ -64,18 +63,20 @@ bool RecordingImageBufferSurface::writePixels(const SkImageInfo& origInfo, const
|
| if (x <= 0 && y <= 0 && x + origInfo.width() >= size().width() && y + origInfo.height() >= size().height()) {
|
| willOverwriteCanvas();
|
| }
|
| - fallBackToRasterCanvas();
|
| + fallBackToRasterCanvas(FallbackReasonWritePixels);
|
| }
|
| return m_fallbackSurface->writePixels(origInfo, pixels, rowBytes, x, y);
|
| }
|
|
|
| -void RecordingImageBufferSurface::fallBackToRasterCanvas()
|
| +void RecordingImageBufferSurface::fallBackToRasterCanvas(FallbackReason reason)
|
| {
|
| if (m_fallbackSurface) {
|
| ASSERT(!m_currentFrame);
|
| return;
|
| }
|
|
|
| + Platform::current()->histogramEnumeration("Canvas.DisplayListFallbackReason", reason, FallbackReasonCount);
|
| +
|
| m_fallbackSurface = m_fallbackFactory->createSurface(size(), opacityMode());
|
| m_fallbackSurface->setImageBuffer(m_imageBuffer);
|
|
|
| @@ -97,11 +98,37 @@ void RecordingImageBufferSurface::fallBackToRasterCanvas()
|
| CanvasMetrics::countCanvasContextUsage(CanvasMetrics::DisplayList2DCanvasFallbackToRaster);
|
| }
|
|
|
| -PassRefPtr<SkImage> RecordingImageBufferSurface::newImageSnapshot(AccelerationHint hint)
|
| +static RecordingImageBufferSurface::FallbackReason snapshotReasonToFallbackReason(SnapshotReason reason)
|
| +{
|
| + switch (reason) {
|
| + case SnapshotReasonUnknown:
|
| + return RecordingImageBufferSurface::FallbackReasonUnknown;
|
| + case SnapshotReasonGetImageData:
|
| + return RecordingImageBufferSurface::FallbackReasonSnapshotForGetImageData;
|
| + case SnapshotReasonCopyToWebGLTexture:
|
| + return RecordingImageBufferSurface::FallbackReasonSnapshotForCopyToWebGLTexture;
|
| + case SnapshotReasonPaint:
|
| + return RecordingImageBufferSurface::FallbackReasonSnapshotForPaint;
|
| + case SnapshotReasonToDataURL:
|
| + return RecordingImageBufferSurface::FallbackReasonSnapshotForToDataURL;
|
| + case SnapshotReasonToBlob:
|
| + return RecordingImageBufferSurface::FallbackReasonSnapshotForToBlob;
|
| + case SnapshotReasonCanvasListenerCapture:
|
| + return RecordingImageBufferSurface::FallbackReasonSnapshotForCanvasListenerCapture;
|
| + case SnapshotReasonDrawImage:
|
| + return RecordingImageBufferSurface::FallbackReasonSnapshotForDrawImage;
|
| + case SnapshotReasonCreatePattern:
|
| + return RecordingImageBufferSurface::FallbackReasonSnapshotForCreatePattern;
|
| + }
|
| + ASSERT_NOT_REACHED();
|
| + return RecordingImageBufferSurface::FallbackReasonUnknown;
|
| +}
|
| +
|
| +PassRefPtr<SkImage> RecordingImageBufferSurface::newImageSnapshot(AccelerationHint hint, SnapshotReason reason)
|
| {
|
| if (!m_fallbackSurface)
|
| - fallBackToRasterCanvas();
|
| - return m_fallbackSurface->newImageSnapshot(hint);
|
| + fallBackToRasterCanvas(snapshotReasonToFallbackReason(reason));
|
| + return m_fallbackSurface->newImageSnapshot(hint, reason);
|
| }
|
|
|
| SkCanvas* RecordingImageBufferSurface::canvas()
|
| @@ -113,10 +140,31 @@ SkCanvas* RecordingImageBufferSurface::canvas()
|
| return m_currentFrame->getRecordingCanvas();
|
| }
|
|
|
| -void RecordingImageBufferSurface::disableDeferral()
|
| +static RecordingImageBufferSurface::FallbackReason disableDeferralReasonToFallbackReason(DisableDeferralReason reason)
|
| +{
|
| + switch (reason) {
|
| + case DisableDeferralReasonUnknown:
|
| + return RecordingImageBufferSurface::FallbackReasonUnknown;
|
| + case DisableDeferralReasonExpensiveOverdrawHeuristic:
|
| + return RecordingImageBufferSurface::FallbackReasonExpensiveOverdrawHeuristic;
|
| + case DisableDeferralReasonUsingTextureBackedPattern:
|
| + return RecordingImageBufferSurface::FallbackReasonTextureBackedPattern;
|
| + case DisableDeferralReasonDrawImageOfVideo:
|
| + return RecordingImageBufferSurface::FallbackReasonDrawImageOfVideo;
|
| + case DisableDeferralReasonDrawImageOfAnimated2dCanvas:
|
| + return RecordingImageBufferSurface::FallbackReasonDrawImageOfAnimated2dCanvas;
|
| + case DisableDeferralReasonCount:
|
| + ASSERT_NOT_REACHED();
|
| + break;
|
| + }
|
| + ASSERT_NOT_REACHED();
|
| + return RecordingImageBufferSurface::FallbackReasonUnknown;
|
| +}
|
| +
|
| +void RecordingImageBufferSurface::disableDeferral(DisableDeferralReason reason)
|
| {
|
| if (!m_fallbackSurface)
|
| - fallBackToRasterCanvas();
|
| + fallBackToRasterCanvas(disableDeferralReasonToFallbackReason(reason));
|
| }
|
|
|
| PassRefPtr<SkPicture> RecordingImageBufferSurface::getPicture()
|
| @@ -124,7 +172,8 @@ PassRefPtr<SkPicture> RecordingImageBufferSurface::getPicture()
|
| if (m_fallbackSurface)
|
| return nullptr;
|
|
|
| - bool canUsePicture = finalizeFrameInternal();
|
| + FallbackReason fallbackReason = FallbackReasonUnknown;
|
| + bool canUsePicture = finalizeFrameInternal(&fallbackReason);
|
| m_imageBuffer->didFinalizeFrame();
|
|
|
| if (canUsePicture) {
|
| @@ -132,7 +181,7 @@ PassRefPtr<SkPicture> RecordingImageBufferSurface::getPicture()
|
| }
|
|
|
| if (!m_fallbackSurface)
|
| - fallBackToRasterCanvas();
|
| + fallBackToRasterCanvas(fallbackReason);
|
| return nullptr;
|
| }
|
|
|
| @@ -143,15 +192,30 @@ void RecordingImageBufferSurface::finalizeFrame(const FloatRect &dirtyRect)
|
| return;
|
| }
|
|
|
| - if (!finalizeFrameInternal())
|
| - fallBackToRasterCanvas();
|
| + FallbackReason fallbackReason = FallbackReasonUnknown;
|
| + if (!finalizeFrameInternal(&fallbackReason))
|
| + fallBackToRasterCanvas(fallbackReason);
|
| }
|
|
|
| -void RecordingImageBufferSurface::flush()
|
| +static RecordingImageBufferSurface::FallbackReason flushReasonToFallbackReason(FlushReason reason)
|
| +{
|
| + switch (reason) {
|
| + case FlushReasonUnknown:
|
| + return RecordingImageBufferSurface::FallbackReasonUnknown;
|
| + case FlushReasonInitialClear:
|
| + return RecordingImageBufferSurface::FallbackReasonFlushInitialClear;
|
| + case FlushReasonDrawImageOfWebGL:
|
| + return RecordingImageBufferSurface::FallbackReasonFlushForDrawImageOfWebGL;
|
| + }
|
| + ASSERT_NOT_REACHED();
|
| + return RecordingImageBufferSurface::FallbackReasonUnknown;
|
| +}
|
| +
|
| +void RecordingImageBufferSurface::flush(FlushReason reason)
|
| {
|
| if (!m_fallbackSurface)
|
| - fallBackToRasterCanvas();
|
| - m_fallbackSurface->flush();
|
| + fallBackToRasterCanvas(flushReasonToFallbackReason(reason));
|
| + m_fallbackSurface->flush(reason);
|
| }
|
|
|
| void RecordingImageBufferSurface::willOverwriteCanvas()
|
| @@ -174,11 +238,13 @@ void RecordingImageBufferSurface::didDraw(const FloatRect& rect)
|
| m_currentFramePixelCount += pixelBounds.width() * pixelBounds.height();
|
| }
|
|
|
| -bool RecordingImageBufferSurface::finalizeFrameInternal()
|
| +bool RecordingImageBufferSurface::finalizeFrameInternal(FallbackReason* fallbackReason)
|
| {
|
| ASSERT(!m_fallbackSurface);
|
| ASSERT(m_currentFrame);
|
| ASSERT(m_currentFrame->getRecordingCanvas());
|
| + ASSERT(fallbackReason);
|
| + ASSERT(*fallbackReason == FallbackReasonUnknown);
|
|
|
| if (!m_imageBuffer->isDirty()) {
|
| if (!m_previousFrame) {
|
| @@ -189,15 +255,20 @@ bool RecordingImageBufferSurface::finalizeFrameInternal()
|
| return m_currentFrame;
|
| }
|
|
|
| - if (!m_frameWasCleared || m_currentFrame->getRecordingCanvas()->getSaveCount() > ExpensiveCanvasHeuristicParameters::ExpensiveRecordingStackDepth) {
|
| + if (!m_frameWasCleared) {
|
| + *fallbackReason = FallbackReasonCanvasNotClearedBetweenFrames;
|
| + return false;
|
| + }
|
| +
|
| + if (m_currentFrame->getRecordingCanvas()->getSaveCount() > ExpensiveCanvasHeuristicParameters::ExpensiveRecordingStackDepth) {
|
| + *fallbackReason = FallbackReasonRunawayStateStack;
|
| return false;
|
| }
|
|
|
| m_previousFrame = adoptRef(m_currentFrame->endRecording());
|
| m_previousFrameHasExpensiveOp = m_currentFrameHasExpensiveOp;
|
| m_previousFramePixelCount = m_currentFramePixelCount;
|
| - if (!initializeCurrentFrame())
|
| - return false;
|
| + initializeCurrentFrame();
|
|
|
| m_frameWasCleared = false;
|
| return true;
|
|
|