SkPictureFlat.cpp revision cae5d8d5705081cb4d22af7a30be0f01bffce745
1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "SkPictureFlat.h"
9
10#include "SkChecksum.h"
11#include "SkColorFilter.h"
12#include "SkDrawLooper.h"
13#include "SkMaskFilter.h"
14#include "SkRasterizer.h"
15#include "SkShader.h"
16#include "SkTypeface.h"
17#include "SkXfermode.h"
18
19SK_DEFINE_INST_COUNT(SkFlatController)
20
21///////////////////////////////////////////////////////////////////////////////
22
23SkTypefacePlayback::SkTypefacePlayback() : fCount(0), fArray(NULL) {}
24
25SkTypefacePlayback::~SkTypefacePlayback() {
26    this->reset(NULL);
27}
28
29void SkTypefacePlayback::reset(const SkRefCntSet* rec) {
30    for (int i = 0; i < fCount; i++) {
31        SkASSERT(fArray[i]);
32        fArray[i]->unref();
33    }
34    SkDELETE_ARRAY(fArray);
35
36    if (rec!= NULL && rec->count() > 0) {
37        fCount = rec->count();
38        fArray = SkNEW_ARRAY(SkRefCnt*, fCount);
39        rec->copyToArray(fArray);
40        for (int i = 0; i < fCount; i++) {
41            fArray[i]->ref();
42        }
43    } else {
44        fCount = 0;
45        fArray = NULL;
46    }
47}
48
49void SkTypefacePlayback::setCount(int count) {
50    this->reset(NULL);
51
52    fCount = count;
53    fArray = SkNEW_ARRAY(SkRefCnt*, count);
54    sk_bzero(fArray, count * sizeof(SkRefCnt*));
55}
56
57SkRefCnt* SkTypefacePlayback::set(int index, SkRefCnt* obj) {
58    SkASSERT((unsigned)index < (unsigned)fCount);
59    SkRefCnt_SafeAssign(fArray[index], obj);
60    return obj;
61}
62
63///////////////////////////////////////////////////////////////////////////////
64
65SkFlatController::SkFlatController()
66: fBitmapHeap(NULL)
67, fTypefaceSet(NULL)
68, fTypefacePlayback(NULL)
69, fFactorySet(NULL)
70, fWriteBufferFlags(0) {}
71
72SkFlatController::~SkFlatController() {
73    SkSafeUnref(fBitmapHeap);
74    SkSafeUnref(fTypefaceSet);
75    SkSafeUnref(fFactorySet);
76}
77
78void SkFlatController::setBitmapHeap(SkBitmapHeap* heap) {
79    SkRefCnt_SafeAssign(fBitmapHeap, heap);
80}
81
82void SkFlatController::setTypefaceSet(SkRefCntSet *set) {
83    SkRefCnt_SafeAssign(fTypefaceSet, set);
84}
85
86void SkFlatController::setTypefacePlayback(SkTypefacePlayback* playback) {
87    fTypefacePlayback = playback;
88}
89
90SkNamedFactorySet* SkFlatController::setNamedFactorySet(SkNamedFactorySet* set) {
91    SkRefCnt_SafeAssign(fFactorySet, set);
92    return set;
93}
94
95///////////////////////////////////////////////////////////////////////////////
96
97void SkFlatData::stampHeaderAndSentinel(int index, int32_t size) {
98    fIndex    = index;
99    fFlatSize = size;
100    fChecksum = SkChecksum::Compute(this->data32(), size);
101    this->setTopBotUnwritten();
102    this->setSentinelAsCandidate();
103}
104
105SkFlatData* SkFlatData::Create(SkFlatController* controller, const void* obj,
106        int index, void (*flattenProc)(SkOrderedWriteBuffer&, const void*)) {
107    // a buffer of 256 bytes should be sufficient for most paints, regions,
108    // and matrices.
109    intptr_t storage[256];
110    SkOrderedWriteBuffer buffer(256, storage, sizeof(storage));
111
112    buffer.setBitmapHeap(controller->getBitmapHeap());
113    buffer.setTypefaceRecorder(controller->getTypefaceSet());
114    buffer.setNamedFactoryRecorder(controller->getNamedFactorySet());
115    buffer.setFlags(controller->getWriteBufferFlags());
116
117    flattenProc(buffer, obj);
118    uint32_t size = buffer.size();
119    SkASSERT(SkIsAlign4(size));
120
121    /**
122     *  Allocate enough memory to hold
123     *  1. SkFlatData struct
124     *  2. flattenProc's data (4-byte aligned)
125     *  3. 4-byte sentinel
126     */
127    size_t allocSize = sizeof(SkFlatData) + size + sizeof(uint32_t);
128    SkFlatData* result = (SkFlatData*) controller->allocThrow(allocSize);
129
130    // put the serialized contents into the data section of the new allocation
131    buffer.writeToMemory(result->data());
132    result->stampHeaderAndSentinel(index, size);
133    return result;
134}
135
136void SkFlatData::unflatten(void* result,
137        void (*unflattenProc)(SkOrderedReadBuffer&, void*),
138        SkBitmapHeap* bitmapHeap,
139        SkTypefacePlayback* facePlayback) const {
140
141    SkOrderedReadBuffer buffer(this->data(), fFlatSize);
142
143    if (bitmapHeap) {
144        buffer.setBitmapStorage(bitmapHeap);
145    }
146    if (facePlayback) {
147        facePlayback->setupBuffer(buffer);
148    }
149
150    unflattenProc(buffer, result);
151    SkASSERT(fFlatSize == (int32_t)buffer.offset());
152}
153