blob: 54e1efe5501a21c45693dbf5b6cdad642df4e104 [file] [log] [blame]
djsollen@google.comc73dd5c2012-08-07 15:54:32 +00001
reed@google.com02f65f22012-08-06 21:20:05 +00002#include "SkBitmap.h"
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +00003#include "SkTableColorFilter.h"
djsollen@google.comc73dd5c2012-08-07 15:54:32 +00004#include "SkColorPriv.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +00005#include "SkReadBuffer.h"
6#include "SkWriteBuffer.h"
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +00007#include "SkUnPreMultiply.h"
robertphillips@google.com1202c2a2013-05-23 14:00:17 +00008#include "SkString.h"
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +00009
10class SkTable_ColorFilter : public SkColorFilter {
11public:
12 SkTable_ColorFilter(const uint8_t tableA[], const uint8_t tableR[],
13 const uint8_t tableG[], const uint8_t tableB[]) {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000014 fBitmap = NULL;
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000015 fFlags = 0;
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000016
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000017 uint8_t* dst = fStorage;
18 if (tableA) {
19 memcpy(dst, tableA, 256);
20 dst += 256;
21 fFlags |= kA_Flag;
22 }
23 if (tableR) {
24 memcpy(dst, tableR, 256);
25 dst += 256;
26 fFlags |= kR_Flag;
27 }
28 if (tableG) {
29 memcpy(dst, tableG, 256);
30 dst += 256;
31 fFlags |= kG_Flag;
32 }
33 if (tableB) {
34 memcpy(dst, tableB, 256);
35 fFlags |= kB_Flag;
36 }
37 }
38
tomhudson@google.com1bb4be22012-07-24 17:24:21 +000039 virtual ~SkTable_ColorFilter() {
40 SkDELETE(fBitmap);
41 }
42
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000043 virtual bool asComponentTable(SkBitmap* table) const SK_OVERRIDE;
44
45#if SK_SUPPORT_GPU
bsalomon97b9ab72014-07-08 06:52:35 -070046 virtual GrEffect* asNewEffect(GrContext* context) const SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000047#endif
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000048
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000049 virtual void filterSpan(const SkPMColor src[], int count,
reed@google.combada6442012-12-17 20:21:44 +000050 SkPMColor dst[]) const SK_OVERRIDE;
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000051
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +000052 SK_TO_STRING_OVERRIDE()
robertphillips@google.com1202c2a2013-05-23 14:00:17 +000053
djsollen@google.comba28d032012-03-26 17:57:35 +000054 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTable_ColorFilter)
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000055
bsalomon@google.com371e1052013-01-11 21:08:55 +000056 enum {
57 kA_Flag = 1 << 0,
58 kR_Flag = 1 << 1,
59 kG_Flag = 1 << 2,
60 kB_Flag = 1 << 3,
61 };
62
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000063protected:
reed9fa60da2014-08-21 07:59:51 -070064#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000065 SkTable_ColorFilter(SkReadBuffer& buffer);
reed9fa60da2014-08-21 07:59:51 -070066#endif
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000067 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000068
69private:
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000070 mutable const SkBitmap* fBitmap; // lazily allocated
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000071
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000072 uint8_t fStorage[256 * 4];
73 unsigned fFlags;
74
reed9fa60da2014-08-21 07:59:51 -070075 friend class SkTableColorFilter;
76
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000077 typedef SkColorFilter INHERITED;
78};
79
80static const uint8_t gIdentityTable[] = {
rmistry@google.comfbfcd562012-08-23 18:09:54 +000081 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
82 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
83 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
84 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
85 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
86 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
87 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
88 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
89 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
90 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
91 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
92 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
93 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
94 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
95 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
96 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
97 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
98 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
99 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
100 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
101 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
102 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
103 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
104 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
105 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
106 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
107 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
108 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
109 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
110 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
111 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000112 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
113};
114
115void SkTable_ColorFilter::filterSpan(const SkPMColor src[], int count,
reed@google.combada6442012-12-17 20:21:44 +0000116 SkPMColor dst[]) const {
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000117 const uint8_t* table = fStorage;
118 const uint8_t* tableA = gIdentityTable;
119 const uint8_t* tableR = gIdentityTable;
120 const uint8_t* tableG = gIdentityTable;
121 const uint8_t* tableB = gIdentityTable;
122 if (fFlags & kA_Flag) {
123 tableA = table; table += 256;
124 }
125 if (fFlags & kR_Flag) {
126 tableR = table; table += 256;
127 }
128 if (fFlags & kG_Flag) {
129 tableG = table; table += 256;
130 }
131 if (fFlags & kB_Flag) {
132 tableB = table;
133 }
134
135 const SkUnPreMultiply::Scale* scaleTable = SkUnPreMultiply::GetScaleTable();
136 for (int i = 0; i < count; ++i) {
137 SkPMColor c = src[i];
138 unsigned a, r, g, b;
139 if (0 == c) {
140 a = r = g = b = 0;
141 } else {
142 a = SkGetPackedA32(c);
143 r = SkGetPackedR32(c);
144 g = SkGetPackedG32(c);
145 b = SkGetPackedB32(c);
146
147 if (a < 255) {
148 SkUnPreMultiply::Scale scale = scaleTable[a];
149 r = SkUnPreMultiply::ApplyScale(scale, r);
150 g = SkUnPreMultiply::ApplyScale(scale, g);
151 b = SkUnPreMultiply::ApplyScale(scale, b);
152 }
153 }
154 dst[i] = SkPremultiplyARGBInline(tableA[a], tableR[r],
155 tableG[g], tableB[b]);
156 }
157}
158
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +0000159#ifndef SK_IGNORE_TO_STRING
robertphillips@google.com1202c2a2013-05-23 14:00:17 +0000160void SkTable_ColorFilter::toString(SkString* str) const {
161 str->append("SkTable_ColorFilter");
162}
163#endif
164
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000165static const uint8_t gCountNibBits[] = {
166 0, 1, 1, 2,
167 1, 2, 2, 3,
168 1, 2, 2, 3,
169 2, 3, 3, 4
170};
171
172#include "SkPackBits.h"
173
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000174void SkTable_ColorFilter::flatten(SkWriteBuffer& buffer) const {
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000175 uint8_t storage[5*256];
176 int count = gCountNibBits[fFlags & 0xF];
177 size_t size = SkPackBits::Pack8(fStorage, count * 256, storage);
178 SkASSERT(size <= sizeof(storage));
179
reed9fa60da2014-08-21 07:59:51 -0700180 buffer.write32(fFlags);
djsollen@google.comc73dd5c2012-08-07 15:54:32 +0000181 buffer.writeByteArray(storage, size);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000182}
183
reed9fa60da2014-08-21 07:59:51 -0700184SkFlattenable* SkTable_ColorFilter::CreateProc(SkReadBuffer& buffer) {
185 const int flags = buffer.read32();
186 const size_t count = gCountNibBits[flags & 0xF];
187 SkASSERT(count <= 4);
188
189 uint8_t packedStorage[5*256];
190 size_t packedSize = buffer.getArrayCount();
191 if (!buffer.validate(packedSize <= sizeof(packedStorage))) {
192 return NULL;
193 }
194 if (!buffer.readByteArray(packedStorage, packedSize)) {
195 return NULL;
196 }
197
198 uint8_t unpackedStorage[4*256];
199 size_t unpackedSize = SkPackBits::Unpack8(packedStorage, packedSize, unpackedStorage);
200 // now check that we got the size we expected
201 if (!buffer.validate(unpackedSize != count*256)) {
202 return NULL;
203 }
204
205 const uint8_t* a = NULL;
206 const uint8_t* r = NULL;
207 const uint8_t* g = NULL;
208 const uint8_t* b = NULL;
209 const uint8_t* ptr = unpackedStorage;
210
211 if (flags & kA_Flag) {
212 a = ptr;
213 ptr += 256;
214 }
215 if (flags & kR_Flag) {
216 r = ptr;
217 ptr += 256;
218 }
219 if (flags & kG_Flag) {
220 g = ptr;
221 ptr += 256;
222 }
223 if (flags & kB_Flag) {
224 b = ptr;
225 ptr += 256;
226 }
227 return SkTableColorFilter::CreateARGB(a, r, g, b);
228}
229
230#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000231SkTable_ColorFilter::SkTable_ColorFilter(SkReadBuffer& buffer) : INHERITED(buffer) {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000232 fBitmap = NULL;
233
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000234 uint8_t storage[5*256];
235
236 fFlags = buffer.readInt();
djsollen@google.comc73dd5c2012-08-07 15:54:32 +0000237
238 size_t size = buffer.getArrayCount();
239 SkASSERT(size <= sizeof(storage));
commit-bot@chromium.orgef74fa12013-12-17 20:49:46 +0000240 buffer.validate(size <= sizeof(storage));
commit-bot@chromium.org02512882013-10-31 18:37:50 +0000241 buffer.readByteArray(storage, size);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000242
humper@google.com0e515772013-01-07 19:54:40 +0000243 SkDEBUGCODE(size_t raw = ) SkPackBits::Unpack8(storage, size, fStorage);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000244
245 SkASSERT(raw <= sizeof(fStorage));
humper@google.com0e515772013-01-07 19:54:40 +0000246 SkDEBUGCODE(size_t count = gCountNibBits[fFlags & 0xF]);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000247 SkASSERT(raw == count * 256);
248}
reed9fa60da2014-08-21 07:59:51 -0700249#endif
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000250
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000251bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000252 if (table) {
253 if (NULL == fBitmap) {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000254 SkBitmap* bmp = SkNEW(SkBitmap);
reed@google.com9ebcac52014-01-24 18:53:42 +0000255 bmp->allocPixels(SkImageInfo::MakeA8(256, 4));
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000256 uint8_t* bitmapPixels = bmp->getAddr8(0, 0);
twiz@google.com58071162012-07-18 21:41:50 +0000257 int offset = 0;
258 static const unsigned kFlags[] = { kA_Flag, kR_Flag, kG_Flag, kB_Flag };
259
260 for (int x = 0; x < 4; ++x) {
261 if (!(fFlags & kFlags[x])) {
262 memcpy(bitmapPixels, gIdentityTable, sizeof(gIdentityTable));
263 } else {
264 memcpy(bitmapPixels, fStorage + offset, 256);
265 offset += 256;
266 }
267 bitmapPixels += 256;
268 }
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000269 fBitmap = bmp;
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000270 }
271 *table = *fBitmap;
272 }
273 return true;
274}
275
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000276#if SK_SUPPORT_GPU
277
bsalomon@google.coma469c282012-10-24 18:28:34 +0000278#include "GrEffect.h"
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +0000279#include "GrTBackendEffectFactory.h"
bsalomon@google.comd698f772012-10-25 13:22:00 +0000280#include "gl/GrGLEffect.h"
bsalomon848faf02014-07-11 10:01:02 -0700281#include "gl/GrGLShaderBuilder.h"
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000282#include "SkGr.h"
283
284class GLColorTableEffect;
285
bsalomon@google.coma469c282012-10-24 18:28:34 +0000286class ColorTableEffect : public GrEffect {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000287public:
bsalomon83d081a2014-07-08 09:56:10 -0700288 static GrEffect* Create(GrTexture* texture, unsigned flags) {
bsalomon55fad7a2014-07-08 07:34:20 -0700289 return SkNEW_ARGS(ColorTableEffect, (texture, flags));
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000290 }
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000291
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000292 virtual ~ColorTableEffect();
293
294 static const char* Name() { return "ColorTable"; }
bsalomon@google.com396e61f2012-10-25 19:00:29 +0000295 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000296
bsalomon@google.com371e1052013-01-11 21:08:55 +0000297 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
298
bsalomon@google.com422e81a2012-10-25 14:11:03 +0000299 typedef GLColorTableEffect GLEffect;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000300
301private:
bsalomon@google.com8a252f72013-01-22 20:35:13 +0000302 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000303
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000304 explicit ColorTableEffect(GrTexture* texture, unsigned flags);
305
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000306 GR_DECLARE_EFFECT_TEST;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000307
308 GrTextureAccess fTextureAccess;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000309 unsigned fFlags; // currently not used in shader code, just to assist
310 // getConstantColorComponents().
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000311
bsalomon@google.coma469c282012-10-24 18:28:34 +0000312 typedef GrEffect INHERITED;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000313};
314
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000315class GLColorTableEffect : public GrGLEffect {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000316public:
bsalomon@google.comc7818882013-03-20 19:19:53 +0000317 GLColorTableEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000318
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000319 virtual void emitCode(GrGLShaderBuilder*,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000320 const GrDrawEffect&,
bsalomon63e99f72014-07-21 08:03:14 -0700321 const GrEffectKey&,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000322 const char* outputColor,
323 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000324 const TransformedCoordsArray&,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000325 const TextureSamplerArray&) SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000326
kkinnunen7510b222014-07-30 00:04:16 -0700327 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE {}
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000328
bsalomon63e99f72014-07-21 08:03:14 -0700329 static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder* b) {}
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000330
331private:
332
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000333 typedef GrGLEffect INHERITED;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000334};
335
bsalomon@google.comc7818882013-03-20 19:19:53 +0000336GLColorTableEffect::GLColorTableEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000337 : INHERITED(factory) {
338 }
339
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000340void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000341 const GrDrawEffect&,
bsalomon63e99f72014-07-21 08:03:14 -0700342 const GrEffectKey&,
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000343 const char* outputColor,
344 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000345 const TransformedCoordsArray&,
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000346 const TextureSamplerArray& samplers) {
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000347
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000348 static const float kColorScaleFactor = 255.0f / 256.0f;
349 static const float kColorOffsetFactor = 1.0f / 512.0f;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000350 if (NULL == inputColor) {
351 // the input color is solid white (all ones).
352 static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000353 builder->fsCodeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
354 kMaxValue, kMaxValue, kMaxValue, kMaxValue);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000355
356 } else {
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000357 builder->fsCodeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", inputColor);
358 builder->fsCodeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n", inputColor);
359 builder->fsCodeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
360 kColorScaleFactor,
361 kColorOffsetFactor, kColorOffsetFactor,
362 kColorOffsetFactor, kColorOffsetFactor);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000363 }
364
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000365 builder->fsCodeAppendf("\t\t%s.a = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000366 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.a, 0.125)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000367 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000368
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000369 builder->fsCodeAppendf("\t\t%s.r = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000370 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.r, 0.375)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000371 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000372
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000373 builder->fsCodeAppendf("\t\t%s.g = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000374 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.g, 0.625)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000375 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000376
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000377 builder->fsCodeAppendf("\t\t%s.b = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000378 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.b, 0.875)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000379 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000380
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000381 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000382}
383
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000384///////////////////////////////////////////////////////////////////////////////
385
bsalomon@google.com371e1052013-01-11 21:08:55 +0000386ColorTableEffect::ColorTableEffect(GrTexture* texture, unsigned flags)
387 : fTextureAccess(texture, "a")
388 , fFlags(flags) {
bsalomon@google.com50db75c2013-01-11 13:54:30 +0000389 this->addTextureAccess(&fTextureAccess);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000390}
391
392ColorTableEffect::~ColorTableEffect() {
393}
394
bsalomon@google.com396e61f2012-10-25 19:00:29 +0000395const GrBackendEffectFactory& ColorTableEffect::getFactory() const {
396 return GrTBackendEffectFactory<ColorTableEffect>::getInstance();
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000397}
398
bsalomon@google.com8a252f72013-01-22 20:35:13 +0000399bool ColorTableEffect::onIsEqual(const GrEffect& sBase) const {
400 return this->texture(0) == sBase.texture(0);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000401}
402
bsalomon@google.com371e1052013-01-11 21:08:55 +0000403void ColorTableEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
404 // If we kept the table in the effect then we could actually run known inputs through the
405 // table.
406 if (fFlags & SkTable_ColorFilter::kR_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000407 *validFlags &= ~kR_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000408 }
409 if (fFlags & SkTable_ColorFilter::kG_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000410 *validFlags &= ~kG_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000411 }
412 if (fFlags & SkTable_ColorFilter::kB_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000413 *validFlags &= ~kB_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000414 }
415 if (fFlags & SkTable_ColorFilter::kA_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000416 *validFlags &= ~kA_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000417 }
418}
419
420
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000421///////////////////////////////////////////////////////////////////////////////
422
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000423GR_DEFINE_EFFECT_TEST(ColorTableEffect);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000424
bsalomon83d081a2014-07-08 09:56:10 -0700425GrEffect* ColorTableEffect::TestCreate(SkRandom* random,
426 GrContext* context,
427 const GrDrawTargetCaps&,
428 GrTexture* textures[]) {
bsalomon@google.com371e1052013-01-11 21:08:55 +0000429 static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilter::kG_Flag |
430 SkTable_ColorFilter::kB_Flag | SkTable_ColorFilter::kA_Flag;
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000431 return ColorTableEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000432}
433
bsalomon83d081a2014-07-08 09:56:10 -0700434GrEffect* SkTable_ColorFilter::asNewEffect(GrContext* context) const {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000435 SkBitmap bitmap;
bsalomon83d081a2014-07-08 09:56:10 -0700436 GrEffect* effect = NULL;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000437 this->asComponentTable(&bitmap);
bsalomon@google.com8ea78d82012-10-24 20:11:30 +0000438 // passing NULL because this effect does no tiling or filtering.
bsalomon@google.com95ed55a2013-01-24 14:46:47 +0000439 GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, bitmap, NULL);
commit-bot@chromium.orgc7d624e2013-05-28 13:13:56 +0000440 if (NULL != texture) {
441 effect = ColorTableEffect::Create(texture, fFlags);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000442
commit-bot@chromium.orgc7d624e2013-05-28 13:13:56 +0000443 // Unlock immediately, this is not great, but we don't have a way of
444 // knowing when else to unlock it currently. TODO: Remove this when
445 // unref becomes the unlock replacement for all types of textures.
446 GrUnlockAndUnrefCachedBitmapTexture(texture);
447 }
bsalomon@google.com021fc732012-10-25 12:47:42 +0000448 return effect;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000449}
450
451#endif // SK_SUPPORT_GPU
452
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000453///////////////////////////////////////////////////////////////////////////////
454
455#ifdef SK_CPU_BENDIAN
456#else
457 #define SK_A32_INDEX (3 - (SK_A32_SHIFT >> 3))
458 #define SK_R32_INDEX (3 - (SK_R32_SHIFT >> 3))
459 #define SK_G32_INDEX (3 - (SK_G32_SHIFT >> 3))
460 #define SK_B32_INDEX (3 - (SK_B32_SHIFT >> 3))
461#endif
462
463///////////////////////////////////////////////////////////////////////////////
464
465SkColorFilter* SkTableColorFilter::Create(const uint8_t table[256]) {
466 return SkNEW_ARGS(SkTable_ColorFilter, (table, table, table, table));
467}
468
469SkColorFilter* SkTableColorFilter::CreateARGB(const uint8_t tableA[256],
470 const uint8_t tableR[256],
471 const uint8_t tableG[256],
472 const uint8_t tableB[256]) {
473 return SkNEW_ARGS(SkTable_ColorFilter, (tableA, tableR, tableG, tableB));
474}
djsollen@google.coma2ca41e2012-03-23 19:00:34 +0000475
476SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkTableColorFilter)
477 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTable_ColorFilter)
478SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END