1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include <new> 9 10 #include "SkAutoMalloc.h" 11 #include "SkImageGenerator.h" 12 #include "SkPictureData.h" 13 #include "SkPictureRecord.h" 14 #include "SkReadBuffer.h" 15 #include "SkTextBlob.h" 16 #include "SkTypeface.h" 17 #include "SkWriteBuffer.h" 18 19 #if SK_SUPPORT_GPU 20 #include "GrContext.h" 21 #endif 22 23 template <typename T> int SafeCount(const T* obj) { 24 return obj ? obj->count() : 0; 25 } 26 27 SkPictureData::SkPictureData(const SkPictInfo& info) 28 : fInfo(info) { 29 this->init(); 30 } 31 32 void SkPictureData::initForPlayback() const { 33 // ensure that the paths bounds are pre-computed 34 for (int i = 0; i < fPaths.count(); i++) { 35 fPaths[i].updateBoundsCache(); 36 } 37 } 38 39 SkPictureData::SkPictureData(const SkPictureRecord& record, 40 const SkPictInfo& info) 41 : fInfo(info) { 42 43 this->init(); 44 45 fOpData = record.opData(); 46 47 fPaints = record.fPaints; 48 49 fPaths.reset(record.fPaths.count()); 50 record.fPaths.foreach([this](const SkPath& path, int n) { 51 // These indices are logically 1-based, but we need to serialize them 52 // 0-based to keep the deserializing SkPictureData::getPath() working. 53 fPaths[n-1] = path; 54 }); 55 56 this->initForPlayback(); 57 58 const SkTDArray<const SkPicture* >& pictures = record.getPictureRefs(); 59 fPictureCount = pictures.count(); 60 if (fPictureCount > 0) { 61 fPictureRefs = new const SkPicture* [fPictureCount]; 62 for (int i = 0; i < fPictureCount; i++) { 63 fPictureRefs[i] = pictures[i]; 64 fPictureRefs[i]->ref(); 65 } 66 } 67 68 const SkTDArray<SkDrawable* >& drawables = record.getDrawableRefs(); 69 fDrawableCount = drawables.count(); 70 if (fDrawableCount > 0) { 71 fDrawableRefs = new SkDrawable* [fDrawableCount]; 72 for (int i = 0; i < fDrawableCount; i++) { 73 fDrawableRefs[i] = drawables[i]; 74 fDrawableRefs[i]->ref(); 75 } 76 } 77 78 // templatize to consolidate with similar picture logic? 79 const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs(); 80 fTextBlobCount = blobs.count(); 81 if (fTextBlobCount > 0) { 82 fTextBlobRefs = new const SkTextBlob* [fTextBlobCount]; 83 for (int i = 0; i < fTextBlobCount; ++i) { 84 fTextBlobRefs[i] = SkRef(blobs[i]); 85 } 86 } 87 88 const SkTDArray<const SkVertices*>& verts = record.getVerticesRefs(); 89 fVerticesCount = verts.count(); 90 if (fVerticesCount > 0) { 91 fVerticesRefs = new const SkVertices* [fVerticesCount]; 92 for (int i = 0; i < fVerticesCount; ++i) { 93 fVerticesRefs[i] = SkRef(verts[i]); 94 } 95 } 96 97 const SkTDArray<const SkImage*>& imgs = record.getImageRefs(); 98 fImageCount = imgs.count(); 99 if (fImageCount > 0) { 100 fImageRefs = new const SkImage* [fImageCount]; 101 for (int i = 0; i < fImageCount; ++i) { 102 fImageRefs[i] = SkRef(imgs[i]); 103 } 104 } 105 } 106 107 void SkPictureData::init() { 108 fPictureRefs = nullptr; 109 fPictureCount = 0; 110 fDrawableRefs = nullptr; 111 fDrawableCount = 0; 112 fTextBlobRefs = nullptr; 113 fTextBlobCount = 0; 114 fVerticesRefs = nullptr; 115 fVerticesCount = 0; 116 fImageRefs = nullptr; 117 fImageCount = 0; 118 fBitmapImageCount = 0; 119 fBitmapImageRefs = nullptr; 120 fFactoryPlayback = nullptr; 121 } 122 123 SkPictureData::~SkPictureData() { 124 for (int i = 0; i < fPictureCount; i++) { 125 fPictureRefs[i]->unref(); 126 } 127 delete[] fPictureRefs; 128 129 for (int i = 0; i < fDrawableCount; i++) { 130 fDrawableRefs[i]->unref(); 131 } 132 if (fDrawableCount > 0) { 133 SkASSERT(fDrawableRefs); 134 delete[] fDrawableRefs; 135 } 136 137 for (int i = 0; i < fTextBlobCount; i++) { 138 fTextBlobRefs[i]->unref(); 139 } 140 delete[] fTextBlobRefs; 141 142 for (int i = 0; i < fVerticesCount; i++) { 143 fVerticesRefs[i]->unref(); 144 } 145 delete[] fVerticesRefs; 146 147 for (int i = 0; i < fImageCount; i++) { 148 fImageRefs[i]->unref(); 149 } 150 delete[] fImageRefs; 151 152 delete fFactoryPlayback; 153 } 154 155 /////////////////////////////////////////////////////////////////////////////// 156 /////////////////////////////////////////////////////////////////////////////// 157 158 #include "SkStream.h" 159 160 static size_t compute_chunk_size(SkFlattenable::Factory* array, int count) { 161 size_t size = 4; // for 'count' 162 163 for (int i = 0; i < count; i++) { 164 const char* name = SkFlattenable::FactoryToName(array[i]); 165 if (nullptr == name || 0 == *name) { 166 size += SkWStream::SizeOfPackedUInt(0); 167 } else { 168 size_t len = strlen(name); 169 size += SkWStream::SizeOfPackedUInt(len); 170 size += len; 171 } 172 } 173 174 return size; 175 } 176 177 static void write_tag_size(SkWriteBuffer& buffer, uint32_t tag, size_t size) { 178 buffer.writeUInt(tag); 179 buffer.writeUInt(SkToU32(size)); 180 } 181 182 static void write_tag_size(SkWStream* stream, uint32_t tag, size_t size) { 183 stream->write32(tag); 184 stream->write32(SkToU32(size)); 185 } 186 187 void SkPictureData::WriteFactories(SkWStream* stream, const SkFactorySet& rec) { 188 int count = rec.count(); 189 190 SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count); 191 SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get(); 192 rec.copyToArray(array); 193 194 size_t size = compute_chunk_size(array, count); 195 196 // TODO: write_tag_size should really take a size_t 197 write_tag_size(stream, SK_PICT_FACTORY_TAG, (uint32_t) size); 198 SkDEBUGCODE(size_t start = stream->bytesWritten()); 199 stream->write32(count); 200 201 for (int i = 0; i < count; i++) { 202 const char* name = SkFlattenable::FactoryToName(array[i]); 203 if (nullptr == name || 0 == *name) { 204 stream->writePackedUInt(0); 205 } else { 206 size_t len = strlen(name); 207 stream->writePackedUInt(len); 208 stream->write(name, len); 209 } 210 } 211 212 SkASSERT(size == (stream->bytesWritten() - start)); 213 } 214 215 void SkPictureData::WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec) { 216 int count = rec.count(); 217 218 write_tag_size(stream, SK_PICT_TYPEFACE_TAG, count); 219 220 SkAutoSTMalloc<16, SkTypeface*> storage(count); 221 SkTypeface** array = (SkTypeface**)storage.get(); 222 rec.copyToArray((SkRefCnt**)array); 223 224 for (int i = 0; i < count; i++) { 225 array[i]->serialize(stream); 226 } 227 } 228 229 void SkPictureData::flattenToBuffer(SkWriteBuffer& buffer) const { 230 int i, n; 231 232 if ((n = fPaints.count()) > 0) { 233 write_tag_size(buffer, SK_PICT_PAINT_BUFFER_TAG, n); 234 for (i = 0; i < n; i++) { 235 buffer.writePaint(fPaints[i]); 236 } 237 } 238 239 if ((n = fPaths.count()) > 0) { 240 write_tag_size(buffer, SK_PICT_PATH_BUFFER_TAG, n); 241 buffer.writeInt(n); 242 for (int i = 0; i < n; i++) { 243 buffer.writePath(fPaths[i]); 244 } 245 } 246 247 if (fTextBlobCount > 0) { 248 write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount); 249 for (i = 0; i < fTextBlobCount; ++i) { 250 fTextBlobRefs[i]->flatten(buffer); 251 } 252 } 253 254 if (fVerticesCount > 0) { 255 write_tag_size(buffer, SK_PICT_VERTICES_BUFFER_TAG, fVerticesCount); 256 for (i = 0; i < fVerticesCount; ++i) { 257 buffer.writeDataAsByteArray(fVerticesRefs[i]->encode().get()); 258 } 259 } 260 261 if (fImageCount > 0) { 262 write_tag_size(buffer, SK_PICT_IMAGE_BUFFER_TAG, fImageCount); 263 for (i = 0; i < fImageCount; ++i) { 264 buffer.writeImage(fImageRefs[i]); 265 } 266 } 267 } 268 269 void SkPictureData::serialize(SkWStream* stream, const SkSerialProcs& procs, 270 SkRefCntSet* topLevelTypeFaceSet) const { 271 // This can happen at pretty much any time, so might as well do it first. 272 write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size()); 273 stream->write(fOpData->bytes(), fOpData->size()); 274 275 // We serialize all typefaces into the typeface section of the top-level picture. 276 SkRefCntSet localTypefaceSet; 277 SkRefCntSet* typefaceSet = topLevelTypeFaceSet ? topLevelTypeFaceSet : &localTypefaceSet; 278 279 // We delay serializing the bulk of our data until after we've serialized 280 // factories and typefaces by first serializing to an in-memory write buffer. 281 SkFactorySet factSet; // buffer refs factSet, so factSet must come first. 282 SkBinaryWriteBuffer buffer; 283 buffer.setFactoryRecorder(&factSet); 284 buffer.setSerialProcs(procs); 285 buffer.setTypefaceRecorder(typefaceSet); 286 this->flattenToBuffer(buffer); 287 288 // Dummy serialize our sub-pictures for the side effect of filling 289 // typefaceSet with typefaces from sub-pictures. 290 struct DevNull: public SkWStream { 291 DevNull() : fBytesWritten(0) {} 292 size_t fBytesWritten; 293 bool write(const void*, size_t size) override { fBytesWritten += size; return true; } 294 size_t bytesWritten() const override { return fBytesWritten; } 295 } devnull; 296 for (int i = 0; i < fPictureCount; i++) { 297 fPictureRefs[i]->serialize(&devnull, nullptr, typefaceSet); 298 } 299 300 // We need to write factories before we write the buffer. 301 // We need to write typefaces before we write the buffer or any sub-picture. 302 WriteFactories(stream, factSet); 303 if (typefaceSet == &localTypefaceSet) { 304 WriteTypefaces(stream, *typefaceSet); 305 } 306 307 // Write the buffer. 308 write_tag_size(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten()); 309 buffer.writeToStream(stream); 310 311 // Write sub-pictures by calling serialize again. 312 if (fPictureCount > 0) { 313 write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount); 314 for (int i = 0; i < fPictureCount; i++) { 315 fPictureRefs[i]->serialize(stream, &procs, typefaceSet); 316 } 317 } 318 319 stream->write32(SK_PICT_EOF_TAG); 320 } 321 322 void SkPictureData::flatten(SkWriteBuffer& buffer) const { 323 write_tag_size(buffer, SK_PICT_READER_TAG, fOpData->size()); 324 buffer.writeByteArray(fOpData->bytes(), fOpData->size()); 325 326 if (fPictureCount > 0) { 327 write_tag_size(buffer, SK_PICT_PICTURE_TAG, fPictureCount); 328 for (int i = 0; i < fPictureCount; i++) { 329 fPictureRefs[i]->flatten(buffer); 330 } 331 } 332 333 if (fDrawableCount > 0) { 334 write_tag_size(buffer, SK_PICT_DRAWABLE_TAG, fDrawableCount); 335 for (int i = 0; i < fDrawableCount; i++) { 336 buffer.writeFlattenable(fDrawableRefs[i]); 337 } 338 } 339 340 // Write this picture playback's data into a writebuffer 341 this->flattenToBuffer(buffer); 342 buffer.write32(SK_PICT_EOF_TAG); 343 } 344 345 /////////////////////////////////////////////////////////////////////////////// 346 347 bool SkPictureData::parseStreamTag(SkStream* stream, 348 uint32_t tag, 349 uint32_t size, 350 const SkDeserialProcs& procs, 351 SkTypefacePlayback* topLevelTFPlayback) { 352 /* 353 * By the time we encounter BUFFER_SIZE_TAG, we need to have already seen 354 * its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required 355 * but if they are present, they need to have been seen before the buffer. 356 * 357 * We assert that if/when we see either of these, that we have not yet seen 358 * the buffer tag, because if we have, then its too-late to deal with the 359 * factories or typefaces. 360 */ 361 SkDEBUGCODE(bool haveBuffer = false;) 362 363 switch (tag) { 364 case SK_PICT_READER_TAG: 365 SkASSERT(nullptr == fOpData); 366 fOpData = SkData::MakeFromStream(stream, size); 367 if (!fOpData) { 368 return false; 369 } 370 break; 371 case SK_PICT_FACTORY_TAG: { 372 SkASSERT(!haveBuffer); 373 size = stream->readU32(); 374 fFactoryPlayback = new SkFactoryPlayback(size); 375 for (size_t i = 0; i < size; i++) { 376 SkString str; 377 const size_t len = stream->readPackedUInt(); 378 str.resize(len); 379 if (stream->read(str.writable_str(), len) != len) { 380 return false; 381 } 382 fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str()); 383 } 384 } break; 385 case SK_PICT_TYPEFACE_TAG: { 386 SkASSERT(!haveBuffer); 387 const int count = SkToInt(size); 388 fTFPlayback.setCount(count); 389 for (int i = 0; i < count; i++) { 390 sk_sp<SkTypeface> tf(SkTypeface::MakeDeserialize(stream)); 391 if (!tf.get()) { // failed to deserialize 392 // fTFPlayback asserts it never has a null, so we plop in 393 // the default here. 394 tf = SkTypeface::MakeDefault(); 395 } 396 fTFPlayback.set(i, tf.get()); 397 } 398 } break; 399 case SK_PICT_PICTURE_TAG: { 400 fPictureCount = 0; 401 fPictureRefs = new const SkPicture* [size]; 402 for (uint32_t i = 0; i < size; i++) { 403 fPictureRefs[i] = SkPicture::MakeFromStream(stream, &procs, topLevelTFPlayback).release(); 404 if (!fPictureRefs[i]) { 405 return false; 406 } 407 fPictureCount++; 408 } 409 } break; 410 case SK_PICT_BUFFER_SIZE_TAG: { 411 SkAutoMalloc storage(size); 412 if (stream->read(storage.get(), size) != size) { 413 return false; 414 } 415 416 SkReadBuffer buffer(storage.get(), size); 417 buffer.setVersion(fInfo.getVersion()); 418 419 if (!fFactoryPlayback) { 420 return false; 421 } 422 fFactoryPlayback->setupBuffer(buffer); 423 buffer.setDeserialProcs(procs); 424 425 if (fTFPlayback.count() > 0) { 426 // .skp files <= v43 have typefaces serialized with each sub picture. 427 fTFPlayback.setupBuffer(buffer); 428 } else { 429 // Newer .skp files serialize all typefaces with the top picture. 430 topLevelTFPlayback->setupBuffer(buffer); 431 } 432 433 while (!buffer.eof() && buffer.isValid()) { 434 tag = buffer.readUInt(); 435 size = buffer.readUInt(); 436 this->parseBufferTag(buffer, tag, size); 437 } 438 if (!buffer.isValid()) { 439 return false; 440 } 441 SkDEBUGCODE(haveBuffer = true;) 442 } break; 443 } 444 return true; // success 445 } 446 447 static sk_sp<SkImage> create_image_from_buffer(SkReadBuffer& buffer) { 448 return buffer.readImage(); 449 } 450 static sk_sp<SkVertices> create_vertices_from_buffer(SkReadBuffer& buffer) { 451 auto data = buffer.readByteArrayAsData(); 452 return data ? SkVertices::Decode(data->data(), data->size()) : nullptr; 453 } 454 455 static sk_sp<SkDrawable> create_drawable_from_buffer(SkReadBuffer& buffer) { 456 return sk_sp<SkDrawable>((SkDrawable*)buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); 457 } 458 459 template <typename T> 460 bool new_array_from_buffer(SkReadBuffer& buffer, uint32_t inCount, 461 const T*** array, int* outCount, sk_sp<T> (*factory)(SkReadBuffer&)) { 462 if (!buffer.validate((0 == *outCount) && (nullptr == *array))) { 463 return false; 464 } 465 if (0 == inCount) { 466 return true; 467 } 468 if (!buffer.validate(SkTFitsIn<int>(inCount))) { 469 return false; 470 } 471 472 *outCount = inCount; 473 *array = new const T* [*outCount]; 474 bool success = true; 475 int i = 0; 476 for (; i < *outCount; i++) { 477 (*array)[i] = factory(buffer).release(); 478 if (nullptr == (*array)[i]) { 479 success = false; 480 break; 481 } 482 } 483 if (!success) { 484 // Delete all of the blobs that were already created (up to but excluding i): 485 for (int j = 0; j < i; j++) { 486 (*array)[j]->unref(); 487 } 488 // Delete the array 489 delete[] * array; 490 *array = nullptr; 491 *outCount = 0; 492 return buffer.validate(false); 493 } 494 return true; 495 } 496 497 void SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size) { 498 switch (tag) { 499 case SK_PICT_PAINT_BUFFER_TAG: { 500 if (!buffer.validate(SkTFitsIn<int>(size))) { 501 return; 502 } 503 const int count = SkToInt(size); 504 fPaints.reset(count); 505 for (int i = 0; i < count; ++i) { 506 if (!buffer.readPaint(&fPaints[i])) { 507 return; 508 } 509 } 510 } break; 511 case SK_PICT_PATH_BUFFER_TAG: 512 if (size > 0) { 513 const int count = buffer.readInt(); 514 if (!buffer.validate(count >= 0)) { 515 return; 516 } 517 fPaths.reset(count); 518 for (int i = 0; i < count; i++) { 519 buffer.readPath(&fPaths[i]); 520 } 521 } break; 522 case SK_PICT_TEXTBLOB_BUFFER_TAG: 523 new_array_from_buffer(buffer, size, &fTextBlobRefs, &fTextBlobCount, 524 SkTextBlob::MakeFromBuffer); 525 break; 526 case SK_PICT_VERTICES_BUFFER_TAG: 527 new_array_from_buffer(buffer, size, &fVerticesRefs, &fVerticesCount, 528 create_vertices_from_buffer); 529 break; 530 case SK_PICT_IMAGE_BUFFER_TAG: 531 new_array_from_buffer(buffer, size, &fImageRefs, &fImageCount, 532 create_image_from_buffer); 533 break; 534 case SK_PICT_READER_TAG: { 535 auto data(SkData::MakeUninitialized(size)); 536 if (!buffer.readByteArray(data->writable_data(), size) || 537 !buffer.validate(nullptr == fOpData)) { 538 return; 539 } 540 SkASSERT(nullptr == fOpData); 541 fOpData = std::move(data); 542 } break; 543 case SK_PICT_PICTURE_TAG: 544 new_array_from_buffer(buffer, size, &fPictureRefs, &fPictureCount, 545 SkPicture::MakeFromBuffer); 546 break; 547 case SK_PICT_DRAWABLE_TAG: 548 new_array_from_buffer(buffer, size, (const SkDrawable***)&fDrawableRefs, 549 &fDrawableCount, create_drawable_from_buffer); 550 break; 551 default: 552 buffer.validate(false); // The tag was invalid. 553 break; 554 } 555 } 556 557 SkPictureData* SkPictureData::CreateFromStream(SkStream* stream, 558 const SkPictInfo& info, 559 const SkDeserialProcs& procs, 560 SkTypefacePlayback* topLevelTFPlayback) { 561 std::unique_ptr<SkPictureData> data(new SkPictureData(info)); 562 if (!topLevelTFPlayback) { 563 topLevelTFPlayback = &data->fTFPlayback; 564 } 565 566 if (!data->parseStream(stream, procs, topLevelTFPlayback)) { 567 return nullptr; 568 } 569 return data.release(); 570 } 571 572 SkPictureData* SkPictureData::CreateFromBuffer(SkReadBuffer& buffer, 573 const SkPictInfo& info) { 574 std::unique_ptr<SkPictureData> data(new SkPictureData(info)); 575 buffer.setVersion(info.getVersion()); 576 577 if (!data->parseBuffer(buffer)) { 578 return nullptr; 579 } 580 return data.release(); 581 } 582 583 bool SkPictureData::parseStream(SkStream* stream, 584 const SkDeserialProcs& procs, 585 SkTypefacePlayback* topLevelTFPlayback) { 586 for (;;) { 587 uint32_t tag = stream->readU32(); 588 if (SK_PICT_EOF_TAG == tag) { 589 break; 590 } 591 592 uint32_t size = stream->readU32(); 593 if (!this->parseStreamTag(stream, tag, size, procs, topLevelTFPlayback)) { 594 return false; // we're invalid 595 } 596 } 597 return true; 598 } 599 600 bool SkPictureData::parseBuffer(SkReadBuffer& buffer) { 601 while (buffer.isValid()) { 602 uint32_t tag = buffer.readUInt(); 603 if (SK_PICT_EOF_TAG == tag) { 604 break; 605 } 606 this->parseBufferTag(buffer, tag, buffer.readUInt()); 607 } 608 609 // Check that we encountered required tags 610 if (!buffer.validate(this->opData())) { 611 // If we didn't build any opData, we are invalid. Even an EmptyPicture allocates the 612 // SkData for the ops (though its length may be zero). 613 return false; 614 } 615 return true; 616 } 617