Chromium Code Reviews| 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 |