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

Side by Side Diff: src/core/SkRecordDraw.cpp

Issue 496963003: Fix saveLayer() with a pixel-moving filter vs SkBBoxHierarchyRecord / SkRecordDraw (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 4 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
« no previous file with comments | « src/core/SkBBoxHierarchyRecord.cpp ('k') | tests/ImageFilterTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkRecordDraw.h" 8 #include "SkRecordDraw.h"
9 #include "SkTSort.h" 9 #include "SkTSort.h"
10 10
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 this->trackBounds(op); 153 this->trackBounds(op);
154 } 154 }
155 155
156 private: 156 private:
157 struct SaveBounds { 157 struct SaveBounds {
158 int controlOps; // Number of control ops in this Save block, incl uding the Save. 158 int controlOps; // Number of control ops in this Save block, incl uding the Save.
159 SkIRect bounds; // Bounds of everything in the block. 159 SkIRect bounds; // Bounds of everything in the block.
160 const SkPaint* paint; // Unowned. If set, adjusts the bounds of all op s in this block. 160 const SkPaint* paint; // Unowned. If set, adjusts the bounds of all op s in this block.
161 }; 161 };
162 162
163 static bool PaintMayAffectTransparentBlack(const SkPaint* paint) {
164 // FIXME: this is very conservative
165 return paint && (paint->getImageFilter() || paint->getColorFilter());
166 }
167
163 template <typename T> void updateCTM(const T&) { /* most ops don't change th e CTM */ } 168 template <typename T> void updateCTM(const T&) { /* most ops don't change th e CTM */ }
164 void updateCTM(const Restore& op) { fCTM = &op.matrix; } 169 void updateCTM(const Restore& op) { fCTM = &op.matrix; }
165 void updateCTM(const SetMatrix& op) { fCTM = &op.matrix; } 170 void updateCTM(const SetMatrix& op) { fCTM = &op.matrix; }
166 171
167 template <typename T> void updateClipBounds(const T&) { /* most ops don't ch ange the clip */ } 172 template <typename T> void updateClipBounds(const T&) { /* most ops don't ch ange the clip */ }
168 // Each of these devBounds fields is the state of the device bounds after th e op. 173 // Each of these devBounds fields is the state of the device bounds after th e op.
169 // So Restore's devBounds are those bounds saved by its paired Save or SaveL ayer. 174 // So Restore's devBounds are those bounds saved by its paired Save or SaveL ayer.
170 void updateClipBounds(const Restore& op) { fCurrentClipBounds = op.devBou nds; } 175 void updateClipBounds(const Restore& op) { fCurrentClipBounds = op.devBou nds; }
171 void updateClipBounds(const ClipPath& op) { fCurrentClipBounds = op.devBou nds; } 176 void updateClipBounds(const ClipPath& op) { fCurrentClipBounds = op.devBou nds; }
172 void updateClipBounds(const ClipRRect& op) { fCurrentClipBounds = op.devBou nds; } 177 void updateClipBounds(const ClipRRect& op) { fCurrentClipBounds = op.devBou nds; }
173 void updateClipBounds(const ClipRect& op) { fCurrentClipBounds = op.devBou nds; } 178 void updateClipBounds(const ClipRect& op) { fCurrentClipBounds = op.devBou nds; }
174 void updateClipBounds(const ClipRegion& op) { fCurrentClipBounds = op.devBou nds; } 179 void updateClipBounds(const ClipRegion& op) { fCurrentClipBounds = op.devBou nds; }
175 void updateClipBounds(const SaveLayer& op) { 180 void updateClipBounds(const SaveLayer& op) {
176 if (op.bounds) { 181 // Intersect the clip with the SaveLayer bounds, unless the paint affect s transparent black.
182 if (op.bounds && !PaintMayAffectTransparentBlack(op.paint)) {
mtklein 2014/08/22 15:45:58 Just reading again: "Since the bounds we pass to
177 fCurrentClipBounds.intersect(this->adjustAndMap(*op.bounds, op.paint )); 183 fCurrentClipBounds.intersect(this->adjustAndMap(*op.bounds, op.paint ));
178 } 184 }
179 } 185 }
180 186
181 // The bounds of these ops must be calculated when we hit the Restore 187 // The bounds of these ops must be calculated when we hit the Restore
182 // from the bounds of the ops in the same Save block. 188 // from the bounds of the ops in the same Save block.
183 void trackBounds(const Save&) { this->pushSaveBlock(NULL); } 189 void trackBounds(const Save&) { this->pushSaveBlock(NULL); }
184 // TODO: bounds of SaveLayer may be more complicated? 190 // TODO: bounds of SaveLayer may be more complicated?
185 void trackBounds(const SaveLayer& op) { this->pushSaveBlock(op.paint); } 191 void trackBounds(const SaveLayer& op) { this->pushSaveBlock(op.paint); }
186 void trackBounds(const Restore&) { fBounds[fCurrentOp] = this->popSaveBlock( ); } 192 void trackBounds(const Restore&) { fBounds[fCurrentOp] = this->popSaveBlock( ); }
(...skipping 14 matching lines...) Expand all
201 // Starting a new Save block. Push a new entry to represent that. 207 // Starting a new Save block. Push a new entry to represent that.
202 SaveBounds sb = { 0, SkIRect::MakeEmpty(), paint }; 208 SaveBounds sb = { 0, SkIRect::MakeEmpty(), paint };
203 fSaveStack.push(sb); 209 fSaveStack.push(sb);
204 this->pushControl(); 210 this->pushControl();
205 } 211 }
206 212
207 SkIRect popSaveBlock() { 213 SkIRect popSaveBlock() {
208 // We're done the Save block. Apply the block's bounds to all control o ps inside it. 214 // We're done the Save block. Apply the block's bounds to all control o ps inside it.
209 SaveBounds sb; 215 SaveBounds sb;
210 fSaveStack.pop(&sb); 216 fSaveStack.pop(&sb);
217
218 // If the paint affects transparent black, we can't trust any of our cal culated bounds.
219 const SkIRect& bounds =
220 PaintMayAffectTransparentBlack(sb.paint) ? fCurrentClipBounds : sb.b ounds;
221
211 while (sb.controlOps --> 0) { 222 while (sb.controlOps --> 0) {
212 this->popControl(sb.bounds); 223 this->popControl(bounds);
213 } 224 }
214 225
215 // This whole Save block may be part another Save block. 226 // This whole Save block may be part another Save block.
216 this->updateSaveBounds(sb.bounds); 227 this->updateSaveBounds(bounds);
217 228
218 // If called from a real Restore (not a phony one for balance), it'll ne ed the bounds. 229 // If called from a real Restore (not a phony one for balance), it'll ne ed the bounds.
219 return sb.bounds; 230 return bounds;
220 } 231 }
221 232
222 void pushControl() { 233 void pushControl() {
223 fControlIndices.push(fCurrentOp); 234 fControlIndices.push(fCurrentOp);
224 if (!fSaveStack.isEmpty()) { 235 if (!fSaveStack.isEmpty()) {
225 fSaveStack.top().controlOps++; 236 fSaveStack.top().controlOps++;
226 } 237 }
227 } 238 }
228 239
229 void popControl(const SkIRect& bounds) { 240 void popControl(const SkIRect& bounds) {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 // Used to track the bounds of Save/Restore blocks and the control ops insid e them. 401 // Used to track the bounds of Save/Restore blocks and the control ops insid e them.
391 SkTDArray<SaveBounds> fSaveStack; 402 SkTDArray<SaveBounds> fSaveStack;
392 SkTDArray<unsigned> fControlIndices; 403 SkTDArray<unsigned> fControlIndices;
393 }; 404 };
394 405
395 } // namespace SkRecords 406 } // namespace SkRecords
396 407
397 void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) { 408 void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) {
398 SkRecords::FillBounds(record, bbh); 409 SkRecords::FillBounds(record, bbh);
399 } 410 }
OLDNEW
« no previous file with comments | « src/core/SkBBoxHierarchyRecord.cpp ('k') | tests/ImageFilterTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698