blob: f6088f56beb2e68f4e170fc9e932ff2f7c745a38 [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"
5#include "SkFlattenableBuffers.h"
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +00006#include "SkUnPreMultiply.h"
robertphillips@google.com1202c2a2013-05-23 14:00:17 +00007#include "SkString.h"
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +00008
9class SkTable_ColorFilter : public SkColorFilter {
10public:
11 SkTable_ColorFilter(const uint8_t tableA[], const uint8_t tableR[],
12 const uint8_t tableG[], const uint8_t tableB[]) {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000013 fBitmap = NULL;
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000014 fFlags = 0;
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000015
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000016 uint8_t* dst = fStorage;
17 if (tableA) {
18 memcpy(dst, tableA, 256);
19 dst += 256;
20 fFlags |= kA_Flag;
21 }
22 if (tableR) {
23 memcpy(dst, tableR, 256);
24 dst += 256;
25 fFlags |= kR_Flag;
26 }
27 if (tableG) {
28 memcpy(dst, tableG, 256);
29 dst += 256;
30 fFlags |= kG_Flag;
31 }
32 if (tableB) {
33 memcpy(dst, tableB, 256);
34 fFlags |= kB_Flag;
35 }
36 }
37
tomhudson@google.com1bb4be22012-07-24 17:24:21 +000038 virtual ~SkTable_ColorFilter() {
39 SkDELETE(fBitmap);
40 }
41
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000042 virtual bool asComponentTable(SkBitmap* table) const SK_OVERRIDE;
43
44#if SK_SUPPORT_GPU
bsalomon@google.com0ac6af42013-01-16 15:16:18 +000045 virtual GrEffectRef* asNewEffect(GrContext* context) const SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000046#endif
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000047
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000048 virtual void filterSpan(const SkPMColor src[], int count,
reed@google.combada6442012-12-17 20:21:44 +000049 SkPMColor dst[]) const SK_OVERRIDE;
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000050
robertphillips@google.com1202c2a2013-05-23 14:00:17 +000051 SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;)
52
djsollen@google.comba28d032012-03-26 17:57:35 +000053 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTable_ColorFilter)
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000054
bsalomon@google.com371e1052013-01-11 21:08:55 +000055 enum {
56 kA_Flag = 1 << 0,
57 kR_Flag = 1 << 1,
58 kG_Flag = 1 << 2,
59 kB_Flag = 1 << 3,
60 };
61
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000062protected:
63 SkTable_ColorFilter(SkFlattenableReadBuffer& buffer);
djsollen@google.com54924242012-03-29 15:18:04 +000064 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000065
66private:
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000067 mutable const SkBitmap* fBitmap; // lazily allocated
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000068
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000069 uint8_t fStorage[256 * 4];
70 unsigned fFlags;
71
72 typedef SkColorFilter INHERITED;
73};
74
75static const uint8_t gIdentityTable[] = {
rmistry@google.comfbfcd562012-08-23 18:09:54 +000076 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
77 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
78 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
79 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
80 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
81 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
82 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
83 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
84 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
85 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
86 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
87 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
88 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
89 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
90 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
91 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
92 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
93 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
94 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
95 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
96 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
97 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
98 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
99 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
100 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
101 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
102 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
103 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
104 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
105 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
106 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000107 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
108};
109
110void SkTable_ColorFilter::filterSpan(const SkPMColor src[], int count,
reed@google.combada6442012-12-17 20:21:44 +0000111 SkPMColor dst[]) const {
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000112 const uint8_t* table = fStorage;
113 const uint8_t* tableA = gIdentityTable;
114 const uint8_t* tableR = gIdentityTable;
115 const uint8_t* tableG = gIdentityTable;
116 const uint8_t* tableB = gIdentityTable;
117 if (fFlags & kA_Flag) {
118 tableA = table; table += 256;
119 }
120 if (fFlags & kR_Flag) {
121 tableR = table; table += 256;
122 }
123 if (fFlags & kG_Flag) {
124 tableG = table; table += 256;
125 }
126 if (fFlags & kB_Flag) {
127 tableB = table;
128 }
129
130 const SkUnPreMultiply::Scale* scaleTable = SkUnPreMultiply::GetScaleTable();
131 for (int i = 0; i < count; ++i) {
132 SkPMColor c = src[i];
133 unsigned a, r, g, b;
134 if (0 == c) {
135 a = r = g = b = 0;
136 } else {
137 a = SkGetPackedA32(c);
138 r = SkGetPackedR32(c);
139 g = SkGetPackedG32(c);
140 b = SkGetPackedB32(c);
141
142 if (a < 255) {
143 SkUnPreMultiply::Scale scale = scaleTable[a];
144 r = SkUnPreMultiply::ApplyScale(scale, r);
145 g = SkUnPreMultiply::ApplyScale(scale, g);
146 b = SkUnPreMultiply::ApplyScale(scale, b);
147 }
148 }
149 dst[i] = SkPremultiplyARGBInline(tableA[a], tableR[r],
150 tableG[g], tableB[b]);
151 }
152}
153
robertphillips@google.com1202c2a2013-05-23 14:00:17 +0000154#ifdef SK_DEVELOPER
155void SkTable_ColorFilter::toString(SkString* str) const {
156 str->append("SkTable_ColorFilter");
157}
158#endif
159
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000160static const uint8_t gCountNibBits[] = {
161 0, 1, 1, 2,
162 1, 2, 2, 3,
163 1, 2, 2, 3,
164 2, 3, 3, 4
165};
166
167#include "SkPackBits.h"
168
djsollen@google.com54924242012-03-29 15:18:04 +0000169void SkTable_ColorFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000170 this->INHERITED::flatten(buffer);
171
172 uint8_t storage[5*256];
173 int count = gCountNibBits[fFlags & 0xF];
174 size_t size = SkPackBits::Pack8(fStorage, count * 256, storage);
175 SkASSERT(size <= sizeof(storage));
176
177// SkDebugf("raw %d packed %d\n", count * 256, size);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000178
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000179 buffer.writeInt(fFlags);
djsollen@google.comc73dd5c2012-08-07 15:54:32 +0000180 buffer.writeByteArray(storage, size);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000181}
182
183SkTable_ColorFilter::SkTable_ColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000184 fBitmap = NULL;
185
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000186 uint8_t storage[5*256];
187
188 fFlags = buffer.readInt();
djsollen@google.comc73dd5c2012-08-07 15:54:32 +0000189
190 size_t size = buffer.getArrayCount();
191 SkASSERT(size <= sizeof(storage));
192 buffer.readByteArray(storage);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000193
humper@google.com0e515772013-01-07 19:54:40 +0000194 SkDEBUGCODE(size_t raw = ) SkPackBits::Unpack8(storage, size, fStorage);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000195
196 SkASSERT(raw <= sizeof(fStorage));
humper@google.com0e515772013-01-07 19:54:40 +0000197 SkDEBUGCODE(size_t count = gCountNibBits[fFlags & 0xF]);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000198 SkASSERT(raw == count * 256);
199}
200
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000201bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000202 if (table) {
203 if (NULL == fBitmap) {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000204 SkBitmap* bmp = SkNEW(SkBitmap);
205 bmp->setConfig(SkBitmap::kA8_Config, 256, 4, 256);
206 bmp->allocPixels();
207 uint8_t* bitmapPixels = bmp->getAddr8(0, 0);
twiz@google.com58071162012-07-18 21:41:50 +0000208 int offset = 0;
209 static const unsigned kFlags[] = { kA_Flag, kR_Flag, kG_Flag, kB_Flag };
210
211 for (int x = 0; x < 4; ++x) {
212 if (!(fFlags & kFlags[x])) {
213 memcpy(bitmapPixels, gIdentityTable, sizeof(gIdentityTable));
214 } else {
215 memcpy(bitmapPixels, fStorage + offset, 256);
216 offset += 256;
217 }
218 bitmapPixels += 256;
219 }
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000220 fBitmap = bmp;
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000221 }
222 *table = *fBitmap;
223 }
224 return true;
225}
226
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000227#if SK_SUPPORT_GPU
228
bsalomon@google.coma469c282012-10-24 18:28:34 +0000229#include "GrEffect.h"
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +0000230#include "GrTBackendEffectFactory.h"
bsalomon@google.comd698f772012-10-25 13:22:00 +0000231#include "gl/GrGLEffect.h"
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000232#include "SkGr.h"
233
234class GLColorTableEffect;
235
bsalomon@google.coma469c282012-10-24 18:28:34 +0000236class ColorTableEffect : public GrEffect {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000237public:
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000238 static GrEffectRef* Create(GrTexture* texture, unsigned flags) {
bsalomon@google.com6340a412013-01-22 19:55:59 +0000239 AutoEffectUnref effect(SkNEW_ARGS(ColorTableEffect, (texture, flags)));
bsalomon@google.coma1ebbe42013-01-16 15:51:47 +0000240 return CreateEffectRef(effect);
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000241 }
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000242
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000243 virtual ~ColorTableEffect();
244
245 static const char* Name() { return "ColorTable"; }
bsalomon@google.com396e61f2012-10-25 19:00:29 +0000246 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000247
bsalomon@google.com371e1052013-01-11 21:08:55 +0000248 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
249
bsalomon@google.com422e81a2012-10-25 14:11:03 +0000250 typedef GLColorTableEffect GLEffect;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000251
252private:
bsalomon@google.com8a252f72013-01-22 20:35:13 +0000253 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000254
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000255 explicit ColorTableEffect(GrTexture* texture, unsigned flags);
256
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000257 GR_DECLARE_EFFECT_TEST;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000258
259 GrTextureAccess fTextureAccess;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000260 unsigned fFlags; // currently not used in shader code, just to assist
261 // getConstantColorComponents().
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000262
bsalomon@google.coma469c282012-10-24 18:28:34 +0000263 typedef GrEffect INHERITED;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000264};
265
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000266class GLColorTableEffect : public GrGLEffect {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000267public:
bsalomon@google.comc7818882013-03-20 19:19:53 +0000268 GLColorTableEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000269
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000270 virtual void emitCode(GrGLShaderBuilder*,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000271 const GrDrawEffect&,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000272 EffectKey,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000273 const char* outputColor,
274 const char* inputColor,
275 const TextureSamplerArray&) SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000276
bsalomon@google.comc7818882013-03-20 19:19:53 +0000277 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000278
bsalomon@google.comc7818882013-03-20 19:19:53 +0000279 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000280
281private:
282
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000283 typedef GrGLEffect INHERITED;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000284};
285
bsalomon@google.comc7818882013-03-20 19:19:53 +0000286GLColorTableEffect::GLColorTableEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000287 : INHERITED(factory) {
288 }
289
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000290void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000291 const GrDrawEffect&,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000292 EffectKey,
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000293 const char* outputColor,
294 const char* inputColor,
295 const TextureSamplerArray& samplers) {
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000296
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000297 static const float kColorScaleFactor = 255.0f / 256.0f;
298 static const float kColorOffsetFactor = 1.0f / 512.0f;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000299 if (NULL == inputColor) {
300 // the input color is solid white (all ones).
301 static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000302 builder->fsCodeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
303 kMaxValue, kMaxValue, kMaxValue, kMaxValue);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000304
305 } else {
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000306 builder->fsCodeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", inputColor);
307 builder->fsCodeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n", inputColor);
308 builder->fsCodeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
309 kColorScaleFactor,
310 kColorOffsetFactor, kColorOffsetFactor,
311 kColorOffsetFactor, kColorOffsetFactor);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000312 }
313
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000314 builder->fsCodeAppendf("\t\t%s.a = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000315 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.a, 0.125)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000316 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000317
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000318 builder->fsCodeAppendf("\t\t%s.r = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000319 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.r, 0.375)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000320 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000321
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000322 builder->fsCodeAppendf("\t\t%s.g = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000323 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.g, 0.625)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000324 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000325
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000326 builder->fsCodeAppendf("\t\t%s.b = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000327 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.b, 0.875)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000328 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000329
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000330 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000331}
332
bsalomon@google.comc7818882013-03-20 19:19:53 +0000333GrGLEffect::EffectKey GLColorTableEffect::GenKey(const GrDrawEffect&, const GrGLCaps&) {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000334 return 0;
335}
336
337///////////////////////////////////////////////////////////////////////////////
338
bsalomon@google.com371e1052013-01-11 21:08:55 +0000339ColorTableEffect::ColorTableEffect(GrTexture* texture, unsigned flags)
340 : fTextureAccess(texture, "a")
341 , fFlags(flags) {
bsalomon@google.com50db75c2013-01-11 13:54:30 +0000342 this->addTextureAccess(&fTextureAccess);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000343}
344
345ColorTableEffect::~ColorTableEffect() {
346}
347
bsalomon@google.com396e61f2012-10-25 19:00:29 +0000348const GrBackendEffectFactory& ColorTableEffect::getFactory() const {
349 return GrTBackendEffectFactory<ColorTableEffect>::getInstance();
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000350}
351
bsalomon@google.com8a252f72013-01-22 20:35:13 +0000352bool ColorTableEffect::onIsEqual(const GrEffect& sBase) const {
353 return this->texture(0) == sBase.texture(0);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000354}
355
bsalomon@google.com371e1052013-01-11 21:08:55 +0000356void ColorTableEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
357 // If we kept the table in the effect then we could actually run known inputs through the
358 // table.
359 if (fFlags & SkTable_ColorFilter::kR_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000360 *validFlags &= ~kR_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000361 }
362 if (fFlags & SkTable_ColorFilter::kG_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000363 *validFlags &= ~kG_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000364 }
365 if (fFlags & SkTable_ColorFilter::kB_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000366 *validFlags &= ~kB_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000367 }
368 if (fFlags & SkTable_ColorFilter::kA_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000369 *validFlags &= ~kA_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000370 }
371}
372
373
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000374///////////////////////////////////////////////////////////////////////////////
375
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000376GR_DEFINE_EFFECT_TEST(ColorTableEffect);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000377
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000378GrEffectRef* ColorTableEffect::TestCreate(SkRandom* random,
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000379 GrContext* context,
bsalomon@google.comc26d94f2013-03-25 18:19:00 +0000380 const GrDrawTargetCaps&,
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000381 GrTexture* textures[]) {
bsalomon@google.com371e1052013-01-11 21:08:55 +0000382 static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilter::kG_Flag |
383 SkTable_ColorFilter::kB_Flag | SkTable_ColorFilter::kA_Flag;
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000384 return ColorTableEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000385}
386
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000387GrEffectRef* SkTable_ColorFilter::asNewEffect(GrContext* context) const {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000388 SkBitmap bitmap;
commit-bot@chromium.orgc7d624e2013-05-28 13:13:56 +0000389 GrEffectRef* effect = NULL;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000390 this->asComponentTable(&bitmap);
bsalomon@google.com8ea78d82012-10-24 20:11:30 +0000391 // passing NULL because this effect does no tiling or filtering.
bsalomon@google.com95ed55a2013-01-24 14:46:47 +0000392 GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, bitmap, NULL);
commit-bot@chromium.orgc7d624e2013-05-28 13:13:56 +0000393 if (NULL != texture) {
394 effect = ColorTableEffect::Create(texture, fFlags);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000395
commit-bot@chromium.orgc7d624e2013-05-28 13:13:56 +0000396 // Unlock immediately, this is not great, but we don't have a way of
397 // knowing when else to unlock it currently. TODO: Remove this when
398 // unref becomes the unlock replacement for all types of textures.
399 GrUnlockAndUnrefCachedBitmapTexture(texture);
400 }
bsalomon@google.com021fc732012-10-25 12:47:42 +0000401 return effect;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000402}
403
404#endif // SK_SUPPORT_GPU
405
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000406///////////////////////////////////////////////////////////////////////////////
407
408#ifdef SK_CPU_BENDIAN
409#else
410 #define SK_A32_INDEX (3 - (SK_A32_SHIFT >> 3))
411 #define SK_R32_INDEX (3 - (SK_R32_SHIFT >> 3))
412 #define SK_G32_INDEX (3 - (SK_G32_SHIFT >> 3))
413 #define SK_B32_INDEX (3 - (SK_B32_SHIFT >> 3))
414#endif
415
416///////////////////////////////////////////////////////////////////////////////
417
418SkColorFilter* SkTableColorFilter::Create(const uint8_t table[256]) {
419 return SkNEW_ARGS(SkTable_ColorFilter, (table, table, table, table));
420}
421
422SkColorFilter* SkTableColorFilter::CreateARGB(const uint8_t tableA[256],
423 const uint8_t tableR[256],
424 const uint8_t tableG[256],
425 const uint8_t tableB[256]) {
426 return SkNEW_ARGS(SkTable_ColorFilter, (tableA, tableR, tableG, tableB));
427}
djsollen@google.coma2ca41e2012-03-23 19:00:34 +0000428
429SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkTableColorFilter)
430 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTable_ColorFilter)
431SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END