Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: Source/platform/graphics/RecordingImageBufferSurface.cpp

Issue 501353002: Transfer canvas state to the next frame with noticable restrictions. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: [WIP] first patch to check my approach Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 6
7 #include "platform/graphics/RecordingImageBufferSurface.h" 7 #include "platform/graphics/RecordingImageBufferSurface.h"
8 8
9 #include "platform/graphics/GraphicsContext.h" 9 #include "platform/graphics/GraphicsContext.h"
10 #include "platform/graphics/ImageBuffer.h" 10 #include "platform/graphics/ImageBuffer.h"
11 #include "public/platform/Platform.h" 11 #include "public/platform/Platform.h"
12 #include "third_party/skia/include/core/SkCanvas.h" 12 #include "third_party/skia/include/core/SkCanvas.h"
13 #include "third_party/skia/include/core/SkPictureRecorder.h" 13 #include "third_party/skia/include/core/SkPictureRecorder.h"
14 #include "wtf/PassOwnPtr.h" 14 #include "wtf/PassOwnPtr.h"
15 #include "wtf/PassRefPtr.h" 15 #include "wtf/PassRefPtr.h"
16 16
17 namespace blink { 17 namespace blink {
18 18
19 struct RecordingImageBufferSurface::StateRec {
20 public:
21 SkMatrix m_ctm;
22 SkRect m_clip;
23 };
24
19 RecordingImageBufferSurface::RecordingImageBufferSurface(const IntSize& size, Op acityMode opacityMode) 25 RecordingImageBufferSurface::RecordingImageBufferSurface(const IntSize& size, Op acityMode opacityMode)
20 : ImageBufferSurface(size, opacityMode) 26 : ImageBufferSurface(size, opacityMode)
21 , m_imageBuffer(0) 27 , m_imageBuffer(0)
22 , m_initialSaveCount(0) 28 , m_initialSaveCount(0)
23 , m_frameWasCleared(true) 29 , m_frameWasCleared(true)
30 , m_stateStack(sizeof(StateRec), m_stateStackStorage, sizeof(m_stateStackSto rage))
24 { 31 {
25 initializeCurrentFrame(); 32 initializeCurrentFrame();
26 } 33 }
27 34
28 RecordingImageBufferSurface::~RecordingImageBufferSurface() 35 RecordingImageBufferSurface::~RecordingImageBufferSurface()
29 { } 36 { }
30 37
31 void RecordingImageBufferSurface::initializeCurrentFrame() 38 void RecordingImageBufferSurface::initializeCurrentFrame()
32 { 39 {
33 static SkRTreeFactory rTreeFactory; 40 static SkRTreeFactory rTreeFactory;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 118
112 void RecordingImageBufferSurface::didClearCanvas() 119 void RecordingImageBufferSurface::didClearCanvas()
113 { 120 {
114 m_frameWasCleared = true; 121 m_frameWasCleared = true;
115 } 122 }
116 123
117 bool RecordingImageBufferSurface::finalizeFrameInternal() 124 bool RecordingImageBufferSurface::finalizeFrameInternal()
118 { 125 {
119 if (!m_imageBuffer->isDirty()) { 126 if (!m_imageBuffer->isDirty()) {
120 if (m_currentFrame && !m_previousFrame) { 127 if (m_currentFrame && !m_previousFrame) {
121 // Create an initial blank frame
122 m_previousFrame = adoptRef(m_currentFrame->endRecording()); 128 m_previousFrame = adoptRef(m_currentFrame->endRecording());
123 initializeCurrentFrame(); 129 initializeCurrentFrame();
124 } 130 }
125 return m_currentFrame; 131 return m_currentFrame;
126 } 132 }
127 133
128 if (!m_currentFrame) { 134 if (!m_currentFrame) {
129 return false; 135 return false;
130 } 136 }
131 137
132 IntRect canvasRect(IntPoint(0, 0), size()); 138 IntRect canvasRect(IntPoint(0, 0), size());
133 if (!m_frameWasCleared && !m_imageBuffer->context()->opaqueRegion().asRect() .contains(canvasRect)) { 139 if (!m_frameWasCleared && !m_imageBuffer->context()->opaqueRegion().asRect() .contains(canvasRect)) {
134 return false; 140 return false;
135 } 141 }
136 142
137 SkCanvas* oldCanvas = m_currentFrame->getRecordingCanvas(); // Could be rast er or picture 143 if (!saveState(m_currentFrame->getRecordingCanvas()))
138
139 // FIXME(crbug.com/392614): handle transferring complex state from the curre nt picture to the new one.
140 if (oldCanvas->getSaveCount() > m_initialSaveCount)
141 return false; 144 return false;
142 145
143 if (!oldCanvas->isClipRect())
144 return false;
145
146 SkMatrix ctm = oldCanvas->getTotalMatrix();
147 SkRect clip;
148 oldCanvas->getClipBounds(&clip);
149
150 m_previousFrame = adoptRef(m_currentFrame->endRecording()); 146 m_previousFrame = adoptRef(m_currentFrame->endRecording());
151 initializeCurrentFrame(); 147 initializeCurrentFrame();
152 148
153 SkCanvas* newCanvas = m_currentFrame->getRecordingCanvas(); 149 setCurrentState(m_currentFrame->getRecordingCanvas());
154 newCanvas->concat(ctm);
155 newCanvas->clipRect(clip);
156 150
157 m_frameWasCleared = false; 151 m_frameWasCleared = false;
158 return true; 152 return true;
159 } 153 }
160 154
155 bool RecordingImageBufferSurface::saveState(SkCanvas* srcCanvas)
156 {
157 // FIXME(crbug.com/392614): handle transferring complex state from the curre nt picture to the new one:
158 // - 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.
159 // - non-invertable clip
Justin Novosad 2014/08/26 16:57:20 "non-invertible"
Sergey 2014/08/28 09:55:33 Done.
160 StateRec* state = 0;
161
162 if (!srcCanvas->isClipRect())
163 return false;
164
165 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.
166 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.
167 state->~StateRec();
168 m_stateStack.pop_back();
169 }
170
171 // we will remove all the saved state stack in endRecording anyway, so it ma kes no difference
172 while (srcCanvas->getSaveCount() > m_initialSaveCount) {
173 state = (StateRec *)m_stateStack.push_back();
174 state->m_ctm = srcCanvas->getTotalMatrix();
175 srcCanvas->getClipBounds(&state->m_clip);
176 srcCanvas->restore();
177 if (!srcCanvas->isClipRect())
178 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
179 }
180
181 state = (StateRec *)m_stateStack.push_back();
182 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
183 state->m_ctm = srcCanvas->getTotalMatrix();
184 srcCanvas->getClipBounds(&state->m_clip);
185
186 return true;
187 }
188
189 void RecordingImageBufferSurface::setCurrentState(SkCanvas* dstCanvas)
190 {
191 StateRec* state = 0;
192
193 while (m_stateStack.count() > 1) {
194 state = (StateRec *)m_stateStack.back();
195 dstCanvas->concat(state->m_ctm);
196 dstCanvas->clipRect(state->m_clip);
197 dstCanvas->save();
198 state->~StateRec();
199 m_stateStack.pop_back();
200 }
201
202 state = (StateRec *)m_stateStack.back();
203 dstCanvas->concat(state->m_ctm);
204 dstCanvas->clipRect(state->m_clip);
205 state->~StateRec();
206 m_stateStack.pop_back();
207 }
208
161 } // namespace blink 209 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698