180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2007 The Android Open Source Project
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
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPictureFlat.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPicturePlayback.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPictureRecord.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkCanvas.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkChunkAlloc.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkDevice.h"
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPicture.h"
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRegion.h"
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h"
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTDArray.h"
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTSearch.h"
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTime.h"
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkReader32.h"
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkWriter32.h"
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRTree.h"
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBBoxHierarchyRecord.h"
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_INST_COUNT(SkPicture)
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMP_BUFFER_SIZE 65536
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//#define ENABLE_TIME_DRAW    // dumps milliseconds for each draw
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// enable SK_DEBUG_TRACE to trace DrawType elements when
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//     recorded and played back
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// #define SK_DEBUG_TRACE
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// enable SK_DEBUG_SIZE to see the size of picture components
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// #define SK_DEBUG_SIZE
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// enable SK_DEBUG_DUMP to see the contents of recorded elements
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// #define SK_DEBUG_DUMP
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// enable SK_DEBUG_VALIDATE to check internal structures for consistency
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// #define SK_DEBUG_VALIDATE
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined SK_DEBUG_TRACE || defined SK_DEBUG_DUMP
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* DrawTypeToString(DrawType drawType) {
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch (drawType) {
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case UNUSED: SkDebugf("DrawType UNUSED\n"); SkASSERT(0); break;
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case CLIP_PATH: return "CLIP_PATH";
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case CLIP_REGION: return "CLIP_REGION";
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case CLIP_RECT: return "CLIP_RECT";
55096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case CLIP_RRECT: return "CLIP_RRECT";
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case CONCAT: return "CONCAT";
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_BITMAP: return "DRAW_BITMAP";
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_BITMAP_MATRIX: return "DRAW_BITMAP_MATRIX";
59096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_BITMAP_NINE: return "DRAW_BITMAP_NINE";
60096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_BITMAP_RECT_TO_RECT: return "DRAW_BITMAP_RECT_TO_RECT";
61096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_CLEAR: return "DRAW_CLEAR";
62096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_DATA: return "DRAW_DATA";
63096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_OVAL: return "DRAW_OVAL";
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_PAINT: return "DRAW_PAINT";
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_PATH: return "DRAW_PATH";
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_PICTURE: return "DRAW_PICTURE";
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_POINTS: return "DRAW_POINTS";
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_POS_TEXT: return "DRAW_POS_TEXT";
69096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_POS_TEXT_TOP_BOTTOM: return "DRAW_POS_TEXT_TOP_BOTTOM";
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_POS_TEXT_H: return "DRAW_POS_TEXT_H";
71096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_POS_TEXT_H_TOP_BOTTOM: return "DRAW_POS_TEXT_H_TOP_BOTTOM";
72096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_RECT: return "DRAW_RECT";
73096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_RRECT: return "DRAW_RRECT";
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_SPRITE: return "DRAW_SPRITE";
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_TEXT: return "DRAW_TEXT";
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case DRAW_TEXT_ON_PATH: return "DRAW_TEXT_ON_PATH";
77096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_TEXT_TOP_BOTTOM: return "DRAW_TEXT_TOP_BOTTOM";
78096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case DRAW_VERTICES: return "DRAW_VERTICES";
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case RESTORE: return "RESTORE";
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case ROTATE: return "ROTATE";
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case SAVE: return "SAVE";
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case SAVE_LAYER: return "SAVE_LAYER";
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case SCALE: return "SCALE";
84096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case SET_MATRIX: return "SET_MATRIX";
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case SKEW: return "SKEW";
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case TRANSLATE: return "TRANSLATE";
87096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case NOOP: return "NOOP";
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        default:
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkDebugf("DrawType error 0x%08x\n", drawType);
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkASSERT(0);
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            break;
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(0);
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return NULL;
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG_VALIDATE
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void validateMatrix(const SkMatrix* matrix) {
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar scaleX = matrix->getScaleX();
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar scaleY = matrix->getScaleY();
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar skewX = matrix->getSkewX();
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar skewY = matrix->getSkewY();
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar perspX = matrix->getPerspX();
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar perspY = matrix->getPerspY();
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scaleX != 0 && skewX != 0)
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("scaleX != 0 && skewX != 0\n");
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(scaleX == 0 || skewX == 0);
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(scaleY == 0 || skewY == 0);
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(perspX == 0);
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(perspY == 0);
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPicture::SkPicture() {
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRecord = NULL;
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPlayback = NULL;
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fWidth = fHeight = 0;
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkPicture::SkPicture(const SkPicture& src) : INHERITED() {
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fWidth = src.fWidth;
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fHeight = src.fHeight;
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRecord = NULL;
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /*  We want to copy the src's playback. However, if that hasn't been built
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        yet, we need to fake a call to endRecording() without actually calling
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        it (since it is destructive, and we don't want to change src).
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (src.fPlayback) {
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fPlayback));
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else if (src.fRecord) {
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // here we do a fake src.endRecording()
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fRecord));
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPlayback = NULL;
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPicture::~SkPicture() {
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeUnref(fRecord);
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDELETE(fPlayback);
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicture::swap(SkPicture& other) {
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTSwap(fRecord, other.fRecord);
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTSwap(fPlayback, other.fPlayback);
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTSwap(fWidth, other.fWidth);
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTSwap(fHeight, other.fHeight);
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPicture* SkPicture::clone() const {
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPicture* clonedPicture = SkNEW(SkPicture);
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    clone(clonedPicture, 1);
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return clonedPicture;
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicture::clone(SkPicture* pictures, int count) const {
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPictCopyInfo copyInfo;
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < count; i++) {
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkPicture* clone = &pictures[i];
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        clone->fWidth = fWidth;
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        clone->fHeight = fHeight;
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        clone->fRecord = NULL;
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
171363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        if (NULL != clone->fRecord) {
172363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            clone->fRecord->unref();
173363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            clone->fRecord = NULL;
174363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        }
175363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkDELETE(clone->fPlayback);
176363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        /*  We want to copy the src's playback. However, if that hasn't been built
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            yet, we need to fake a call to endRecording() without actually calling
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            it (since it is destructive, and we don't want to change src).
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         */
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fPlayback) {
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fPlayback, &copyInfo));
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else if (fRecord) {
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // here we do a fake src.endRecording()
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, true));
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            clone->fPlayback = NULL;
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCanvas* SkPicture::beginRecording(int width, int height,
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    uint32_t recordingFlags) {
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPlayback) {
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDELETE(fPlayback);
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPlayback = NULL;
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL != fRecord) {
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fRecord->unref();
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fRecord = NULL;
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap bm;
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.setConfig(SkBitmap::kNo_Config, width, height);
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoTUnref<SkDevice> dev(SkNEW_ARGS(SkDevice, (bm)));
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
210363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    // Must be set before calling createBBoxHierarchy
211363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    fWidth = width;
212363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    fHeight = height;
213363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (recordingFlags & kOptimizeForClippedPlayback_RecordingFlag) {
215363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkBBoxHierarchy* tree = this->createBBoxHierarchy();
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(NULL != tree);
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (recordingFlags, tree, dev));
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        tree->unref();
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fRecord = SkNEW_ARGS(SkPictureRecord, (recordingFlags, dev));
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRecord->beginRecording();
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return fRecord;
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
227363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerSkBBoxHierarchy* SkPicture::createBBoxHierarchy() const {
228363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    // These values were empirically determined to produce reasonable
229363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    // performance in most cases.
230363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    static const int kRTreeMinChildren = 6;
231363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    static const int kRTreeMaxChildren = 11;
232363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
233363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkScalar aspectRatio = SkScalarDiv(SkIntToScalar(fWidth),
234363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                       SkIntToScalar(fHeight));
235363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return SkRTree::Create(kRTreeMinChildren, kRTreeMaxChildren,
236363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                           aspectRatio);
237363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
238363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCanvas* SkPicture::getRecordingCanvas() const {
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // will be null if we are not recording
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return fRecord;
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicture::endRecording() {
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == fPlayback) {
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL != fRecord) {
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fRecord->endRecording();
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord));
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fRecord->unref();
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fRecord = NULL;
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(NULL == fRecord);
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) {
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->endRecording();
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fPlayback) {
2597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fPlayback->draw(*surface, callback);
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h"
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerbool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
26858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (NULL == stream) {
26958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return false;
27058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
271096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
27258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPictInfo info;
27358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (!stream->read(&info, sizeof(SkPictInfo))) {
27458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return false;
27558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
27658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (PICTURE_VERSION != info.fVersion) {
27758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return false;
27858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
279096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
28058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (pInfo != NULL) {
28158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        *pInfo = info;
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
28358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return true;
28458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
28558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
28658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkPicture::SkPicture(SkPicturePlayback* playback, int width, int height)
28758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    : fPlayback(playback)
28858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    , fRecord(NULL)
28958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    , fWidth(width)
29058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    , fHeight(height) {}
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc proc) {
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPictInfo info;
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (!StreamIsSKP(stream, &info)) {
29658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return NULL;
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPicturePlayback* playback;
30058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // Check to see if there is a playback to recreate.
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (stream->readBool()) {
30258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        playback = SkNEW_ARGS(SkPicturePlayback, (stream, info, proc));
30358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    } else {
30458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        playback = NULL;
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
310096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergervoid SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPicturePlayback* playback = fPlayback;
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == playback && fRecord) {
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord));
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPictInfo info;
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    info.fVersion = PICTURE_VERSION;
32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    info.fWidth = fWidth;
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    info.fHeight = fHeight;
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    info.fFlags = SkPictInfo::kCrossProcess_Flag;
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    info.fFlags |= SkPictInfo::kScalarIsFloat_Flag;
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (8 == sizeof(void*)) {
32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        info.fFlags |= SkPictInfo::kPtrIs64Bit_Flag;
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    stream->write(&info, sizeof(info));
33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (playback) {
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        stream->writeBool(true);
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        playback->serialize(stream, encoder);
33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // delete playback if it is a local version (i.e. cons'd up just now)
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (playback != fPlayback) {
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkDELETE(playback);
33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        stream->writeBool(false);
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
343d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPicture::abortPlayback() {
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == fPlayback) {
34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPlayback->abort();
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
350d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif
351