Index: Source/platform/graphics/RecordingImageBufferSurface.cpp |
diff --git a/Source/platform/graphics/RecordingImageBufferSurface.cpp b/Source/platform/graphics/RecordingImageBufferSurface.cpp |
index 252d436f8c42e33feb8aa66c68e1426396e14e15..385a1040489ea00e315afdcb0b07c25ba7639e7a 100644 |
--- a/Source/platform/graphics/RecordingImageBufferSurface.cpp |
+++ b/Source/platform/graphics/RecordingImageBufferSurface.cpp |
@@ -16,11 +16,18 @@ |
namespace blink { |
+struct RecordingImageBufferSurface::StateRec { |
+public: |
+ SkMatrix m_ctm; |
+ SkRect m_clip; |
+}; |
+ |
RecordingImageBufferSurface::RecordingImageBufferSurface(const IntSize& size, OpacityMode opacityMode) |
: ImageBufferSurface(size, opacityMode) |
, m_imageBuffer(0) |
, m_initialSaveCount(0) |
, m_frameWasCleared(true) |
+ , m_stateStack(sizeof(StateRec), m_stateStackStorage, sizeof(m_stateStackStorage)) |
{ |
initializeCurrentFrame(); |
} |
@@ -118,7 +125,6 @@ bool RecordingImageBufferSurface::finalizeFrameInternal() |
{ |
if (!m_imageBuffer->isDirty()) { |
if (m_currentFrame && !m_previousFrame) { |
- // Create an initial blank frame |
m_previousFrame = adoptRef(m_currentFrame->endRecording()); |
initializeCurrentFrame(); |
} |
@@ -134,28 +140,70 @@ bool RecordingImageBufferSurface::finalizeFrameInternal() |
return false; |
} |
- SkCanvas* oldCanvas = m_currentFrame->getRecordingCanvas(); // Could be raster or picture |
- |
- // FIXME(crbug.com/392614): handle transferring complex state from the current picture to the new one. |
- if (oldCanvas->getSaveCount() > m_initialSaveCount) |
- return false; |
- |
- if (!oldCanvas->isClipRect()) |
+ if (!saveState(m_currentFrame->getRecordingCanvas())) |
return false; |
- SkMatrix ctm = oldCanvas->getTotalMatrix(); |
- SkRect clip; |
- oldCanvas->getClipBounds(&clip); |
- |
m_previousFrame = adoptRef(m_currentFrame->endRecording()); |
initializeCurrentFrame(); |
- SkCanvas* newCanvas = m_currentFrame->getRecordingCanvas(); |
- newCanvas->concat(ctm); |
- newCanvas->clipRect(clip); |
+ setCurrentState(m_currentFrame->getRecordingCanvas()); |
m_frameWasCleared = false; |
return true; |
} |
+bool RecordingImageBufferSurface::saveState(SkCanvas* srcCanvas) |
+{ |
+ // FIXME(crbug.com/392614): handle transferring complex state from the current picture to the new one: |
+ // - non-square clip |
Justin Novosad
2014/08/26 16:57:20
I think you mean non-rectangular clip
Sergey
2014/08/28 09:55:33
Done.
|
+ // - non-invertable clip |
Justin Novosad
2014/08/26 16:57:20
"non-invertible"
Sergey
2014/08/28 09:55:33
Done.
|
+ StateRec* state = 0; |
+ |
+ if (!srcCanvas->isClipRect()) |
+ return false; |
+ |
+ while (!m_stateStack.empty()) { |
Justin Novosad
2014/08/26 16:57:20
You will not have to do this once you make the sta
Sergey
2014/08/28 09:55:33
Done.
|
+ state = (StateRec *)m_stateStack.back(); |
Justin Novosad
2014/08/26 16:57:20
Please avoid C-style casts. If you switch to WTF:
Sergey
2014/08/28 09:55:34
Done.
|
+ state->~StateRec(); |
+ m_stateStack.pop_back(); |
+ } |
+ |
+ // we will remove all the saved state stack in endRecording anyway, so it makes no difference |
+ while (srcCanvas->getSaveCount() > m_initialSaveCount) { |
+ state = (StateRec *)m_stateStack.push_back(); |
+ state->m_ctm = srcCanvas->getTotalMatrix(); |
+ srcCanvas->getClipBounds(&state->m_clip); |
+ srcCanvas->restore(); |
+ if (!srcCanvas->isClipRect()) |
+ return false; |
Justin Novosad
2014/08/26 16:57:20
This needs to be fixed before we can ship display
Sergey
2014/08/28 09:55:34
I've filed crbug.com/408392. It seems I don't have
|
+ } |
+ |
+ state = (StateRec *)m_stateStack.push_back(); |
+ new (state) StateRec(); |
Justin Novosad
2014/08/26 16:57:20
No need to do this because StateRec does not even
Sergey
2014/08/28 09:55:33
I thought that I should do that in case StateRec w
|
+ state->m_ctm = srcCanvas->getTotalMatrix(); |
+ srcCanvas->getClipBounds(&state->m_clip); |
+ |
+ return true; |
+} |
+ |
+void RecordingImageBufferSurface::setCurrentState(SkCanvas* dstCanvas) |
+{ |
+ StateRec* state = 0; |
+ |
+ while (m_stateStack.count() > 1) { |
+ state = (StateRec *)m_stateStack.back(); |
+ dstCanvas->concat(state->m_ctm); |
+ dstCanvas->clipRect(state->m_clip); |
+ dstCanvas->save(); |
+ state->~StateRec(); |
+ m_stateStack.pop_back(); |
+ } |
+ |
+ state = (StateRec *)m_stateStack.back(); |
+ dstCanvas->concat(state->m_ctm); |
+ dstCanvas->clipRect(state->m_clip); |
+ state->~StateRec(); |
+ m_stateStack.pop_back(); |
+} |
+ |
} // namespace blink |