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