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

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

Issue 249453002: First step in pulling SkPicturePlayback & SkPictureRecord out of SkPicture (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: cleanup Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/core/SkBBoxRecord.h ('k') | src/core/SkPicturePlayback.h » ('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 /* 2 /*
3 * Copyright 2007 The Android Open Source Project 3 * Copyright 2007 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #include "SkPictureFlat.h" 10 #include "SkPictureFlat.h"
(...skipping 13 matching lines...) Expand all
24 24
25 #include "SkReader32.h" 25 #include "SkReader32.h"
26 #include "SkWriter32.h" 26 #include "SkWriter32.h"
27 #include "SkRTree.h" 27 #include "SkRTree.h"
28 #include "SkBBoxHierarchyRecord.h" 28 #include "SkBBoxHierarchyRecord.h"
29 29
30 #if SK_SUPPORT_GPU 30 #if SK_SUPPORT_GPU
31 #include "GrContext.h" 31 #include "GrContext.h"
32 #endif 32 #endif
33 33
34 template <typename T> int SafeCount(const T* obj) {
35 return obj ? obj->count() : 0;
36 }
37
34 #define DUMP_BUFFER_SIZE 65536 38 #define DUMP_BUFFER_SIZE 65536
35 39
36 //#define ENABLE_TIME_DRAW // dumps milliseconds for each draw 40 //#define ENABLE_TIME_DRAW // dumps milliseconds for each draw
37 41
38 42
39 #ifdef SK_DEBUG 43 #ifdef SK_DEBUG
40 // enable SK_DEBUG_TRACE to trace DrawType elements when 44 // enable SK_DEBUG_TRACE to trace DrawType elements when
41 // recorded and played back 45 // recorded and played back
42 // #define SK_DEBUG_TRACE 46 // #define SK_DEBUG_TRACE
43 // enable SK_DEBUG_SIZE to see the size of picture components 47 // enable SK_DEBUG_SIZE to see the size of picture components
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 this->needsNewGenID(); 136 this->needsNewGenID();
133 fWidth = src.fWidth; 137 fWidth = src.fWidth;
134 fHeight = src.fHeight; 138 fHeight = src.fHeight;
135 fRecord = NULL; 139 fRecord = NULL;
136 140
137 /* We want to copy the src's playback. However, if that hasn't been built 141 /* We want to copy the src's playback. However, if that hasn't been built
138 yet, we need to fake a call to endRecording() without actually calling 142 yet, we need to fake a call to endRecording() without actually calling
139 it (since it is destructive, and we don't want to change src). 143 it (since it is destructive, and we don't want to change src).
140 */ 144 */
141 if (src.fPlayback) { 145 if (src.fPlayback) {
142 fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fPlayback)); 146 fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *src.fPlayback));
143 SkASSERT(NULL == src.fRecord); 147 SkASSERT(NULL == src.fRecord);
144 fUniqueID = src.uniqueID(); // need to call method to ensure != 0 148 fUniqueID = src.uniqueID(); // need to call method to ensure != 0
145 } else if (src.fRecord) { 149 } else if (src.fRecord) {
146 SkPictInfo info; 150 SkPictInfo info;
147 this->createHeader(&info); 151 this->createHeader(&info);
148 // here we do a fake src.endRecording() 152 // here we do a fake src.endRecording()
149 fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fRecord, info)); 153 fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *src.fRecord, info));
150 } else { 154 } else {
151 fPlayback = NULL; 155 fPlayback = NULL;
152 } 156 }
157
158 fPathHeap.reset(SkSafeRef(src.fPathHeap.get()));
159 }
160
161 const SkPath& SkPicture::getPath(int index) const {
162 return (*fPathHeap.get())[index];
163 }
164
165 int SkPicture::addPathToHeap(const SkPath& path) {
166 if (NULL == fPathHeap) {
167 fPathHeap.reset(SkNEW(SkPathHeap));
168 }
169 #ifdef SK_DEDUP_PICTURE_PATHS
170 return fPathHeap->insert(path);
171 #else
172 return fPathHeap->append(path);
173 #endif
174 }
175
176 void SkPicture::initForPlayback() const {
177 // ensure that the paths bounds are pre-computed
178 if (NULL != fPathHeap.get()) {
179 for (int i = 0; i < fPathHeap->count(); i++) {
180 (*fPathHeap.get())[i].updateBoundsCache();
181 }
182 }
183 }
184
185 void SkPicture::dumpSize() const {
186 SkDebugf("--- picture size: paths=%d\n",
187 SafeCount(fPathHeap.get()));
153 } 188 }
154 189
155 SkPicture::~SkPicture() { 190 SkPicture::~SkPicture() {
156 SkSafeUnref(fRecord); 191 SkSafeUnref(fRecord);
157 SkDELETE(fPlayback); 192 SkDELETE(fPlayback);
158 SkSafeUnref(fAccelData); 193 SkSafeUnref(fAccelData);
159 } 194 }
160 195
161 void SkPicture::internalOnly_EnableOpts(bool enableOpts) { 196 void SkPicture::internalOnly_EnableOpts(bool enableOpts) {
162 if (NULL != fRecord) { 197 if (NULL != fRecord) {
163 fRecord->internalOnly_EnableOpts(enableOpts); 198 fRecord->internalOnly_EnableOpts(enableOpts);
164 } 199 }
165 } 200 }
166 201
167 void SkPicture::swap(SkPicture& other) { 202 void SkPicture::swap(SkPicture& other) {
168 SkTSwap(fUniqueID, other.fUniqueID); 203 SkTSwap(fUniqueID, other.fUniqueID);
169 SkTSwap(fRecord, other.fRecord); 204 SkTSwap(fRecord, other.fRecord);
170 SkTSwap(fPlayback, other.fPlayback); 205 SkTSwap(fPlayback, other.fPlayback);
171 SkTSwap(fAccelData, other.fAccelData); 206 SkTSwap(fAccelData, other.fAccelData);
172 SkTSwap(fWidth, other.fWidth); 207 SkTSwap(fWidth, other.fWidth);
173 SkTSwap(fHeight, other.fHeight); 208 SkTSwap(fHeight, other.fHeight);
209 fPathHeap.swap(&other.fPathHeap);
174 } 210 }
175 211
176 SkPicture* SkPicture::clone() const { 212 SkPicture* SkPicture::clone() const {
177 SkPicture* clonedPicture = SkNEW(SkPicture); 213 SkPicture* clonedPicture = SkNEW(SkPicture);
178 this->clone(clonedPicture, 1); 214 this->clone(clonedPicture, 1);
179 return clonedPicture; 215 return clonedPicture;
180 } 216 }
181 217
182 void SkPicture::clone(SkPicture* pictures, int count) const { 218 void SkPicture::clone(SkPicture* pictures, int count) const {
183 SkPictCopyInfo copyInfo; 219 SkPictCopyInfo copyInfo;
184 SkPictInfo info; 220 SkPictInfo info;
185 this->createHeader(&info); 221 this->createHeader(&info);
186 222
187 for (int i = 0; i < count; i++) { 223 for (int i = 0; i < count; i++) {
188 SkPicture* clone = &pictures[i]; 224 SkPicture* clone = &pictures[i];
189 225
190 clone->needsNewGenID(); 226 clone->needsNewGenID();
191 clone->fWidth = fWidth; 227 clone->fWidth = fWidth;
192 clone->fHeight = fHeight; 228 clone->fHeight = fHeight;
193 SkSafeSetNull(clone->fRecord); 229 SkSafeSetNull(clone->fRecord);
194 SkDELETE(clone->fPlayback); 230 SkDELETE(clone->fPlayback);
195 231
196 /* We want to copy the src's playback. However, if that hasn't been bui lt 232 /* We want to copy the src's playback. However, if that hasn't been bui lt
197 yet, we need to fake a call to endRecording() without actually calli ng 233 yet, we need to fake a call to endRecording() without actually calli ng
198 it (since it is destructive, and we don't want to change src). 234 it (since it is destructive, and we don't want to change src).
199 */ 235 */
200 if (fPlayback) { 236 if (fPlayback) {
201 clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fPlayback, &copyI nfo)); 237 clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (clone, *fPlayback, &copyInfo));
202 SkASSERT(NULL == fRecord); 238 SkASSERT(NULL == fRecord);
203 clone->fUniqueID = this->uniqueID(); // need to call method to ensur e != 0 239 clone->fUniqueID = this->uniqueID(); // need to call method to ensur e != 0
204 } else if (fRecord) { 240 } else if (fRecord) {
205 // here we do a fake src.endRecording() 241 // here we do a fake src.endRecording()
206 clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info, tr ue)); 242 clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (clone, *fRecord, i nfo, true));
207 } else { 243 } else {
208 clone->fPlayback = NULL; 244 clone->fPlayback = NULL;
209 } 245 }
246
247 clone->fPathHeap.reset(SkSafeRef(fPathHeap.get()));
210 } 248 }
211 } 249 }
212 250
213 SkPicture::AccelData::Domain SkPicture::AccelData::GenerateDomain() { 251 SkPicture::AccelData::Domain SkPicture::AccelData::GenerateDomain() {
214 static int32_t gNextID = 0; 252 static int32_t gNextID = 0;
215 253
216 int32_t id = sk_atomic_inc(&gNextID); 254 int32_t id = sk_atomic_inc(&gNextID);
217 if (id >= 1 << (8 * sizeof(Domain))) { 255 if (id >= 1 << (8 * sizeof(Domain))) {
218 SK_CRASH(); 256 SK_CRASH();
219 } 257 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 297
260 SkCanvas* SkPicture::beginRecording(int width, int height, 298 SkCanvas* SkPicture::beginRecording(int width, int height,
261 SkBBHFactory* bbhFactory, 299 SkBBHFactory* bbhFactory,
262 uint32_t recordingFlags) { 300 uint32_t recordingFlags) {
263 if (fPlayback) { 301 if (fPlayback) {
264 SkDELETE(fPlayback); 302 SkDELETE(fPlayback);
265 fPlayback = NULL; 303 fPlayback = NULL;
266 } 304 }
267 SkSafeUnref(fAccelData); 305 SkSafeUnref(fAccelData);
268 SkSafeSetNull(fRecord); 306 SkSafeSetNull(fRecord);
307 SkASSERT(NULL == fPathHeap);
269 308
270 this->needsNewGenID(); 309 this->needsNewGenID();
271 310
272 fWidth = width; 311 fWidth = width;
273 fHeight = height; 312 fHeight = height;
274 313
275 const SkISize size = SkISize::Make(width, height); 314 const SkISize size = SkISize::Make(width, height);
276 315
277 if (NULL != bbhFactory) { 316 if (NULL != bbhFactory) {
278 SkAutoTUnref<SkBBoxHierarchy> tree((*bbhFactory)(width, height)); 317 SkAutoTUnref<SkBBoxHierarchy> tree((*bbhFactory)(width, height));
279 SkASSERT(NULL != tree); 318 SkASSERT(NULL != tree);
280 fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (size, 319 fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (this, size,
281 recordingFlags| 320 recordingFlags|
282 kOptimizeForClippedPlayback _RecordingFlag, 321 kOptimizeForClippedPlayback _RecordingFlag,
283 tree.get())); 322 tree.get()));
284 } else { 323 } else {
285 fRecord = SkNEW_ARGS(SkPictureRecord, (size, recordingFlags)); 324 fRecord = SkNEW_ARGS(SkPictureRecord, (this, size, recordingFlags));
286 } 325 }
287 fRecord->beginRecording(); 326 fRecord->beginRecording();
288 327
289 return fRecord; 328 return fRecord;
290 } 329 }
291 330
292 331
293 #ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES 332 #ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
294 333
295 SkBBoxHierarchy* SkPicture::createBBoxHierarchy() const { 334 SkBBoxHierarchy* SkPicture::createBBoxHierarchy() const {
(...skipping 20 matching lines...) Expand all
316 // will be null if we are not recording 355 // will be null if we are not recording
317 return fRecord; 356 return fRecord;
318 } 357 }
319 358
320 void SkPicture::endRecording() { 359 void SkPicture::endRecording() {
321 if (NULL == fPlayback) { 360 if (NULL == fPlayback) {
322 if (NULL != fRecord) { 361 if (NULL != fRecord) {
323 fRecord->endRecording(); 362 fRecord->endRecording();
324 SkPictInfo info; 363 SkPictInfo info;
325 this->createHeader(&info); 364 this->createHeader(&info);
326 fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info)); 365 fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
327 SkSafeSetNull(fRecord); 366 SkSafeSetNull(fRecord);
328 } 367 }
329 } 368 }
330 SkASSERT(NULL == fRecord); 369 SkASSERT(NULL == fRecord);
331 } 370 }
332 371
333 const SkPicture::OperationList& SkPicture::OperationList::InvalidList() { 372 const SkPicture::OperationList& SkPicture::OperationList::InvalidList() {
334 static OperationList gInvalid; 373 static OperationList gInvalid;
335 return gInvalid; 374 return gInvalid;
336 } 375 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 this->needsNewGenID(); 456 this->needsNewGenID();
418 } 457 }
419 458
420 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro c) { 459 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro c) {
421 SkPictInfo info; 460 SkPictInfo info;
422 461
423 if (!InternalOnly_StreamIsSKP(stream, &info)) { 462 if (!InternalOnly_StreamIsSKP(stream, &info)) {
424 return NULL; 463 return NULL;
425 } 464 }
426 465
427 SkPicturePlayback* playback; 466 SkPicture* newPict = SkNEW_ARGS(SkPicture, (NULL, info.fWidth, info.fHeight) );
467
428 // Check to see if there is a playback to recreate. 468 // Check to see if there is a playback to recreate.
429 if (stream->readBool()) { 469 if (stream->readBool()) {
430 playback = SkPicturePlayback::CreateFromStream(stream, info, proc); 470 SkPicturePlayback* playback = SkPicturePlayback::CreateFromStream(newPic t, stream,
471 info, proc);
431 if (NULL == playback) { 472 if (NULL == playback) {
473 SkDELETE(newPict);
432 return NULL; 474 return NULL;
433 } 475 }
434 } else { 476 newPict->fPlayback = playback;
435 playback = NULL;
436 } 477 }
437 478
438 return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight)); 479 return newPict;
439 } 480 }
440 481
441 SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) { 482 SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) {
442 SkPictInfo info; 483 SkPictInfo info;
443 484
444 if (!InternalOnly_BufferIsSKP(buffer, &info)) { 485 if (!InternalOnly_BufferIsSKP(buffer, &info)) {
445 return NULL; 486 return NULL;
446 } 487 }
447 488
448 SkPicturePlayback* playback; 489 SkPicture* newPict = SkNEW_ARGS(SkPicture, (NULL, info.fWidth, info.fHeight) );
490
449 // Check to see if there is a playback to recreate. 491 // Check to see if there is a playback to recreate.
450 if (buffer.readBool()) { 492 if (buffer.readBool()) {
451 playback = SkPicturePlayback::CreateFromBuffer(buffer, info); 493 SkPicturePlayback* playback = SkPicturePlayback::CreateFromBuffer(newPic t, buffer, info);
452 if (NULL == playback) { 494 if (NULL == playback) {
495 SkDELETE(newPict);
453 return NULL; 496 return NULL;
454 } 497 }
455 } else { 498 newPict->fPlayback = playback;
456 playback = NULL;
457 } 499 }
458 500
459 return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight)); 501 return newPict;
460 } 502 }
461 503
462 void SkPicture::createHeader(SkPictInfo* info) const { 504 void SkPicture::createHeader(SkPictInfo* info) const {
463 // Copy magic bytes at the beginning of the header 505 // Copy magic bytes at the beginning of the header
464 SkASSERT(sizeof(kMagic) == 8); 506 SkASSERT(sizeof(kMagic) == 8);
465 SkASSERT(sizeof(kMagic) == sizeof(info->fMagic)); 507 SkASSERT(sizeof(kMagic) == sizeof(info->fMagic));
466 memcpy(info->fMagic, kMagic, sizeof(kMagic)); 508 memcpy(info->fMagic, kMagic, sizeof(kMagic));
467 509
468 // Set picture info after magic bytes in the header 510 // Set picture info after magic bytes in the header
469 info->fVersion = CURRENT_PICTURE_VERSION; 511 info->fVersion = CURRENT_PICTURE_VERSION;
470 info->fWidth = fWidth; 512 info->fWidth = fWidth;
471 info->fHeight = fHeight; 513 info->fHeight = fHeight;
472 info->fFlags = SkPictInfo::kCrossProcess_Flag; 514 info->fFlags = SkPictInfo::kCrossProcess_Flag;
473 // TODO: remove this flag, since we're always float (now) 515 // TODO: remove this flag, since we're always float (now)
474 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag; 516 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag;
475 517
476 if (8 == sizeof(void*)) { 518 if (8 == sizeof(void*)) {
477 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag; 519 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag;
478 } 520 }
479 } 521 }
480 522
481 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { 523 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
482 SkPicturePlayback* playback = fPlayback; 524 SkPicturePlayback* playback = fPlayback;
483 525
484 SkPictInfo info; 526 SkPictInfo info;
485 this->createHeader(&info); 527 this->createHeader(&info);
486 if (NULL == playback && fRecord) { 528 if (NULL == playback && fRecord) {
487 playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info)); 529 playback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
488 } 530 }
489 531
490 stream->write(&info, sizeof(info)); 532 stream->write(&info, sizeof(info));
491 if (playback) { 533 if (playback) {
492 stream->writeBool(true); 534 stream->writeBool(true);
493 playback->serialize(stream, encoder); 535 playback->serialize(stream, encoder);
494 // delete playback if it is a local version (i.e. cons'd up just now) 536 // delete playback if it is a local version (i.e. cons'd up just now)
495 if (playback != fPlayback) { 537 if (playback != fPlayback) {
496 SkDELETE(playback); 538 SkDELETE(playback);
497 } 539 }
498 } else { 540 } else {
499 stream->writeBool(false); 541 stream->writeBool(false);
500 } 542 }
501 } 543 }
502 544
545 void SkPicture::WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size) {
546 buffer.writeUInt(tag);
547 buffer.writeUInt(SkToU32(size));
548 }
549
550 void SkPicture::WriteTagSize(SkWStream* stream, uint32_t tag, size_t size) {
551 stream->write32(tag);
552 stream->write32(SkToU32(size));
553 }
554
555 bool SkPicture::parseBufferTag(SkReadBuffer& buffer,
556 uint32_t tag,
557 uint32_t size) {
558 switch (tag) {
559 case SK_PICT_PATH_BUFFER_TAG:
560 if (size > 0) {
561 fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
562 }
563 break;
564 default:
565 // The tag was invalid.
566 return false;
567 }
568
569 return true; // success
570 }
571
572 void SkPicture::flattenToBuffer(SkWriteBuffer& buffer) const {
573 int n;
574
575 if ((n = SafeCount(fPathHeap.get())) > 0) {
576 WriteTagSize(buffer, SK_PICT_PATH_BUFFER_TAG, n);
577 fPathHeap->flatten(buffer);
578 }
579 }
580
503 void SkPicture::flatten(SkWriteBuffer& buffer) const { 581 void SkPicture::flatten(SkWriteBuffer& buffer) const {
504 SkPicturePlayback* playback = fPlayback; 582 SkPicturePlayback* playback = fPlayback;
505 583
506 SkPictInfo info; 584 SkPictInfo info;
507 this->createHeader(&info); 585 this->createHeader(&info);
508 if (NULL == playback && fRecord) { 586 if (NULL == playback && fRecord) {
509 playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info)); 587 playback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
510 } 588 }
511 589
512 buffer.writeByteArray(&info, sizeof(info)); 590 buffer.writeByteArray(&info, sizeof(info));
513 if (playback) { 591 if (playback) {
514 buffer.writeBool(true); 592 buffer.writeBool(true);
515 playback->flatten(buffer); 593 playback->flatten(buffer);
516 // delete playback if it is a local version (i.e. cons'd up just now) 594 // delete playback if it is a local version (i.e. cons'd up just now)
517 if (playback != fPlayback) { 595 if (playback != fPlayback) {
518 SkDELETE(playback); 596 SkDELETE(playback);
519 } 597 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 if (NULL != fRecord) { 638 if (NULL != fRecord) {
561 SkASSERT(NULL == fPlayback); 639 SkASSERT(NULL == fPlayback);
562 return SK_InvalidGenID; 640 return SK_InvalidGenID;
563 } 641 }
564 642
565 if (SK_InvalidGenID == fUniqueID) { 643 if (SK_InvalidGenID == fUniqueID) {
566 fUniqueID = next_picture_generation_id(); 644 fUniqueID = next_picture_generation_id();
567 } 645 }
568 return fUniqueID; 646 return fUniqueID;
569 } 647 }
OLDNEW
« no previous file with comments | « src/core/SkBBoxRecord.h ('k') | src/core/SkPicturePlayback.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698