Index: Source/platform/graphics/RecordingImageBufferSurface.cpp |
diff --git a/Source/platform/graphics/RecordingImageBufferSurface.cpp b/Source/platform/graphics/RecordingImageBufferSurface.cpp |
index abd7003fa38821b46f8c9c7bdc24eb30e8d309ea..bad61686e84800754194f13b962f6e53b2247699 100644 |
--- a/Source/platform/graphics/RecordingImageBufferSurface.cpp |
+++ b/Source/platform/graphics/RecordingImageBufferSurface.cpp |
@@ -8,6 +8,7 @@ |
#include "platform/graphics/GraphicsContext.h" |
#include "platform/graphics/ImageBuffer.h" |
+#include "public/platform/Platform.h" |
#include "third_party/skia/include/core/SkCanvas.h" |
#include "third_party/skia/include/core/SkPictureRecorder.h" |
#include "wtf/PassOwnPtr.h" |
@@ -20,13 +21,17 @@ RecordingImageBufferSurface::RecordingImageBufferSurface(const IntSize& size, Op |
, m_graphicsContext(0) |
, m_initialSaveCount(0) |
, m_frameWasCleared(true) |
- , m_surfaceUsedSincePreviousFrameWasPresented(false) |
+ , m_recordedSinceLastFrameWasFinalized(false) |
{ |
initializeCurrentFrame(); |
} |
RecordingImageBufferSurface::~RecordingImageBufferSurface() |
-{ } |
+{ |
+ if (m_recordedSinceLastFrameWasFinalized) { |
+ blink::Platform::current()->currentThread()->removeTaskObserver(this); |
+ } |
+} |
void RecordingImageBufferSurface::initializeCurrentFrame() |
{ |
@@ -90,8 +95,7 @@ SkCanvas* RecordingImageBufferSurface::canvas() const |
PassRefPtr<SkPicture> RecordingImageBufferSurface::getPicture() |
{ |
- if (handleOpaqueFrame()) { |
- m_surfaceUsedSincePreviousFrameWasPresented = false; |
+ if (finalizeFrame()) { |
return m_previousFrame; |
} |
@@ -100,9 +104,30 @@ PassRefPtr<SkPicture> RecordingImageBufferSurface::getPicture() |
return nullptr; |
} |
-void RecordingImageBufferSurface::willUse() |
+void RecordingImageBufferSurface::didDraw() |
+{ |
+ if (!m_recordedSinceLastFrameWasFinalized && m_currentFrame) { |
+ m_recordedSinceLastFrameWasFinalized = true; |
+ blink::Platform::current()->currentThread()->addTaskObserver(this); |
+ } |
+} |
+ |
+void RecordingImageBufferSurface::willProcessTask() |
+{ |
+} |
+ |
+void RecordingImageBufferSurface::didProcessTask() |
{ |
- m_surfaceUsedSincePreviousFrameWasPresented = true; |
+ ASSERT(m_recordedSinceLastFrameWasFinalized); |
+ // This is to insert a frame barrier at the end of each script execution |
+ // task that touches the canvas. finalizeFrame() will discard the previous |
+ // frame and replace it with the current frame even if it has not been |
+ // consumed, thus allowing the renderer to skip ahead to the most recently |
+ // recorded frame. |
+ if (!finalizeFrame()) { |
+ ASSERT(!m_rasterCanvas); |
+ fallBackToRasterCanvas(); |
+ } |
} |
void RecordingImageBufferSurface::didClearCanvas() |
@@ -110,14 +135,23 @@ void RecordingImageBufferSurface::didClearCanvas() |
m_frameWasCleared = true; |
} |
-bool RecordingImageBufferSurface::handleOpaqueFrame() |
+bool RecordingImageBufferSurface::finalizeFrame() |
{ |
- if (!m_currentFrame) |
+ if (!m_currentFrame) { |
+ ASSERT(!m_recordedSinceLastFrameWasFinalized); |
return false; |
+ } |
+ |
+ bool canvasHasChanged = m_recordedSinceLastFrameWasFinalized; |
+ if (m_recordedSinceLastFrameWasFinalized) { |
+ blink::Platform::current()->currentThread()->removeTaskObserver(this); |
+ m_recordedSinceLastFrameWasFinalized = false; |
+ } |
+ |
IntRect canvasRect(IntPoint(0, 0), size()); |
if (!m_frameWasCleared && !m_graphicsContext->opaqueRegion().asRect().contains(canvasRect)) { |
// No clear happened. If absolutely nothing was drawn, then we can just continue to use the previous frame. |
- return !m_surfaceUsedSincePreviousFrameWasPresented; |
+ return !canvasHasChanged; |
} |
SkCanvas* oldCanvas = m_currentFrame->getRecordingCanvas(); // Could be raster or picture |