blob: ec04495db9cdf1e429ec9241073721aabe05c1f2 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SkPictureFlat.h"
9
junov@chromium.orgef760602012-06-27 20:03:16 +000010#include "SkChecksum.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000011#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
reed@android.com8a1c16f2008-12-17 15:59:43 +000019///////////////////////////////////////////////////////////////////////////////
20
21SkRefCntPlayback::SkRefCntPlayback() : fCount(0), fArray(NULL) {}
22
23SkRefCntPlayback::~SkRefCntPlayback() {
24 this->reset(NULL);
25}
26
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000027void SkRefCntPlayback::reset(const SkRefCntSet* rec) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000028 for (int i = 0; i < fCount; i++) {
29 SkASSERT(fArray[i]);
30 fArray[i]->unref();
31 }
32 SkDELETE_ARRAY(fArray);
33
34 if (rec) {
35 fCount = rec->count();
36 fArray = SkNEW_ARRAY(SkRefCnt*, fCount);
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000037 rec->copyToArray(fArray);
reed@android.com8a1c16f2008-12-17 15:59:43 +000038 for (int i = 0; i < fCount; i++) {
39 fArray[i]->ref();
40 }
41 } else {
42 fCount = 0;
43 fArray = NULL;
44 }
45}
46
47void SkRefCntPlayback::setCount(int count) {
48 this->reset(NULL);
49
50 fCount = count;
51 fArray = SkNEW_ARRAY(SkRefCnt*, count);
reed@android.com4516f472009-06-29 16:25:36 +000052 sk_bzero(fArray, count * sizeof(SkRefCnt*));
reed@android.com8a1c16f2008-12-17 15:59:43 +000053}
54
55SkRefCnt* SkRefCntPlayback::set(int index, SkRefCnt* obj) {
56 SkASSERT((unsigned)index < (unsigned)fCount);
57 SkRefCnt_SafeAssign(fArray[index], obj);
58 return obj;
59}
60
djsollen@google.comd2700ee2012-05-30 16:54:13 +000061///////////////////////////////////////////////////////////////////////////////
62
63SkFlatData* SkFlatData::Create(SkChunkAlloc* heap, const void* obj,
64 int index, void (*flattenProc)(SkOrderedWriteBuffer&, const void*),
junov@chromium.org4866cc02012-06-01 21:23:07 +000065 SkRefCntSet* refCntRecorder, SkRefCntSet* faceRecorder,
66 uint32_t writeBufferflags) {
djsollen@google.comd2700ee2012-05-30 16:54:13 +000067
68 // a buffer of 256 bytes should be sufficient for most paints, regions,
69 // and matrices.
70 intptr_t storage[256];
71 SkOrderedWriteBuffer buffer(256, storage, sizeof(storage));
72 if (refCntRecorder) {
73 buffer.setRefCntRecorder(refCntRecorder);
74 }
75 if (faceRecorder) {
76 buffer.setTypefaceRecorder(faceRecorder);
77 }
junov@chromium.org4866cc02012-06-01 21:23:07 +000078 buffer.setFlags(writeBufferflags);
djsollen@google.comd2700ee2012-05-30 16:54:13 +000079
80 flattenProc(buffer, obj);
81 uint32_t size = buffer.size();
82
junov@chromium.orgef760602012-06-27 20:03:16 +000083
84#if !SK_PREFER_32BIT_CHECKSUM
85 uint32_t unpaddedSize = size;
86 size = SkAlign8(size);
87#endif
88
89 // allocate enough memory to hold both SkFlatData and the serialized
djsollen@google.comd2700ee2012-05-30 16:54:13 +000090 // contents
91 SkFlatData* result = (SkFlatData*) heap->allocThrow(size + sizeof(SkFlatData));
92 result->fIndex = index;
93 result->fAllocSize = size;
94
95 // put the serialized contents into the data section of the new allocation
96 buffer.flatten(result->data());
junov@chromium.orgef760602012-06-27 20:03:16 +000097#if SK_PREFER_32BIT_CHECKSUM
98 result->fChecksum =
99 SkComputeChecksum32(reinterpret_cast<uint32_t*>(result->data()), size);
100#else
101 if (size != unpaddedSize) {
102 // Flat data is padded: put zeros in the last 32 bits.
103 SkASSERT(size - 4 == unpaddedSize);
104 *((uint32_t*)((char*)result->data() + unpaddedSize)) = 0;
105 }
106 result->fChecksum =
107 SkComputeChecksum64(reinterpret_cast<uint64_t*>(result->data()), size);
108#endif
djsollen@google.comd2700ee2012-05-30 16:54:13 +0000109 return result;
110}
111
112void SkFlatData::unflatten(void* result,
113 void (*unflattenProc)(SkOrderedReadBuffer&, void*),
114 SkRefCntPlayback* refCntPlayback,
115 SkTypefacePlayback* facePlayback) const {
116
117 SkOrderedReadBuffer buffer(this->data(), fAllocSize);
118 if (refCntPlayback) {
119 refCntPlayback->setupBuffer(buffer);
120 }
121 if (facePlayback) {
122 facePlayback->setupBuffer(buffer);
123 }
124 unflattenProc(buffer, result);
junov@chromium.orgef760602012-06-27 20:03:16 +0000125 SkASSERT(fAllocSize == SkAlign8((int32_t)buffer.offset()));
djsollen@google.comd2700ee2012-05-30 16:54:13 +0000126}