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