| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "SkPictureRecord.h" | 8 #include "SkPictureRecord.h" |
| 9 #include "SkImage_Base.h" | 9 #include "SkImage_Base.h" |
| 10 #include "SkPatchUtils.h" | 10 #include "SkPatchUtils.h" |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 this->validate(fWriter.bytesWritten(), 0); | 223 this->validate(fWriter.bytesWritten(), 0); |
| 224 // op + scalar | 224 // op + scalar |
| 225 size_t size = 1 * kUInt32Size + 1 * sizeof(SkScalar); | 225 size_t size = 1 * kUInt32Size + 1 * sizeof(SkScalar); |
| 226 size_t initialOffset = this->addDraw(TRANSLATE_Z, &size); | 226 size_t initialOffset = this->addDraw(TRANSLATE_Z, &size); |
| 227 this->addScalar(z); | 227 this->addScalar(z); |
| 228 this->validate(initialOffset, size); | 228 this->validate(initialOffset, size); |
| 229 this->INHERITED::didTranslateZ(z); | 229 this->INHERITED::didTranslateZ(z); |
| 230 #endif | 230 #endif |
| 231 } | 231 } |
| 232 | 232 |
| 233 static bool regionOpExpands(SkRegion::Op op) { | 233 static bool clipOpExpands(SkCanvas::ClipOp op) { |
| 234 switch (op) { | 234 switch (op) { |
| 235 case SkRegion::kUnion_Op: | 235 case SkCanvas::kUnion_Op: |
| 236 case SkRegion::kXOR_Op: | 236 case SkCanvas::kXOR_Op: |
| 237 case SkRegion::kReverseDifference_Op: | 237 case SkCanvas::kReverseDifference_Op: |
| 238 case SkRegion::kReplace_Op: | 238 case SkCanvas::kReplace_Op: |
| 239 return true; | 239 return true; |
| 240 case SkRegion::kIntersect_Op: | 240 case SkCanvas::kIntersect_Op: |
| 241 case SkRegion::kDifference_Op: | 241 case SkCanvas::kDifference_Op: |
| 242 return false; | 242 return false; |
| 243 default: | 243 default: |
| 244 SkDEBUGFAIL("unknown region op"); | 244 SkDEBUGFAIL("unknown region op"); |
| 245 return false; | 245 return false; |
| 246 } | 246 } |
| 247 } | 247 } |
| 248 | 248 |
| 249 void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t
restoreOffset) { | 249 void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t
restoreOffset) { |
| 250 int32_t offset = fRestoreOffsetStack.top(); | 250 int32_t offset = fRestoreOffsetStack.top(); |
| 251 while (offset > 0) { | 251 while (offset > 0) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 272 // recorded. This is balanced by restoreToCount() call from endRecording, | 272 // recorded. This is balanced by restoreToCount() call from endRecording, |
| 273 // which in-turn calls our overridden restore(), so those get recorded too. | 273 // which in-turn calls our overridden restore(), so those get recorded too. |
| 274 fInitialSaveCount = this->save(); | 274 fInitialSaveCount = this->save(); |
| 275 } | 275 } |
| 276 | 276 |
| 277 void SkPictureRecord::endRecording() { | 277 void SkPictureRecord::endRecording() { |
| 278 SkASSERT(kNoInitialSave != fInitialSaveCount); | 278 SkASSERT(kNoInitialSave != fInitialSaveCount); |
| 279 this->restoreToCount(fInitialSaveCount); | 279 this->restoreToCount(fInitialSaveCount); |
| 280 } | 280 } |
| 281 | 281 |
| 282 size_t SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) { | 282 size_t SkPictureRecord::recordRestoreOffsetPlaceholder(ClipOp op) { |
| 283 if (fRestoreOffsetStack.isEmpty()) { | 283 if (fRestoreOffsetStack.isEmpty()) { |
| 284 return -1; | 284 return -1; |
| 285 } | 285 } |
| 286 | 286 |
| 287 // The RestoreOffset field is initially filled with a placeholder | 287 // The RestoreOffset field is initially filled with a placeholder |
| 288 // value that points to the offset of the previous RestoreOffset | 288 // value that points to the offset of the previous RestoreOffset |
| 289 // in the current stack level, thus forming a linked list so that | 289 // in the current stack level, thus forming a linked list so that |
| 290 // the restore offsets can be filled in when the corresponding | 290 // the restore offsets can be filled in when the corresponding |
| 291 // restore command is recorded. | 291 // restore command is recorded. |
| 292 int32_t prevOffset = fRestoreOffsetStack.top(); | 292 int32_t prevOffset = fRestoreOffsetStack.top(); |
| 293 | 293 |
| 294 if (regionOpExpands(op)) { | 294 if (clipOpExpands(op)) { |
| 295 // Run back through any previous clip ops, and mark their offset to | 295 // Run back through any previous clip ops, and mark their offset to |
| 296 // be 0, disabling their ability to trigger a jump-to-restore, otherwise | 296 // be 0, disabling their ability to trigger a jump-to-restore, otherwise |
| 297 // they could hide this clips ability to expand the clip (i.e. go from | 297 // they could hide this clips ability to expand the clip (i.e. go from |
| 298 // empty to non-empty). | 298 // empty to non-empty). |
| 299 this->fillRestoreOffsetPlaceholdersForCurrentStackLevel(0); | 299 this->fillRestoreOffsetPlaceholdersForCurrentStackLevel(0); |
| 300 | 300 |
| 301 // Reset the pointer back to the previous clip so that subsequent | 301 // Reset the pointer back to the previous clip so that subsequent |
| 302 // restores don't overwrite the offsets we just cleared. | 302 // restores don't overwrite the offsets we just cleared. |
| 303 prevOffset = 0; | 303 prevOffset = 0; |
| 304 } | 304 } |
| 305 | 305 |
| 306 size_t offset = fWriter.bytesWritten(); | 306 size_t offset = fWriter.bytesWritten(); |
| 307 this->addInt(prevOffset); | 307 this->addInt(prevOffset); |
| 308 fRestoreOffsetStack.top() = SkToU32(offset); | 308 fRestoreOffsetStack.top() = SkToU32(offset); |
| 309 return offset; | 309 return offset; |
| 310 } | 310 } |
| 311 | 311 |
| 312 void SkPictureRecord::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeSt
yle edgeStyle) { | 312 void SkPictureRecord::onClipRect(const SkRect& rect, SkCanvas::ClipOp op, ClipEd
geStyle edgeStyle) { |
| 313 this->recordClipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle); | 313 this->recordClipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle); |
| 314 this->INHERITED::onClipRect(rect, op, edgeStyle); | 314 this->INHERITED::onClipRect(rect, op, edgeStyle); |
| 315 } | 315 } |
| 316 | 316 |
| 317 size_t SkPictureRecord::recordClipRect(const SkRect& rect, SkRegion::Op op, bool
doAA) { | 317 size_t SkPictureRecord::recordClipRect(const SkRect& rect, SkCanvas::ClipOp op,
bool doAA) { |
| 318 // id + rect + clip params | 318 // id + rect + clip params |
| 319 size_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; | 319 size_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; |
| 320 // recordRestoreOffsetPlaceholder doesn't always write an offset | 320 // recordRestoreOffsetPlaceholder doesn't always write an offset |
| 321 if (!fRestoreOffsetStack.isEmpty()) { | 321 if (!fRestoreOffsetStack.isEmpty()) { |
| 322 // + restore offset | 322 // + restore offset |
| 323 size += kUInt32Size; | 323 size += kUInt32Size; |
| 324 } | 324 } |
| 325 size_t initialOffset = this->addDraw(CLIP_RECT, &size); | 325 size_t initialOffset = this->addDraw(CLIP_RECT, &size); |
| 326 this->addRect(rect); | 326 this->addRect(rect); |
| 327 this->addInt(ClipParams_pack(op, doAA)); | 327 this->addInt(ClipParams_pack(op, doAA)); |
| 328 size_t offset = this->recordRestoreOffsetPlaceholder(op); | 328 size_t offset = this->recordRestoreOffsetPlaceholder(op); |
| 329 | 329 |
| 330 this->validate(initialOffset, size); | 330 this->validate(initialOffset, size); |
| 331 return offset; | 331 return offset; |
| 332 } | 332 } |
| 333 | 333 |
| 334 void SkPictureRecord::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdg
eStyle edgeStyle) { | 334 void SkPictureRecord::onClipRRect(const SkRRect& rrect, SkCanvas::ClipOp op, Cli
pEdgeStyle edgeStyle) { |
| 335 this->recordClipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle); | 335 this->recordClipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle); |
| 336 this->INHERITED::onClipRRect(rrect, op, edgeStyle); | 336 this->INHERITED::onClipRRect(rrect, op, edgeStyle); |
| 337 } | 337 } |
| 338 | 338 |
| 339 size_t SkPictureRecord::recordClipRRect(const SkRRect& rrect, SkRegion::Op op, b
ool doAA) { | 339 size_t SkPictureRecord::recordClipRRect(const SkRRect& rrect, SkCanvas::ClipOp o
p, bool doAA) { |
| 340 // op + rrect + clip params | 340 // op + rrect + clip params |
| 341 size_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; | 341 size_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; |
| 342 // recordRestoreOffsetPlaceholder doesn't always write an offset | 342 // recordRestoreOffsetPlaceholder doesn't always write an offset |
| 343 if (!fRestoreOffsetStack.isEmpty()) { | 343 if (!fRestoreOffsetStack.isEmpty()) { |
| 344 // + restore offset | 344 // + restore offset |
| 345 size += kUInt32Size; | 345 size += kUInt32Size; |
| 346 } | 346 } |
| 347 size_t initialOffset = this->addDraw(CLIP_RRECT, &size); | 347 size_t initialOffset = this->addDraw(CLIP_RRECT, &size); |
| 348 this->addRRect(rrect); | 348 this->addRRect(rrect); |
| 349 this->addInt(ClipParams_pack(op, doAA)); | 349 this->addInt(ClipParams_pack(op, doAA)); |
| 350 size_t offset = recordRestoreOffsetPlaceholder(op); | 350 size_t offset = recordRestoreOffsetPlaceholder(op); |
| 351 this->validate(initialOffset, size); | 351 this->validate(initialOffset, size); |
| 352 return offset; | 352 return offset; |
| 353 } | 353 } |
| 354 | 354 |
| 355 void SkPictureRecord::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeSt
yle edgeStyle) { | 355 void SkPictureRecord::onClipPath(const SkPath& path, SkCanvas::ClipOp op, ClipEd
geStyle edgeStyle) { |
| 356 int pathID = this->addPathToHeap(path); | 356 int pathID = this->addPathToHeap(path); |
| 357 this->recordClipPath(pathID, op, kSoft_ClipEdgeStyle == edgeStyle); | 357 this->recordClipPath(pathID, op, kSoft_ClipEdgeStyle == edgeStyle); |
| 358 this->INHERITED::onClipPath(path, op, edgeStyle); | 358 this->INHERITED::onClipPath(path, op, edgeStyle); |
| 359 } | 359 } |
| 360 | 360 |
| 361 size_t SkPictureRecord::recordClipPath(int pathID, SkRegion::Op op, bool doAA) { | 361 size_t SkPictureRecord::recordClipPath(int pathID, SkCanvas::ClipOp op, bool doA
A) { |
| 362 // op + path index + clip params | 362 // op + path index + clip params |
| 363 size_t size = 3 * kUInt32Size; | 363 size_t size = 3 * kUInt32Size; |
| 364 // recordRestoreOffsetPlaceholder doesn't always write an offset | 364 // recordRestoreOffsetPlaceholder doesn't always write an offset |
| 365 if (!fRestoreOffsetStack.isEmpty()) { | 365 if (!fRestoreOffsetStack.isEmpty()) { |
| 366 // + restore offset | 366 // + restore offset |
| 367 size += kUInt32Size; | 367 size += kUInt32Size; |
| 368 } | 368 } |
| 369 size_t initialOffset = this->addDraw(CLIP_PATH, &size); | 369 size_t initialOffset = this->addDraw(CLIP_PATH, &size); |
| 370 this->addInt(pathID); | 370 this->addInt(pathID); |
| 371 this->addInt(ClipParams_pack(op, doAA)); | 371 this->addInt(ClipParams_pack(op, doAA)); |
| 372 size_t offset = recordRestoreOffsetPlaceholder(op); | 372 size_t offset = recordRestoreOffsetPlaceholder(op); |
| 373 this->validate(initialOffset, size); | 373 this->validate(initialOffset, size); |
| 374 return offset; | 374 return offset; |
| 375 } | 375 } |
| 376 | 376 |
| 377 void SkPictureRecord::onClipRegion(const SkRegion& region, SkRegion::Op op) { | 377 void SkPictureRecord::onClipRegion(const SkRegion& region, ClipOp op) { |
| 378 this->recordClipRegion(region, op); | 378 this->recordClipRegion(region, op); |
| 379 this->INHERITED::onClipRegion(region, op); | 379 this->INHERITED::onClipRegion(region, op); |
| 380 } | 380 } |
| 381 | 381 |
| 382 size_t SkPictureRecord::recordClipRegion(const SkRegion& region, SkRegion::Op op
) { | 382 size_t SkPictureRecord::recordClipRegion(const SkRegion& region, ClipOp op) { |
| 383 // op + clip params + region | 383 // op + clip params + region |
| 384 size_t size = 2 * kUInt32Size + region.writeToMemory(nullptr); | 384 size_t size = 2 * kUInt32Size + region.writeToMemory(nullptr); |
| 385 // recordRestoreOffsetPlaceholder doesn't always write an offset | 385 // recordRestoreOffsetPlaceholder doesn't always write an offset |
| 386 if (!fRestoreOffsetStack.isEmpty()) { | 386 if (!fRestoreOffsetStack.isEmpty()) { |
| 387 // + restore offset | 387 // + restore offset |
| 388 size += kUInt32Size; | 388 size += kUInt32Size; |
| 389 } | 389 } |
| 390 size_t initialOffset = this->addDraw(CLIP_REGION, &size); | 390 size_t initialOffset = this->addDraw(CLIP_REGION, &size); |
| 391 this->addRegion(region); | 391 this->addRegion(region); |
| 392 this->addInt(ClipParams_pack(op, false)); | 392 this->addInt(ClipParams_pack(op, false)); |
| (...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 985 addInt(SkToInt(byteLength)); | 985 addInt(SkToInt(byteLength)); |
| 986 fWriter.writePad(text, byteLength); | 986 fWriter.writePad(text, byteLength); |
| 987 } | 987 } |
| 988 | 988 |
| 989 void SkPictureRecord::addTextBlob(const SkTextBlob* blob) { | 989 void SkPictureRecord::addTextBlob(const SkTextBlob* blob) { |
| 990 // follow the convention of recording a 1-based index | 990 // follow the convention of recording a 1-based index |
| 991 this->addInt(find_or_append_uniqueID(fTextBlobRefs, blob) + 1); | 991 this->addInt(find_or_append_uniqueID(fTextBlobRefs, blob) + 1); |
| 992 } | 992 } |
| 993 | 993 |
| 994 /////////////////////////////////////////////////////////////////////////////// | 994 /////////////////////////////////////////////////////////////////////////////// |
| OLD | NEW |