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