180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPicturePlayback.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPictureRecord.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTypeface.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkOrderedReadBuffer.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkOrderedWriteBuffer.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <new>
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBBoxHierarchy.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPictureStateTree.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTSort.h"
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <typename T> int SafeCount(const T* obj) {
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return obj ? obj->count() : 0;
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*  Define this to spew out a debug statement whenever we skip the remainder of
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    a save/restore block because a clip... command returned false (empty).
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SPEW_CLIP_SKIPPINGx
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPicturePlayback::SkPicturePlayback() {
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->init();
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record, bool deepCopy) {
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG_SIZE
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t overallBytes, bitmapBytes, matricesBytes,
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paintBytes, pathBytes, pictureBytes, regionBytes;
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int bitmaps = record.bitmaps(&bitmapBytes);
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int matrices = record.matrices(&matricesBytes);
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int paints = record.paints(&paintBytes);
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int paths = record.paths(&pathBytes);
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int pictures = record.pictures(&pictureBytes);
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int regions = record.regions(&regionBytes);
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("picture record mem used %zd (stream %zd) ", record.size(),
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             record.streamlen());
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (bitmaps != 0)
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps);
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (matrices != 0)
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("matrices size %zd (matrices:%d) ", matricesBytes, matrices);
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (paints != 0)
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("paints size %zd (paints:%d) ", paintBytes, paints);
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (paths != 0)
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths);
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (pictures != 0)
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures);
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (regions != 0)
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions);
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (record.fPointWrites != 0)
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("points size %zd (points:%d) ", record.fPointBytes, record.fPointWrites);
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (record.fRectWrites != 0)
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("rects size %zd (rects:%d) ", record.fRectBytes, record.fRectWrites);
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (record.fTextWrites != 0)
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("text size %zd (text strings:%d) ", record.fTextBytes, record.fTextWrites);
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("\n");
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG_DUMP
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    record.dumpMatrices();
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    record.dumpPaints();
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    record.validate(record.writeStream().bytesWritten(), 0);
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkWriter32& writer = record.writeStream();
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    init();
720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (writer.bytesWritten() == 0) {
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fOpData = SkData::NewEmpty();
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fBoundingHierarchy = record.fBoundingHierarchy;
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStateTree = record.fStateTree;
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeRef(fBoundingHierarchy);
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeRef(fStateTree);
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL != fBoundingHierarchy) {
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fBoundingHierarchy->flushDeferredInserts();
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        size_t size = writer.bytesWritten();
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        void* buffer = sk_malloc_throw(size);
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        writer.flatten(buffer);
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(!fOpData);
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fOpData = SkData::NewFromMalloc(buffer, size);
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // copy over the refcnt dictionary to our reader
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    record.fFlattenableHeap.setupPlaybacks();
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fBitmaps = record.fBitmapHeap->extractBitmaps();
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMatrices = record.fMatrices.unflattenToArray();
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPaints = record.fPaints.unflattenToArray();
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRegions = record.fRegions.unflattenToArray();
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fBitmapHeap.reset(SkSafeRef(record.fBitmapHeap));
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPathHeap.reset(SkSafeRef(record.fPathHeap));
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // ensure that the paths bounds are pre-computed
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPathHeap.get()) {
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int i = 0; i < fPathHeap->count(); i++) {
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (*fPathHeap)[i].updateBoundsCache();
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkTDArray<SkPicture* >& pictures = record.getPictureRefs();
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPictureCount = pictures.count();
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPictureCount > 0) {
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int i = 0; i < fPictureCount; i++) {
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (deepCopy) {
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fPictureRefs[i] = pictures[i]->clone();
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else {
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fPictureRefs[i] = pictures[i];
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fPictureRefs[i]->ref();
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG_SIZE
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int overall = fPlayback->size(&overallBytes);
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bitmaps = fPlayback->bitmaps(&bitmapBytes);
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paints = fPlayback->paints(&paintBytes);
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paths = fPlayback->paths(&pathBytes);
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pictures = fPlayback->pictures(&pictureBytes);
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    regions = fPlayback->regions(&regionBytes);
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("playback size %zd (objects:%d) ", overallBytes, overall);
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (bitmaps != 0)
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps);
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (paints != 0)
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("paints size %zd (paints:%d) ", paintBytes, paints);
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (paths != 0)
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths);
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (pictures != 0)
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures);
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (regions != 0)
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions);
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("\n");
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
149363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic bool needs_deep_copy(const SkPaint& paint) {
150363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    /*
151363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     *  These fields are known to be immutable, and so can be shallow-copied
152363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     *
1530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  getTypeface()
1540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  getAnnotation()
1550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  paint.getColorFilter()
1560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  getXfermode()
157363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     */
158363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
159363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return paint.getPathEffect() ||
160363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger           paint.getShader() ||
161363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger           paint.getMaskFilter() ||
162363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger           paint.getRasterizer() ||
163363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger           paint.getLooper() ||
164363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger           paint.getImageFilter();
165363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
166363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo) {
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->init();
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get()));
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPathHeap.reset(SkSafeRef(src.fPathHeap.get()));
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMatrices = SkSafeRef(src.fMatrices);
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRegions = SkSafeRef(src.fRegions);
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fOpData = SkSafeRef(src.fOpData);
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fBoundingHierarchy = src.fBoundingHierarchy;
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStateTree = src.fStateTree;
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeRef(fBoundingHierarchy);
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeRef(fStateTree);
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (deepCopyInfo) {
184d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        int paintCount = SafeCount(src.fPaints);
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (src.fBitmaps) {
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src.fBitmaps->count());
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (!deepCopyInfo->initialized) {
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            /* The alternative to doing this is to have a clone method on the paint and have it make
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             * the deep copy of its internal structures as needed. The holdup to doing that is at
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             * this point we would need to pass the SkBitmapHeap so that we don't unnecessarily
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             * flatten the pixels in a bitmap shader.
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             */
196d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            deepCopyInfo->paintData.setCount(paintCount);
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
198363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            /* Use an SkBitmapHeap to avoid flattening bitmaps in shaders. If there already is one,
199363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger             * use it. If this SkPicturePlayback was created from a stream, fBitmapHeap will be
200363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger             * NULL, so create a new one.
201363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger             */
202363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            if (fBitmapHeap.get() == NULL) {
203363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                // FIXME: Put this on the stack inside SkPicture::clone. Further, is it possible to
204363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                // do the rest of this initialization in SkPicture::clone as well?
205363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                SkBitmapHeap* heap = SkNEW(SkBitmapHeap);
206363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                deepCopyInfo->controller.setBitmapStorage(heap);
207363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                heap->unref();
208363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            } else {
209363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                deepCopyInfo->controller.setBitmapStorage(fBitmapHeap);
210363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            }
211363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkDEBUGCODE(int heapSize = SafeCount(fBitmapHeap.get());)
213d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            for (int i = 0; i < paintCount; i++) {
214363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                if (needs_deep_copy(src.fPaints->at(i))) {
215363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                    deepCopyInfo->paintData[i] = SkFlatData::Create(&deepCopyInfo->controller,
216363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                                                    &src.fPaints->at(i), 0,
217363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                                                    &SkFlattenObjectProc<SkPaint>);
218363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                } else {
219363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                    // this is our sentinel, which we use in the unflatten loop
220363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                    deepCopyInfo->paintData[i] = NULL;
221363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                }
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkASSERT(SafeCount(fBitmapHeap.get()) == heapSize);
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // needed to create typeface playback
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            deepCopyInfo->controller.setupPlaybacks();
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            deepCopyInfo->initialized = true;
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
230d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        fPaints = SkTRefArray<SkPaint>::Create(paintCount);
231d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        SkASSERT(deepCopyInfo->paintData.count() == paintCount);
232363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkBitmapHeap* bmHeap = deepCopyInfo->controller.getBitmapHeap();
233363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkTypefacePlayback* tfPlayback = deepCopyInfo->controller.getTypefacePlayback();
234d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        for (int i = 0; i < paintCount; i++) {
235363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            if (deepCopyInfo->paintData[i]) {
236363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                deepCopyInfo->paintData[i]->unflatten(&fPaints->writableAt(i),
237363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                                      &SkUnflattenObjectProc<SkPaint>,
238363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                                      bmHeap, tfPlayback);
239363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            } else {
240363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                // needs_deep_copy was false, so just need to assign
241363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                fPaints->writableAt(i) = src.fPaints->at(i);
242363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            }
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fBitmaps = SkSafeRef(src.fBitmaps);
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaints = SkSafeRef(src.fPaints);
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPictureCount = src.fPictureCount;
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < fPictureCount; i++) {
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (deepCopyInfo) {
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fPictureRefs[i] = src.fPictureRefs[i]->clone();
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fPictureRefs[i] = src.fPictureRefs[i];
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fPictureRefs[i]->ref();
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::init() {
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fBitmaps = NULL;
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMatrices = NULL;
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPaints = NULL;
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPictureRefs = NULL;
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRegions = NULL;
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPictureCount = 0;
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fOpData = NULL;
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fFactoryPlayback = NULL;
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fBoundingHierarchy = NULL;
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStateTree = NULL;
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPicturePlayback::~SkPicturePlayback() {
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fOpData->unref();
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeUnref(fBitmaps);
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeUnref(fMatrices);
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeUnref(fPaints);
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeUnref(fRegions);
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeUnref(fBoundingHierarchy);
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeUnref(fStateTree);
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < fPictureCount; i++) {
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPictureRefs[i]->unref();
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDELETE_ARRAY(fPictureRefs);
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDELETE(fFactoryPlayback);
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::dumpSize() const {
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("--- picture size: ops=%d bitmaps=%d [%d] matrices=%d [%d] paints=%d [%d] paths=%d regions=%d\n",
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             fOpData->size(),
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             SafeCount(fBitmaps), SafeCount(fBitmaps) * sizeof(SkBitmap),
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             SafeCount(fMatrices), SafeCount(fMatrices) * sizeof(SkMatrix),
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             SafeCount(fPaints), SafeCount(fPaints) * sizeof(SkPaint),
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             SafeCount(fPathHeap.get()),
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             SafeCount(fRegions));
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerbool SkPicturePlayback::containsBitmaps() const {
3040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (fBitmaps && fBitmaps->count() > 0) {
3050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return true;
3060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
3070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    for (int i = 0; i < fPictureCount; ++i) {
3080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (fPictureRefs[i]->willPlayBackBitmaps()) {
3090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return true;
3100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
3110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
3120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return false;
3130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
3140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_READER_TAG     SkSetFourByteTag('r', 'e', 'a', 'd')
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_FACTORY_TAG    SkSetFourByteTag('f', 'a', 'c', 't')
32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_TYPEFACE_TAG   SkSetFourByteTag('t', 'p', 'f', 'c')
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_PICTURE_TAG    SkSetFourByteTag('p', 'c', 't', 'r')
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// This tag specifies the size of the ReadBuffer, needed for the following tags
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_BUFFER_SIZE_TAG     SkSetFourByteTag('a', 'r', 'a', 'y')
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// these are all inside the ARRAYS tag
32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_BITMAP_BUFFER_TAG  SkSetFourByteTag('b', 't', 'm', 'p')
32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_MATRIX_BUFFER_TAG  SkSetFourByteTag('m', 't', 'r', 'x')
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_PAINT_BUFFER_TAG   SkSetFourByteTag('p', 'n', 't', ' ')
32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_PATH_BUFFER_TAG    SkSetFourByteTag('p', 't', 'h', ' ')
33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_REGION_BUFFER_TAG  SkSetFourByteTag('r', 'g', 'n', ' ')
33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Always write this guy last (with no length field afterwards)
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define PICT_EOF_TAG     SkSetFourByteTag('e', 'o', 'f', ' ')
33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h"
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void writeTagSize(SkOrderedWriteBuffer& buffer, uint32_t tag,
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                         uint32_t size) {
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    buffer.writeUInt(tag);
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    buffer.writeUInt(size);
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void writeTagSize(SkWStream* stream, uint32_t tag,
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                         uint32_t size) {
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    stream->write32(tag);
34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    stream->write32(size);
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void writeFactories(SkWStream* stream, const SkFactorySet& rec) {
35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = rec.count();
35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    writeTagSize(stream, PICT_FACTORY_TAG, count);
35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count);
35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get();
35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    rec.copyToArray(array);
35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < count; i++) {
35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const char* name = SkFlattenable::FactoryToName(array[i]);
36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//        SkDebugf("---- write factories [%d] %p <%s>\n", i, array[i], name);
36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL == name || 0 == *name) {
36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            stream->writePackedUInt(0);
36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            uint32_t len = strlen(name);
36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            stream->writePackedUInt(len);
36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            stream->write(name, len);
36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void writeTypefaces(SkWStream* stream, const SkRefCntSet& rec) {
37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = rec.count();
37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    writeTagSize(stream, PICT_TYPEFACE_TAG, count);
37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoSTMalloc<16, SkTypeface*> storage(count);
37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTypeface** array = (SkTypeface**)storage.get();
37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    rec.copyToArray((SkRefCnt**)array);
37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < count; i++) {
38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        array[i]->serialize(stream);
38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::flattenToBuffer(SkOrderedWriteBuffer& buffer) const {
38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int i, n;
38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if ((n = SafeCount(fBitmaps)) > 0) {
38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        writeTagSize(buffer, PICT_BITMAP_BUFFER_TAG, n);
39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (i = 0; i < n; i++) {
39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            buffer.writeBitmap((*fBitmaps)[i]);
39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if ((n = SafeCount(fMatrices)) > 0) {
39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        writeTagSize(buffer, PICT_MATRIX_BUFFER_TAG, n);
39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (i = 0; i < n; i++) {
39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            buffer.writeMatrix((*fMatrices)[i]);
39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if ((n = SafeCount(fPaints)) > 0) {
40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        writeTagSize(buffer, PICT_PAINT_BUFFER_TAG, n);
40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (i = 0; i < n; i++) {
40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            buffer.writePaint((*fPaints)[i]);
40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if ((n = SafeCount(fPathHeap.get())) > 0) {
41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        writeTagSize(buffer, PICT_PATH_BUFFER_TAG, n);
41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPathHeap->flatten(buffer);
41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if ((n = SafeCount(fRegions)) > 0) {
41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        writeTagSize(buffer, PICT_REGION_BUFFER_TAG, n);
41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (i = 0; i < n; i++) {
41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            buffer.writeRegion((*fRegions)[i]);
41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::serialize(SkWStream* stream,
424096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                  SkPicture::EncodeBitmap encoder) const {
42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    writeTagSize(stream, PICT_READER_TAG, fOpData->size());
42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    stream->write(fOpData->bytes(), fOpData->size());
42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPictureCount > 0) {
42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        writeTagSize(stream, PICT_PICTURE_TAG, fPictureCount);
43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int i = 0; i < fPictureCount; i++) {
431096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            fPictureRefs[i]->serialize(stream, encoder);
43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Write some of our data into a writebuffer, and then serialize that
43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // into our stream
43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkRefCntSet  typefaceSet;
43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFactorySet factSet;
44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkOrderedWriteBuffer buffer(1024);
44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        buffer.setTypefaceRecorder(&typefaceSet);
44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        buffer.setFactoryRecorder(&factSet);
44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        buffer.setBitmapEncoder(encoder);
44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->flattenToBuffer(buffer);
44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // We have to write these to sets into the stream *before* we write
45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // the buffer, since parsing that buffer will require that we already
45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // have these sets available to use.
45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        writeFactories(stream, factSet);
45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        writeTypefaces(stream, typefaceSet);
45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        writeTagSize(stream, PICT_BUFFER_SIZE_TAG, buffer.size());
45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        buffer.writeToStream(stream);
45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    stream->write32(PICT_EOF_TAG);
46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  Return the corresponding SkFlattenableReadBuffer flags, given a set of
46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  SkPictInfo flags.
46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) {
47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const struct {
47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t    fSrc;
47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t    fDst;
47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } gSD[] = {
47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { SkPictInfo::kCrossProcess_Flag,   SkFlattenableReadBuffer::kCrossProcess_Flag },
47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { SkPictInfo::kScalarIsFloat_Flag,  SkFlattenableReadBuffer::kScalarIsFloat_Flag },
47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { SkPictInfo::kPtrIs64Bit_Flag,     SkFlattenableReadBuffer::kPtrIs64Bit_Flag },
47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t rbMask = 0;
48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) {
48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (pictInfoFlags & gSD[i].fSrc) {
48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            rbMask |= gSD[i].fDst;
48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return rbMask;
48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerbool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, uint32_t tag,
489096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                       size_t size, SkPicture::InstallPixelRefProc proc) {
49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /*
49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  but if they are present, they need to have been seen before the buffer.
49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  We assert that if/when we see either of these, that we have not yet seen
49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  the buffer tag, because if we have, then its too-late to deal with the
49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  factories or typefaces.
49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
499096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkDEBUGCODE(bool haveBuffer = false;)
50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch (tag) {
50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case PICT_READER_TAG: {
5030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkAutoMalloc storage(size);
5040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (stream->read(storage.get(), size) != size) {
5050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                return false;
5060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
50780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkASSERT(NULL == fOpData);
5080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            fOpData = SkData::NewFromMalloc(storage.detach(), size);
50980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } break;
51080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case PICT_FACTORY_TAG: {
51180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkASSERT(!haveBuffer);
51280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fFactoryPlayback = SkNEW_ARGS(SkFactoryPlayback, (size));
51380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (size_t i = 0; i < size; i++) {
51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkString str;
5150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                const size_t len = stream->readPackedUInt();
51680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                str.resize(len);
5170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                if (stream->read(str.writable_str(), len) != len) {
5180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    return false;
5190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                }
52080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str());
52180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
52280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } break;
52380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case PICT_TYPEFACE_TAG: {
52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkASSERT(!haveBuffer);
52580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fTFPlayback.setCount(size);
52680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (size_t i = 0; i < size; i++) {
5277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkAutoTUnref<SkTypeface> tf(SkTypeface::Deserialize(stream));
5287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                if (!tf.get()) {    // failed to deserialize
5297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    // fTFPlayback asserts it never has a null, so we plop in
5307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    // the default here.
5317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    tf.reset(SkTypeface::RefDefault());
5327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                }
5337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fTFPlayback.set(i, tf);
53480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } break;
53680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case PICT_PICTURE_TAG: {
53780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fPictureCount = size;
53880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
5390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            bool success = true;
5400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            int i = 0;
5410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            for ( ; i < fPictureCount; i++) {
54258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                fPictureRefs[i] = SkPicture::CreateFromStream(stream, proc);
5430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                if (NULL == fPictureRefs[i]) {
5440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    success = false;
5450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    break;
5460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                }
5470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
5480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (!success) {
5490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                // Delete all of the pictures that were already created (up to but excluding i):
5500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                for (int j = 0; j < i; j++) {
5510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    fPictureRefs[j]->unref();
5520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                }
5530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                // Delete the array
5540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                SkDELETE_ARRAY(fPictureRefs);
5550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                fPictureCount = 0;
5560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                return false;
55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } break;
55980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case PICT_BUFFER_SIZE_TAG: {
56080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkAutoMalloc storage(size);
5610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (stream->read(storage.get(), size) != size) {
5620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                return false;
5630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
56480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
56580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkOrderedReadBuffer buffer(storage.get(), size);
56680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            buffer.setFlags(pictInfoFlagsToReadBufferFlags(info.fFlags));
56780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
56880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fFactoryPlayback->setupBuffer(buffer);
56980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fTFPlayback.setupBuffer(buffer);
570096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            buffer.setBitmapDecoder(proc);
57180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            while (!buffer.eof()) {
57380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                tag = buffer.readUInt();
57480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size = buffer.readUInt();
5750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                if (!this->parseBufferTag(buffer, tag, size)) {
5760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    return false;
5770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                }
57880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
579096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            SkDEBUGCODE(haveBuffer = true;)
58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } break;
58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return true;    // success
58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerbool SkPicturePlayback::parseBufferTag(SkOrderedReadBuffer& buffer,
58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                       uint32_t tag, size_t size) {
58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch (tag) {
58880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case PICT_BITMAP_BUFFER_TAG: {
58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fBitmaps = SkTRefArray<SkBitmap>::Create(size);
59080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (size_t i = 0; i < size; ++i) {
591363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                SkBitmap* bm = &fBitmaps->writableAt(i);
592363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                buffer.readBitmap(bm);
593363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                bm->setImmutable();
59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } break;
59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case PICT_MATRIX_BUFFER_TAG:
59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fMatrices = SkTRefArray<SkMatrix>::Create(size);
59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (size_t i = 0; i < size; ++i) {
59980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                buffer.readMatrix(&fMatrices->writableAt(i));
60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            break;
60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case PICT_PAINT_BUFFER_TAG: {
60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fPaints = SkTRefArray<SkPaint>::Create(size);
60480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (size_t i = 0; i < size; ++i) {
60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                buffer.readPaint(&fPaints->writableAt(i));
60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } break;
60880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case PICT_PATH_BUFFER_TAG:
60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (size > 0) {
61080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
61180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            break;
61380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case PICT_REGION_BUFFER_TAG: {
61480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fRegions = SkTRefArray<SkRegion>::Create(size);
61580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (size_t i = 0; i < size; ++i) {
61680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                buffer.readRegion(&fRegions->writableAt(i));
61780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
61880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } break;
6190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        default:
6200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            // The tag was invalid.
6210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return false;
62280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return true;    // success
62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
62580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6260a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerSkPicturePlayback* SkPicturePlayback::CreateFromStream(SkStream* stream,
6270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                                       const SkPictInfo& info,
6280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                                       SkPicture::InstallPixelRefProc proc) {
6290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkAutoTDelete<SkPicturePlayback> playback(SkNEW(SkPicturePlayback));
63080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (!playback->parseStream(stream, info, proc)) {
6320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return NULL;
6330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
6340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return playback.detach();
6350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
6360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
6370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerbool SkPicturePlayback::parseStream(SkStream* stream, const SkPictInfo& info,
6380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                    SkPicture::InstallPixelRefProc proc) {
63980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (;;) {
64080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t tag = stream->readU32();
64180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (PICT_EOF_TAG == tag) {
64280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            break;
64380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
64480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
64580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t size = stream->readU32();
6460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (!this->parseStreamTag(stream, info, tag, size, proc)) {
6470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return false; // we're invalid
6480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
64980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return true;
65180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
65280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
65380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
65480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
65580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
65680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SPEW_CLIP_SKIPPING
65780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct SkipClipRec {
65880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int     fCount;
65980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t  fSize;
66080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
66180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkipClipRec() {
66280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fCount = 0;
66380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fSize = 0;
66480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
66580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
66680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void recordSkip(size_t bytes) {
66780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fCount += 1;
66880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fSize += bytes;
66980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
67080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
67180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
67280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
673d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER
674779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenbergerbool SkPicturePlayback::preDraw(int opIndex, int type) {
675779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger    return false;
676363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
677363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
678779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenbergervoid SkPicturePlayback::postDraw(int opIndex) {
679363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
680363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif
681363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
682096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger/*
683096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Read the next op code and chunk size from 'reader'. The returned size
684096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * is the entire size of the chunk (including the opcode). Thus, the
685096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * offset just prior to calling read_op_and_size + 'size' is the offset
686096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * to the next chunk's op code. This also means that the size of a chunk
687096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * with no arguments (just an opcode) will be 4.
688096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger */
689096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerstatic DrawType read_op_and_size(SkReader32* reader, uint32_t* size) {
690096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    uint32_t temp = reader->readInt();
691096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    uint32_t op;
692096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (((uint8_t) temp) == temp) {
693096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // old skp file - no size information
694096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        op = temp;
695096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        *size = 0;
696096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    } else {
697096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        UNPACK_8_24(temp, op, *size);
698096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (MASK_24 == *size) {
699096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            *size = reader->readInt();
700096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        }
701096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
702096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    return (DrawType) op;
703096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
704096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
7057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) {
70680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef ENABLE_TIME_DRAW
70780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoTime  at("SkPicture::draw", 50);
70880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
70980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
71080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SPEW_CLIP_SKIPPING
711363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkipClipRec skipRect, skipRRect, skipRegion, skipPath;
71280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
71380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
71480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_BUILD_FOR_ANDROID
71580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoMutexAcquire autoMutex(fDrawMutex);
71680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
71780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
718363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    // kDrawComplete will be the signal that we have reached the end of
719363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    // the command stream
720363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    static const uint32_t kDrawComplete = SK_MaxU32;
721363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
72280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkReader32 reader(fOpData->bytes(), fOpData->size());
72380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    TextContainer text;
72480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTDArray<void*> results;
72580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
72680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL != fStateTree && NULL != fBoundingHierarchy) {
72780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkRect clipBounds;
72880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (canvas.getClipBounds(&clipBounds)) {
72980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkIRect query;
73080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            clipBounds.roundOut(&query);
73180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fBoundingHierarchy->search(query, &results);
73280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (results.count() == 0) {
73380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return;
73480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
73580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkTQSort<SkPictureStateTree::Draw>(
73680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                reinterpret_cast<SkPictureStateTree::Draw**>(results.begin()),
73780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                reinterpret_cast<SkPictureStateTree::Draw**>(results.end()-1));
73880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
73980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
74080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
74180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPictureStateTree::Iterator it = (NULL == fStateTree) ?
74280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkPictureStateTree::Iterator() :
74380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStateTree->getIterator(results, &canvas);
74480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
74580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (it.isValid()) {
746363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        uint32_t skipTo = it.draw();
747363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        if (kDrawComplete == skipTo) {
74880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return;
74980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
750363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        reader.setOffset(skipTo);
75180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
75280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
75380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Record this, so we can concat w/ it if we encounter a setMatrix()
75480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix initialMatrix = canvas.getTotalMatrix();
7557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int originalSaveCount = canvas.getSaveCount();
75680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
757d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
758d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    fAbortCurrentPlayback = false;
759d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif
760d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
761779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger#ifdef SK_DEVELOPER
762779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger    int opIndex = -1;
763779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger#endif
764779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger
76580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    while (!reader.eof()) {
7667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (callback && callback->abortDrawing()) {
7677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            canvas.restoreToCount(originalSaveCount);
7687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return;
7697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
770d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
771d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        if (fAbortCurrentPlayback) {
772d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            return;
773d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        }
774d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif
775d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
776363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        size_t curOffset = reader.offset();
777096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        uint32_t size;
778096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        DrawType op = read_op_and_size(&reader, &size);
779096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        size_t skipTo = 0;
780779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger        if (NOOP == op) {
781096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // NOOPs are to be ignored - do not propagate them any further
782096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            skipTo = curOffset + size;
783779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger#ifdef SK_DEVELOPER
784779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger        } else {
785779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger            opIndex++;
786779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger            if (this->preDraw(opIndex, op)) {
787779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger                skipTo = curOffset + size;
788779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger            }
789779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger#endif
790096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        }
791096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
792363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        if (0 != skipTo) {
793096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            if (it.isValid()) {
794096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                // If using a bounding box hierarchy, advance the state tree
795096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                // iterator until at or after skipTo
796096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                uint32_t adjustedSkipTo;
797096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                do {
798096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                    adjustedSkipTo = it.draw();
799096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                } while (adjustedSkipTo < skipTo);
800096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                skipTo = adjustedSkipTo;
801096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            }
802363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            if (kDrawComplete == skipTo) {
803363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                break;
804363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            }
805363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            reader.setOffset(skipTo);
806363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            continue;
807363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        }
808096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
809096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        switch (op) {
81080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case CLIP_PATH: {
81180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPath& path = getPath(reader);
81280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                uint32_t packed = reader.readInt();
813096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
81480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                bool doAA = ClipParams_unpackDoAA(packed);
81580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t offsetToRestore = reader.readInt();
81680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkASSERT(!offsetToRestore || \
81780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    offsetToRestore >= reader.offset());
818096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                if (!canvas.clipPath(path, regionOp, doAA) && offsetToRestore) {
81980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SPEW_CLIP_SKIPPING
82080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    skipPath.recordSkip(offsetToRestore - reader.offset());
82180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
82280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    reader.setOffset(offsetToRestore);
82380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
82480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
82580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case CLIP_REGION: {
82680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkRegion& region = getRegion(reader);
82780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                uint32_t packed = reader.readInt();
828096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
82980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t offsetToRestore = reader.readInt();
83080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkASSERT(!offsetToRestore || \
83180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    offsetToRestore >= reader.offset());
832096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                if (!canvas.clipRegion(region, regionOp) && offsetToRestore) {
83380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SPEW_CLIP_SKIPPING
83480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    skipRegion.recordSkip(offsetToRestore - reader.offset());
83580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
83680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    reader.setOffset(offsetToRestore);
83780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
83880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
83980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case CLIP_RECT: {
84080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkRect& rect = reader.skipT<SkRect>();
84180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                uint32_t packed = reader.readInt();
842096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
84380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                bool doAA = ClipParams_unpackDoAA(packed);
84480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t offsetToRestore = reader.readInt();
84580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkASSERT(!offsetToRestore || \
846363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                         offsetToRestore >= reader.offset());
847096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                if (!canvas.clipRect(rect, regionOp, doAA) && offsetToRestore) {
84880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SPEW_CLIP_SKIPPING
84980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    skipRect.recordSkip(offsetToRestore - reader.offset());
85080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
85180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    reader.setOffset(offsetToRestore);
85280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
85380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
854363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            case CLIP_RRECT: {
855363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                SkRRect rrect;
856363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                reader.readRRect(&rrect);
857363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                uint32_t packed = reader.readInt();
858096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
859363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                bool doAA = ClipParams_unpackDoAA(packed);
860363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                size_t offsetToRestore = reader.readInt();
861363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                SkASSERT(!offsetToRestore || \
862363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                         offsetToRestore >= reader.offset());
863096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                if (!canvas.clipRRect(rrect, regionOp, doAA) && offsetToRestore) {
864363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#ifdef SPEW_CLIP_SKIPPING
865363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                    skipRRect.recordSkip(offsetToRestore - reader.offset());
866363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif
867363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                    reader.setOffset(offsetToRestore);
868363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                }
869363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            } break;
87080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case CONCAT:
87180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.concat(*getMatrix(reader));
87280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
87380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_BITMAP: {
87480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint* paint = getPaint(reader);
87580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkBitmap& bitmap = getBitmap(reader);
87680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPoint& loc = reader.skipT<SkPoint>();
87780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawBitmap(bitmap, loc.fX, loc.fY, paint);
87880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
87980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_BITMAP_RECT_TO_RECT: {
88080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint* paint = getPaint(reader);
88180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkBitmap& bitmap = getBitmap(reader);
88280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkRect* src = this->getRectPtr(reader);   // may be null
88380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkRect& dst = reader.skipT<SkRect>();     // required
8840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                SkCanvas::DrawBitmapRectFlags flags;
885910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                flags = (SkCanvas::DrawBitmapRectFlags) reader.readInt();
8860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                canvas.drawBitmapRectToRect(bitmap, src, dst, paint, flags);
88780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
88880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_BITMAP_MATRIX: {
88980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint* paint = getPaint(reader);
89080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkBitmap& bitmap = getBitmap(reader);
89180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkMatrix* matrix = getMatrix(reader);
89280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawBitmapMatrix(bitmap, *matrix, paint);
89380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
89480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_BITMAP_NINE: {
89580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint* paint = getPaint(reader);
89680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkBitmap& bitmap = getBitmap(reader);
89780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkIRect& src = reader.skipT<SkIRect>();
89880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkRect& dst = reader.skipT<SkRect>();
89980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawBitmapNine(bitmap, src, dst, paint);
90080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
90180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_CLEAR:
90280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.clear(reader.readInt());
90380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
90480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_DATA: {
90580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t length = reader.readInt();
90680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawData(reader.skip(length), length);
90780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // skip handles padding the read out to a multiple of 4
90880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
90958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            case BEGIN_COMMENT_GROUP: {
91058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                const char* desc = reader.readString();
91158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                canvas.beginCommentGroup(desc);
91258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            } break;
91358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            case COMMENT: {
91458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                const char* kywd = reader.readString();
91558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                const char* value = reader.readString();
91658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                canvas.addComment(kywd, value);
91758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            } break;
91858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            case END_COMMENT_GROUP: {
91958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                canvas.endCommentGroup();
92058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            } break;
921363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            case DRAW_OVAL: {
922363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                const SkPaint& paint = *getPaint(reader);
923363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                canvas.drawOval(reader.skipT<SkRect>(), paint);
924363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            } break;
92580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_PAINT:
92680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawPaint(*getPaint(reader));
92780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
92880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_PATH: {
92980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
93080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawPath(getPath(reader), paint);
93180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
93280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_PICTURE:
93380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawPicture(getPicture(reader));
93480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
93580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_POINTS: {
93680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
93780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkCanvas::PointMode mode = (SkCanvas::PointMode)reader.readInt();
93880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t count = reader.readInt();
93980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPoint* pts = (const SkPoint*)reader.skip(sizeof(SkPoint) * count);
94080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawPoints(mode, count, pts, paint);
94180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
94280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_POS_TEXT: {
94380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
94480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                getText(reader, &text);
94580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t points = reader.readInt();
94680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPoint* pos = (const SkPoint*)reader.skip(points * sizeof(SkPoint));
94780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawPosText(text.text(), text.length(), pos, paint);
94880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
94980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_POS_TEXT_TOP_BOTTOM: {
95080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
95180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                getText(reader, &text);
95280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t points = reader.readInt();
95380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPoint* pos = (const SkPoint*)reader.skip(points * sizeof(SkPoint));
95480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkScalar top = reader.readScalar();
95580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkScalar bottom = reader.readScalar();
95680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (!canvas.quickRejectY(top, bottom)) {
95780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    canvas.drawPosText(text.text(), text.length(), pos, paint);
95880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
95980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
96080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_POS_TEXT_H: {
96180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
96280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                getText(reader, &text);
96380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t xCount = reader.readInt();
96480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkScalar constY = reader.readScalar();
96580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkScalar* xpos = (const SkScalar*)reader.skip(xCount * sizeof(SkScalar));
96680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawPosTextH(text.text(), text.length(), xpos, constY,
96780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    paint);
96880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
96980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_POS_TEXT_H_TOP_BOTTOM: {
97080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
97180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                getText(reader, &text);
97280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t xCount = reader.readInt();
97380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkScalar* xpos = (const SkScalar*)reader.skip((3 + xCount) * sizeof(SkScalar));
97480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkScalar top = *xpos++;
97580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkScalar bottom = *xpos++;
97680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkScalar constY = *xpos++;
97780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (!canvas.quickRejectY(top, bottom)) {
97880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    canvas.drawPosTextH(text.text(), text.length(), xpos,
97980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        constY, paint);
98080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
98180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
98280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_RECT: {
98380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
98480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawRect(reader.skipT<SkRect>(), paint);
98580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
986363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            case DRAW_RRECT: {
987363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                const SkPaint& paint = *getPaint(reader);
988363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                SkRRect rrect;
989910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                reader.readRRect(&rrect);
990910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                canvas.drawRRect(rrect, paint);
991363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            } break;
99280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_SPRITE: {
99380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint* paint = getPaint(reader);
99480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkBitmap& bitmap = getBitmap(reader);
99580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int left = reader.readInt();
99680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int top = reader.readInt();
99780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawSprite(bitmap, left, top, paint);
99880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
99980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_TEXT: {
100080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
100180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                getText(reader, &text);
100280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar x = reader.readScalar();
100380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar y = reader.readScalar();
100480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawText(text.text(), text.length(), x, y, paint);
100580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
100680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_TEXT_TOP_BOTTOM: {
100780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
100880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                getText(reader, &text);
100980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkScalar* ptr = (const SkScalar*)reader.skip(4 * sizeof(SkScalar));
101080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // ptr[0] == x
101180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // ptr[1] == y
101280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // ptr[2] == top
101380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // ptr[3] == bottom
101480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (!canvas.quickRejectY(ptr[2], ptr[3])) {
101580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    canvas.drawText(text.text(), text.length(), ptr[0], ptr[1],
101680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    paint);
101780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
101880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
101980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_TEXT_ON_PATH: {
102080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
102180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                getText(reader, &text);
102280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPath& path = getPath(reader);
102380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkMatrix* matrix = getMatrix(reader);
102480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawTextOnPath(text.text(), text.length(), path,
102580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                      matrix, paint);
102680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
102780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_VERTICES: {
102880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint& paint = *getPaint(reader);
102980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DrawVertexFlags flags = (DrawVertexFlags)reader.readInt();
103080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader.readInt();
103180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int vCount = reader.readInt();
103280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPoint* verts = (const SkPoint*)reader.skip(
103380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    vCount * sizeof(SkPoint));
103480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPoint* texs = NULL;
103580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkColor* colors = NULL;
103680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const uint16_t* indices = NULL;
103780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int iCount = 0;
103880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (flags & DRAW_VERTICES_HAS_TEXS) {
103980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    texs = (const SkPoint*)reader.skip(
104080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    vCount * sizeof(SkPoint));
104180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
104280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (flags & DRAW_VERTICES_HAS_COLORS) {
104380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    colors = (const SkColor*)reader.skip(
104480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    vCount * sizeof(SkColor));
104580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
104680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (flags & DRAW_VERTICES_HAS_INDICES) {
104780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    iCount = reader.readInt();
104880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    indices = (const uint16_t*)reader.skip(
104980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    iCount * sizeof(uint16_t));
105080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
105180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.drawVertices(vmode, vCount, verts, texs, colors, NULL,
105280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    indices, iCount, paint);
105380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
105480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case RESTORE:
105580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.restore();
105680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
105780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case ROTATE:
105880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.rotate(reader.readScalar());
105980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
106080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SAVE:
106180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.save((SkCanvas::SaveFlags) reader.readInt());
106280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
106380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SAVE_LAYER: {
106480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkRect* boundsPtr = getRectPtr(reader);
106580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                const SkPaint* paint = getPaint(reader);
106680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) reader.readInt());
106780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
106880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SCALE: {
106980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar sx = reader.readScalar();
107080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar sy = reader.readScalar();
107180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.scale(sx, sy);
107280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
107380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SET_MATRIX: {
107480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkMatrix matrix;
107580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                matrix.setConcat(initialMatrix, *getMatrix(reader));
107680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.setMatrix(matrix);
107780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
107880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SKEW: {
107980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar sx = reader.readScalar();
108080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar sy = reader.readScalar();
108180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.skew(sx, sy);
108280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
108380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case TRANSLATE: {
108480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar dx = reader.readScalar();
108580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar dy = reader.readScalar();
108680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas.translate(dx, dy);
108780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
108880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            default:
108980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkASSERT(0);
109080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
109180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1092d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER
1093779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger        this->postDraw(opIndex);
1094363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif
1095363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
109680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (it.isValid()) {
1097363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            uint32_t skipTo = it.draw();
1098363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            if (kDrawComplete == skipTo) {
109980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
110080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
1101363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            reader.setOffset(skipTo);
110280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
110380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
110480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
110580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SPEW_CLIP_SKIPPING
110680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
1107363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        size_t size =  skipRect.fSize + skipRRect.fSize + skipPath.fSize + skipRegion.fSize;
1108363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkDebugf("--- Clip skips %d%% rect:%d rrect:%d path:%d rgn:%d\n",
1109363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger             size * 100 / reader.offset(), skipRect.fCount, skipRRect.fCount,
1110363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                 skipPath.fCount, skipRegion.fCount);
111180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
111280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
111380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//    this->dumpSize();
111480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
111580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
111680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
111780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
111880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG_SIZE
111980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::size(size_t* sizePtr) {
112080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int objects = bitmaps(sizePtr);
112180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    objects += paints(sizePtr);
112280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    objects += paths(sizePtr);
112380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    objects += pictures(sizePtr);
112480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    objects += regions(sizePtr);
112580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *sizePtr = fOpData.size();
112680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return objects;
112780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
112880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
112980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::bitmaps(size_t* size) {
113080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t result = 0;
113180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < fBitmapCount; index++) {
113280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     //   const SkBitmap& bitmap = fBitmaps[index];
113380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        result += sizeof(SkBitmap); // bitmap->size();
113480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
113580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *size = result;
113680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return fBitmapCount;
113780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
113880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
113980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::paints(size_t* size) {
114080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t result = 0;
114180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < fPaintCount; index++) {
114280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //    const SkPaint& paint = fPaints[index];
114380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        result += sizeof(SkPaint); // paint->size();
114480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
114580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *size = result;
114680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return fPaintCount;
114780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
114880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
114980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::paths(size_t* size) {
115080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t result = 0;
115180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < fPathCount; index++) {
115280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkPath& path = fPaths[index];
115380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        result += path.flatten(NULL);
115480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
115580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *size = result;
115680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return fPathCount;
115780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
115880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
115980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::regions(size_t* size) {
116080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t result = 0;
116180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < fRegionCount; index++) {
116280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //    const SkRegion& region = fRegions[index];
116380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        result += sizeof(SkRegion); // region->size();
116480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
116580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *size = result;
116680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return fRegionCount;
116780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
116880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
116980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
117080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG_DUMP
117180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::dumpBitmap(const SkBitmap& bitmap) const {
117280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char pBuffer[DUMP_BUFFER_SIZE];
117380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char* bufferPtr = pBuffer;
117480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
117580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "BitmapData bitmap%p = {", &bitmap);
117680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
117780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "{kWidth, %d}, ", bitmap.width());
117880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
117980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "{kHeight, %d}, ", bitmap.height());
118080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
118180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "{kRowBytes, %d}, ", bitmap.rowBytes());
118280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//        start here;
118380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("%s{0}};\n", pBuffer);
118480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
118580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
118680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid dumpMatrix(const SkMatrix& matrix) const {
118780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix defaultMatrix;
118880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    defaultMatrix.reset();
118980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char pBuffer[DUMP_BUFFER_SIZE];
119080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char* bufferPtr = pBuffer;
119180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
119280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "MatrixData matrix%p = {", &matrix);
119380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar scaleX = matrix.getScaleX();
119480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scaleX != defaultMatrix.getScaleX())
119580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
119680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kScaleX, %g}, ", SkScalarToFloat(scaleX));
119780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar scaleY = matrix.getScaleY();
119880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scaleY != defaultMatrix.getScaleY())
119980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
120080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kScaleY, %g}, ", SkScalarToFloat(scaleY));
120180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar skewX = matrix.getSkewX();
120280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (skewX != defaultMatrix.getSkewX())
120380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
120480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kSkewX, %g}, ", SkScalarToFloat(skewX));
120580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar skewY = matrix.getSkewY();
120680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (skewY != defaultMatrix.getSkewY())
120780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
120880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kSkewY, %g}, ", SkScalarToFloat(skewY));
120980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar translateX = matrix.getTranslateX();
121080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (translateX != defaultMatrix.getTranslateX())
121180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
121280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kTranslateX, %g}, ", SkScalarToFloat(translateX));
121380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar translateY = matrix.getTranslateY();
121480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (translateY != defaultMatrix.getTranslateY())
121580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
121680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kTranslateY, %g}, ", SkScalarToFloat(translateY));
121780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar perspX = matrix.getPerspX();
121880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (perspX != defaultMatrix.getPerspX())
121980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
122080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kPerspX, %g}, ", SkFractToFloat(perspX));
122180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar perspY = matrix.getPerspY();
122280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (perspY != defaultMatrix.getPerspY())
122380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
122480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kPerspY, %g}, ", SkFractToFloat(perspY));
122580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("%s{0}};\n", pBuffer);
122680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
122780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
122880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid dumpPaint(const SkPaint& paint) const {
122980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint defaultPaint;
123080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char pBuffer[DUMP_BUFFER_SIZE];
123180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char* bufferPtr = pBuffer;
123280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
123380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "PaintPointers paintPtrs%p = {", &paint);
123480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkTypeface* typeface = paint.getTypeface();
123580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (typeface != defaultPaint.getTypeface())
123680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
123780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kTypeface, %p}, ", typeface);
123880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkPathEffect* pathEffect = paint.getPathEffect();
123980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (pathEffect != defaultPaint.getPathEffect())
124080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
124180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kPathEffect, %p}, ", pathEffect);
124280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkShader* shader = paint.getShader();
124380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (shader != defaultPaint.getShader())
124480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
124580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kShader, %p}, ", shader);
124680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkXfermode* xfermode = paint.getXfermode();
124780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (xfermode != defaultPaint.getXfermode())
124880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
124980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kXfermode, %p}, ", xfermode);
125080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkMaskFilter* maskFilter = paint.getMaskFilter();
125180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (maskFilter != defaultPaint.getMaskFilter())
125280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
125380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kMaskFilter, %p}, ", maskFilter);
125480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkColorFilter* colorFilter = paint.getColorFilter();
125580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (colorFilter != defaultPaint.getColorFilter())
125680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
125780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kColorFilter, %p}, ", colorFilter);
125880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkRasterizer* rasterizer = paint.getRasterizer();
125980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (rasterizer != defaultPaint.getRasterizer())
126080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
126180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kRasterizer, %p}, ", rasterizer);
126280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkDrawLooper* drawLooper = paint.getLooper();
126380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (drawLooper != defaultPaint.getLooper())
126480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
126580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kDrawLooper, %p}, ", drawLooper);
126680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("%s{0}};\n", pBuffer);
126780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr = pBuffer;
126880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
126980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "PaintScalars paintScalars%p = {", &paint);
127080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar textSize = paint.getTextSize();
127180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (textSize != defaultPaint.getTextSize())
127280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
127380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kTextSize, %g}, ", SkScalarToFloat(textSize));
127480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar textScaleX = paint.getTextScaleX();
127580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (textScaleX != defaultPaint.getTextScaleX())
127680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
127780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kTextScaleX, %g}, ", SkScalarToFloat(textScaleX));
127880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar textSkewX = paint.getTextSkewX();
127980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (textSkewX != defaultPaint.getTextSkewX())
128080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
128180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kTextSkewX, %g}, ", SkScalarToFloat(textSkewX));
128280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar strokeWidth = paint.getStrokeWidth();
128380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (strokeWidth != defaultPaint.getStrokeWidth())
128480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
128580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kStrokeWidth, %g}, ", SkScalarToFloat(strokeWidth));
128680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar strokeMiter = paint.getStrokeMiter();
128780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (strokeMiter != defaultPaint.getStrokeMiter())
128880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
128980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kStrokeMiter, %g}, ", SkScalarToFloat(strokeMiter));
129080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("%s{0}};\n", pBuffer);
129180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr = pBuffer;
129280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
129380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "PaintInts = paintInts%p = {", &paint);
129480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned color = paint.getColor();
129580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (color != defaultPaint.getColor())
129680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
129780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kColor, 0x%x}, ", color);
129880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned flags = paint.getFlags();
129980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (flags != defaultPaint.getFlags())
130080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
130180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kFlags, 0x%x}, ", flags);
130280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int align = paint.getTextAlign();
130380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (align != defaultPaint.getTextAlign())
130480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
130580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kAlign, 0x%x}, ", align);
130680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int strokeCap = paint.getStrokeCap();
130780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (strokeCap != defaultPaint.getStrokeCap())
130880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
130980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kStrokeCap, 0x%x}, ", strokeCap);
131080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int strokeJoin = paint.getStrokeJoin();
131180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (strokeJoin != defaultPaint.getStrokeJoin())
131280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
131380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kAlign, 0x%x}, ", strokeJoin);
131480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int style = paint.getStyle();
131580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (style != defaultPaint.getStyle())
131680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
131780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kStyle, 0x%x}, ", style);
131880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int textEncoding = paint.getTextEncoding();
131980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (textEncoding != defaultPaint.getTextEncoding())
132080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
132180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "{kTextEncoding, 0x%x}, ", textEncoding);
132280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("%s{0}};\n", pBuffer);
132380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
132480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("PaintData paint%p = {paintPtrs%p, paintScalars%p, paintInts%p};\n",
132580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        &paint, &paint, &paint, &paint);
132680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
132780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
132880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::dumpPath(const SkPath& path) const {
132980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("path dump unimplemented\n");
133080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
133180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
133280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::dumpPicture(const SkPicture& picture) const {
133380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("picture dump unimplemented\n");
133480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
133580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
133680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::dumpRegion(const SkRegion& region) const {
133780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("region dump unimplemented\n");
133880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
133980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
134080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType) {
134180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
134280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "k%s, ", DrawTypeToString(drawType));
134380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
134480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
134580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::dumpInt(char* bufferPtr, char* buffer, char* name) {
134680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
134780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "%s:%d, ", name, getInt());
134880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
134980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
135080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::dumpRect(char* bufferPtr, char* buffer, char* name) {
135180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkRect* rect = fReader.skipRect();
135280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
135380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "%s:{l:%g t:%g r:%g b:%g}, ", name, SkScalarToFloat(rect.fLeft),
135480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalarToFloat(rect.fTop),
135580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalarToFloat(rect.fRight), SkScalarToFloat(rect.fBottom));
135680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
135780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
135880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::dumpPoint(char* bufferPtr, char* buffer, char* name) {
135980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint pt;
136080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    getPoint(&pt);
136180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
136280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "%s:{x:%g y:%g}, ", name, SkScalarToFloat(pt.fX),
136380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalarToFloat(pt.fY));
136480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
136580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
136680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::dumpPointArray(char** bufferPtrPtr, char* buffer, int count) {
136780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char* bufferPtr = *bufferPtrPtr;
136880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkPoint* pts = (const SkPoint*)fReadStream.getAtPos();
136980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fReadStream.skip(sizeof(SkPoint) * count);
137080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
137180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "count:%d {", count);
137280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < count; index++)
137380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
137480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "{x:%g y:%g}, ", SkScalarToFloat(pts[index].fX),
137580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalarToFloat(pts[index].fY));
137680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
137780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "} ");
137880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *bufferPtrPtr = bufferPtr;
137980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
138080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
138180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr) {
138280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
138380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "%s:%p, ", name, ptr);
138480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
138580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
138680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::dumpRectPtr(char* bufferPtr, char* buffer, char* name) {
138780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char result;
138880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fReadStream.read(&result, sizeof(result));
138980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (result)
139080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return dumpRect(bufferPtr, buffer, name);
139180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else
139280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
139380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "%s:NULL, ", name);
139480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
139580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
139680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPicturePlayback::dumpScalar(char* bufferPtr, char* buffer, char* name) {
139780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
139880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "%s:%d, ", name, getScalar());
139980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
140080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
140180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::dumpText(char** bufferPtrPtr, char* buffer) {
140280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char* bufferPtr = *bufferPtrPtr;
140380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int length = getInt();
140480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += dumpDrawType(bufferPtr, buffer);
140580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fReadStream.skipToAlign4();
140680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char* text = (char*) fReadStream.getAtPos();
140780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fReadStream.skip(length);
140880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += dumpInt(bufferPtr, buffer, "length");
140980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int limit = DUMP_BUFFER_SIZE - (bufferPtr - buffer) - 2;
141080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    length >>= 1;
141180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (limit > length)
141280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        limit = length;
141380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (limit > 0) {
141480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *bufferPtr++ = '"';
141580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int index = 0; index < limit; index++) {
141680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *bufferPtr++ = *(unsigned short*) text;
141780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            text += sizeof(unsigned short);
141880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
141980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *bufferPtr++ = '"';
142080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
142180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *bufferPtrPtr = bufferPtr;
142280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
142380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
142480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMP_DRAWTYPE(drawType) \
142580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += dumpDrawType(bufferPtr, buffer, drawType)
142680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
142780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMP_INT(name) \
142880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += dumpInt(bufferPtr, buffer, #name)
142980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
143080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMP_RECT_PTR(name) \
143180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += dumpRectPtr(bufferPtr, buffer, #name)
143280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
143380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMP_POINT(name) \
143480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += dumpRect(bufferPtr, buffer, #name)
143580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
143680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMP_RECT(name) \
143780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += dumpRect(bufferPtr, buffer, #name)
143880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
143980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMP_POINT_ARRAY(count) \
144080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dumpPointArray(&bufferPtr, buffer, count)
144180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
144280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMP_PTR(name, ptr) \
144380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += dumpPtr(bufferPtr, buffer, #name, (void*) ptr)
144480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
144580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMP_SCALAR(name) \
144680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr += dumpScalar(bufferPtr, buffer, #name)
144780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
144880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMP_TEXT() \
144980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dumpText(&bufferPtr, buffer)
145080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
145180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::dumpStream() {
145280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("RecordStream stream = {\n");
145380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    DrawType drawType;
145480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    TextContainer text;
145580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fReadStream.rewind();
145680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char buffer[DUMP_BUFFER_SIZE], * bufferPtr;
145780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    while (fReadStream.read(&drawType, sizeof(drawType))) {
145880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr = buffer;
145980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        DUMP_DRAWTYPE(drawType);
146080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        switch (drawType) {
146180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case CLIP_PATH: {
146280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPath, &getPath());
146380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_INT(SkRegion::Op);
146480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_INT(offsetToRestore);
146580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
146680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case CLIP_REGION: {
146780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkRegion, &getRegion());
146880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_INT(SkRegion::Op);
146980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_INT(offsetToRestore);
147080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
147180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case CLIP_RECT: {
147280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_RECT(rect);
147380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_INT(SkRegion::Op);
147480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_INT(offsetToRestore);
147580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
147680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case CONCAT:
147780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkMatrix, getMatrix());
147880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
147980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_BITMAP: {
148080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
148180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkBitmap, &getBitmap());
148280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(left);
148380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(top);
148480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
148580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_PAINT:
148680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
148780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
148880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_PATH: {
148980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
149080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPath, &getPath());
149180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
149280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_PICTURE: {
149380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPicture, &getPicture());
149480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
149580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_POINTS: {
149680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
149780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                (void)getInt(); // PointMode
149880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t count = getInt();
149980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fReadStream.skipToAlign4();
150080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_POINT_ARRAY(count);
150180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
150280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_POS_TEXT: {
150380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
150480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_TEXT();
150580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t points = getInt();
150680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fReadStream.skipToAlign4();
150780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_POINT_ARRAY(points);
150880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
150980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_POS_TEXT_H: {
151080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
151180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_TEXT();
151280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                size_t points = getInt();
151380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fReadStream.skipToAlign4();
151480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(top);
151580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(bottom);
151680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(constY);
151780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_POINT_ARRAY(points);
151880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
151980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_RECT: {
152080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
152180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_RECT(rect);
152280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
152380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_SPRITE: {
152480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
152580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkBitmap, &getBitmap());
152680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(left);
152780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(top);
152880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
152980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_TEXT: {
153080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
153180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_TEXT();
153280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(x);
153380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(y);
153480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
153580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case DRAW_TEXT_ON_PATH: {
153680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
153780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_TEXT();
153880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPath, &getPath());
153980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkMatrix, getMatrix());
154080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
154180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case RESTORE:
154280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
154380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case ROTATE:
154480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(rotate);
154580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
154680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SAVE:
154780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_INT(SkCanvas::SaveFlags);
154880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
154980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SAVE_LAYER: {
155080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_RECT_PTR(layer);
155180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_PTR(SkPaint, getPaint());
155280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_INT(SkCanvas::SaveFlags);
155380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
155480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SCALE: {
155580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(sx);
155680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(sy);
155780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
155880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SKEW: {
155980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(sx);
156080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(sy);
156180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
156280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case TRANSLATE: {
156380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(dx);
156480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                DUMP_SCALAR(dy);
156580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } break;
156680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            default:
156780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkASSERT(0);
156880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
156980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("%s\n", buffer);
157080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
157180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
157280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
157380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicturePlayback::dump() const {
157480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char pBuffer[DUMP_BUFFER_SIZE];
157580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char* bufferPtr = pBuffer;
157680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int index;
157780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fBitmapCount > 0)
157880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("// bitmaps (%d)\n", fBitmapCount);
157980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fBitmapCount; index++) {
158080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkBitmap& bitmap = fBitmaps[index];
158180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dumpBitmap(bitmap);
158280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
158380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fBitmapCount > 0)
158480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
158580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "Bitmaps bitmaps = {");
158680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fBitmapCount; index++)
158780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
158880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "bitmap%p, ", &fBitmaps[index]);
158980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fBitmapCount > 0)
159080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("%s0};\n", pBuffer);
159180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
159280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fMatrixCount > 0)
159380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("// matrices (%d)\n", fMatrixCount);
159480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fMatrixCount; index++) {
159580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkMatrix& matrix = fMatrices[index];
159680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dumpMatrix(matrix);
159780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
159880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr = pBuffer;
159980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fMatrixCount > 0)
160080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
160180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "Matrices matrices = {");
160280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fMatrixCount; index++)
160380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
160480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "matrix%p, ", &fMatrices[index]);
160580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fMatrixCount > 0)
160680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("%s0};\n", pBuffer);
160780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
160880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPaintCount > 0)
160980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("// paints (%d)\n", fPaintCount);
161080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fPaintCount; index++) {
161180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkPaint& paint = fPaints[index];
161280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dumpPaint(paint);
161380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
161480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr = pBuffer;
161580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPaintCount > 0)
161680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
161780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "Paints paints = {");
161880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fPaintCount; index++)
161980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
162080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "paint%p, ", &fPaints[index]);
162180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPaintCount > 0)
162280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("%s0};\n", pBuffer);
162380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
162480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fPathCount; index++) {
162580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkPath& path = fPaths[index];
162680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dumpPath(path);
162780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
162880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr = pBuffer;
162980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPathCount > 0)
163080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
163180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "Paths paths = {");
163280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fPathCount; index++)
163380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
163480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "path%p, ", &fPaths[index]);
163580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPathCount > 0)
163680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("%s0};\n", pBuffer);
163780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
163880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fPictureCount; index++) {
163980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dumpPicture(*fPictureRefs[index]);
164080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
164180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr = pBuffer;
164280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPictureCount > 0)
164380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
164480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "Pictures pictures = {");
164580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fPictureCount; index++)
164680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
164780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "picture%p, ", fPictureRefs[index]);
164880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPictureCount > 0)
164980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("%s0};\n", pBuffer);
165080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
165180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fRegionCount; index++) {
165280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkRegion& region = fRegions[index];
165380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dumpRegion(region);
165480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
165580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bufferPtr = pBuffer;
165680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fRegionCount > 0)
165780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
165880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "Regions regions = {");
165980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fRegionCount; index++)
166080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
166180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            "region%p, ", &fRegions[index]);
166280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fRegionCount > 0)
166380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("%s0};\n", pBuffer);
166480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
166580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const_cast<SkPicturePlayback*>(this)->dumpStream();
166680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
166780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
166880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
1669