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..e0273d7893c170ffe802573b2571fc08dc55163f 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,33 @@ 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 DisableDeferralReasonSubPixelTextAntiAliasingSupport: |
+ return RecordingImageBufferSurface::FallbackReasonSubPixelTextAntiAliasingSupport; |
+ 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 +174,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 +183,7 @@ PassRefPtr<SkPicture> RecordingImageBufferSurface::getPicture() |
} |
if (!m_fallbackSurface) |
- fallBackToRasterCanvas(); |
+ fallBackToRasterCanvas(fallbackReason); |
return nullptr; |
} |
@@ -143,15 +194,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 +240,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 +257,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; |