blob: f991da3bc0f35f239ee520866cbb73b44c8e382e [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/* libs/graphics/sgl/SkColorTable.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#include "SkBitmap.h"
19#include "SkFlattenable.h"
20#include "SkStream.h"
21#include "SkTemplates.h"
22
23SkColorTable::SkColorTable(int count)
24 : f16BitCache(NULL), fFlags(0)
25{
26 if (count < 0)
27 count = 0;
28 else if (count > 256)
29 count = 256;
30
31 fCount = SkToU16(count);
32 fColors = (SkPMColor*)sk_malloc_throw(count * sizeof(SkPMColor));
33 memset(fColors, 0, count * sizeof(SkPMColor));
34
35 SkDEBUGCODE(fColorLockCount = 0;)
36 SkDEBUGCODE(f16BitCacheLockCount = 0;)
37}
38
39SkColorTable::SkColorTable(const SkPMColor colors[], int count)
40 : f16BitCache(NULL), fFlags(0)
41{
42 if (count < 0)
43 count = 0;
44 else if (count > 256)
45 count = 256;
46
47 fCount = SkToU16(count);
48 fColors = (SkPMColor*)sk_malloc_throw(count * sizeof(SkPMColor));
49
50 if (colors)
51 memcpy(fColors, colors, count * sizeof(SkPMColor));
52
53 SkDEBUGCODE(fColorLockCount = 0;)
54 SkDEBUGCODE(f16BitCacheLockCount = 0;)
55}
56
57SkColorTable::~SkColorTable()
58{
59 SkASSERT(fColorLockCount == 0);
60 SkASSERT(f16BitCacheLockCount == 0);
61
62 sk_free(fColors);
63 sk_free(f16BitCache);
64}
65
66void SkColorTable::setFlags(unsigned flags)
67{
68 fFlags = SkToU8(flags);
69}
70
71void SkColorTable::unlockColors(bool changed)
72{
73 SkASSERT(fColorLockCount != 0);
74 SkDEBUGCODE(fColorLockCount -= 1;)
75 if (changed)
76 this->inval16BitCache();
77}
78
79void SkColorTable::inval16BitCache()
80{
81 SkASSERT(f16BitCacheLockCount == 0);
82 if (f16BitCache)
83 {
84 sk_free(f16BitCache);
85 f16BitCache = NULL;
86 }
87}
88
89#include "SkColorPriv.h"
90
91static inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], int count)
92{
93 while (--count >= 0)
94 *dst++ = SkPixel32ToPixel16_ToU16(*src++);
95}
96
97const uint16_t* SkColorTable::lock16BitCache()
98{
99 if (fFlags & kColorsAreOpaque_Flag)
100 {
101 if (f16BitCache == NULL) // build the cache
102 {
103 f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t));
104 build_16bitcache(f16BitCache, fColors, fCount);
105 }
106 }
107 else // our colors have alpha, so no cache
108 {
109 this->inval16BitCache();
110 if (f16BitCache)
111 {
112 sk_free(f16BitCache);
113 f16BitCache = NULL;
114 }
115 }
116
117 SkDEBUGCODE(f16BitCacheLockCount += 1);
118 return f16BitCache;
119}
120
121///////////////////////////////////////////////////////////////////////////////
122
123SkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) {
124 f16BitCache = NULL;
125 SkDEBUGCODE(fColorLockCount = 0;)
126 SkDEBUGCODE(f16BitCacheLockCount = 0;)
127
128 fCount = buffer.readU16();
129 SkASSERT((unsigned)fCount <= 256);
130
131 fFlags = buffer.readU8();
132
133 fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor));
134 buffer.read(fColors, fCount * sizeof(SkPMColor));
135}
136
137void SkColorTable::flatten(SkFlattenableWriteBuffer& buffer) const {
138 int count = this->count();
139 buffer.write16(count);
140 buffer.write8(this->getFlags());
141 buffer.writeMul4(fColors, count * sizeof(SkPMColor));
142}
143