blob: e0c497806d01198d99dcece3a31d75010258ea91 [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"
7
8class SkTable_ColorFilter : public SkColorFilter {
9public:
10 SkTable_ColorFilter(const uint8_t tableA[], const uint8_t tableR[],
11 const uint8_t tableG[], const uint8_t tableB[]) {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000012 fBitmap = NULL;
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000013 fFlags = 0;
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000014
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000015 uint8_t* dst = fStorage;
16 if (tableA) {
17 memcpy(dst, tableA, 256);
18 dst += 256;
19 fFlags |= kA_Flag;
20 }
21 if (tableR) {
22 memcpy(dst, tableR, 256);
23 dst += 256;
24 fFlags |= kR_Flag;
25 }
26 if (tableG) {
27 memcpy(dst, tableG, 256);
28 dst += 256;
29 fFlags |= kG_Flag;
30 }
31 if (tableB) {
32 memcpy(dst, tableB, 256);
33 fFlags |= kB_Flag;
34 }
35 }
36
tomhudson@google.com1bb4be22012-07-24 17:24:21 +000037 virtual ~SkTable_ColorFilter() {
38 SkDELETE(fBitmap);
39 }
40
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000041 virtual bool asComponentTable(SkBitmap* table) const SK_OVERRIDE;
42
43#if SK_SUPPORT_GPU
bsalomon@google.com0ac6af42013-01-16 15:16:18 +000044 virtual GrEffectRef* asNewEffect(GrContext* context) const SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000045#endif
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000046
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000047 virtual void filterSpan(const SkPMColor src[], int count,
reed@google.combada6442012-12-17 20:21:44 +000048 SkPMColor dst[]) const SK_OVERRIDE;
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000049
djsollen@google.comba28d032012-03-26 17:57:35 +000050 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTable_ColorFilter)
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000051
bsalomon@google.com371e1052013-01-11 21:08:55 +000052 enum {
53 kA_Flag = 1 << 0,
54 kR_Flag = 1 << 1,
55 kG_Flag = 1 << 2,
56 kB_Flag = 1 << 3,
57 };
58
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000059protected:
60 SkTable_ColorFilter(SkFlattenableReadBuffer& buffer);
djsollen@google.com54924242012-03-29 15:18:04 +000061 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000062
63private:
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000064 mutable const SkBitmap* fBitmap; // lazily allocated
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000065
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000066 uint8_t fStorage[256 * 4];
67 unsigned fFlags;
68
69 typedef SkColorFilter INHERITED;
70};
71
72static const uint8_t gIdentityTable[] = {
rmistry@google.comfbfcd562012-08-23 18:09:54 +000073 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
74 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
75 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
76 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
77 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
78 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
79 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
80 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
81 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
82 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
83 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
84 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
85 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
86 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
87 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
88 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
89 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
90 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
91 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
92 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
93 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
94 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
95 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
96 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
97 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
98 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
99 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
100 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
101 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
102 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
103 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000104 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
105};
106
107void SkTable_ColorFilter::filterSpan(const SkPMColor src[], int count,
reed@google.combada6442012-12-17 20:21:44 +0000108 SkPMColor dst[]) const {
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000109 const uint8_t* table = fStorage;
110 const uint8_t* tableA = gIdentityTable;
111 const uint8_t* tableR = gIdentityTable;
112 const uint8_t* tableG = gIdentityTable;
113 const uint8_t* tableB = gIdentityTable;
114 if (fFlags & kA_Flag) {
115 tableA = table; table += 256;
116 }
117 if (fFlags & kR_Flag) {
118 tableR = table; table += 256;
119 }
120 if (fFlags & kG_Flag) {
121 tableG = table; table += 256;
122 }
123 if (fFlags & kB_Flag) {
124 tableB = table;
125 }
126
127 const SkUnPreMultiply::Scale* scaleTable = SkUnPreMultiply::GetScaleTable();
128 for (int i = 0; i < count; ++i) {
129 SkPMColor c = src[i];
130 unsigned a, r, g, b;
131 if (0 == c) {
132 a = r = g = b = 0;
133 } else {
134 a = SkGetPackedA32(c);
135 r = SkGetPackedR32(c);
136 g = SkGetPackedG32(c);
137 b = SkGetPackedB32(c);
138
139 if (a < 255) {
140 SkUnPreMultiply::Scale scale = scaleTable[a];
141 r = SkUnPreMultiply::ApplyScale(scale, r);
142 g = SkUnPreMultiply::ApplyScale(scale, g);
143 b = SkUnPreMultiply::ApplyScale(scale, b);
144 }
145 }
146 dst[i] = SkPremultiplyARGBInline(tableA[a], tableR[r],
147 tableG[g], tableB[b]);
148 }
149}
150
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000151static const uint8_t gCountNibBits[] = {
152 0, 1, 1, 2,
153 1, 2, 2, 3,
154 1, 2, 2, 3,
155 2, 3, 3, 4
156};
157
158#include "SkPackBits.h"
159
djsollen@google.com54924242012-03-29 15:18:04 +0000160void SkTable_ColorFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000161 this->INHERITED::flatten(buffer);
162
163 uint8_t storage[5*256];
164 int count = gCountNibBits[fFlags & 0xF];
165 size_t size = SkPackBits::Pack8(fStorage, count * 256, storage);
166 SkASSERT(size <= sizeof(storage));
167
168// SkDebugf("raw %d packed %d\n", count * 256, size);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000169
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000170 buffer.writeInt(fFlags);
djsollen@google.comc73dd5c2012-08-07 15:54:32 +0000171 buffer.writeByteArray(storage, size);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000172}
173
174SkTable_ColorFilter::SkTable_ColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000175 fBitmap = NULL;
176
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000177 uint8_t storage[5*256];
178
179 fFlags = buffer.readInt();
djsollen@google.comc73dd5c2012-08-07 15:54:32 +0000180
181 size_t size = buffer.getArrayCount();
182 SkASSERT(size <= sizeof(storage));
183 buffer.readByteArray(storage);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000184
humper@google.com0e515772013-01-07 19:54:40 +0000185 SkDEBUGCODE(size_t raw = ) SkPackBits::Unpack8(storage, size, fStorage);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000186
187 SkASSERT(raw <= sizeof(fStorage));
humper@google.com0e515772013-01-07 19:54:40 +0000188 SkDEBUGCODE(size_t count = gCountNibBits[fFlags & 0xF]);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000189 SkASSERT(raw == count * 256);
190}
191
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000192bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000193 if (table) {
194 if (NULL == fBitmap) {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000195 SkBitmap* bmp = SkNEW(SkBitmap);
196 bmp->setConfig(SkBitmap::kA8_Config, 256, 4, 256);
197 bmp->allocPixels();
198 uint8_t* bitmapPixels = bmp->getAddr8(0, 0);
twiz@google.com58071162012-07-18 21:41:50 +0000199 int offset = 0;
200 static const unsigned kFlags[] = { kA_Flag, kR_Flag, kG_Flag, kB_Flag };
201
202 for (int x = 0; x < 4; ++x) {
203 if (!(fFlags & kFlags[x])) {
204 memcpy(bitmapPixels, gIdentityTable, sizeof(gIdentityTable));
205 } else {
206 memcpy(bitmapPixels, fStorage + offset, 256);
207 offset += 256;
208 }
209 bitmapPixels += 256;
210 }
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000211 fBitmap = bmp;
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000212 }
213 *table = *fBitmap;
214 }
215 return true;
216}
217
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000218#if SK_SUPPORT_GPU
219
bsalomon@google.coma469c282012-10-24 18:28:34 +0000220#include "GrEffect.h"
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +0000221#include "GrTBackendEffectFactory.h"
bsalomon@google.comd698f772012-10-25 13:22:00 +0000222#include "gl/GrGLEffect.h"
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000223#include "SkGr.h"
224
225class GLColorTableEffect;
226
bsalomon@google.coma469c282012-10-24 18:28:34 +0000227class ColorTableEffect : public GrEffect {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000228public:
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000229 static GrEffectRef* Create(GrTexture* texture, unsigned flags) {
bsalomon@google.com6340a412013-01-22 19:55:59 +0000230 AutoEffectUnref effect(SkNEW_ARGS(ColorTableEffect, (texture, flags)));
bsalomon@google.coma1ebbe42013-01-16 15:51:47 +0000231 return CreateEffectRef(effect);
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000232 }
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000233
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000234 virtual ~ColorTableEffect();
235
236 static const char* Name() { return "ColorTable"; }
bsalomon@google.com396e61f2012-10-25 19:00:29 +0000237 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000238
bsalomon@google.com371e1052013-01-11 21:08:55 +0000239 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
240
bsalomon@google.com422e81a2012-10-25 14:11:03 +0000241 typedef GLColorTableEffect GLEffect;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000242
243private:
bsalomon@google.com8a252f72013-01-22 20:35:13 +0000244 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000245
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000246 explicit ColorTableEffect(GrTexture* texture, unsigned flags);
247
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000248 GR_DECLARE_EFFECT_TEST;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000249
250 GrTextureAccess fTextureAccess;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000251 unsigned fFlags; // currently not used in shader code, just to assist
252 // getConstantColorComponents().
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000253
bsalomon@google.coma469c282012-10-24 18:28:34 +0000254 typedef GrEffect INHERITED;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000255};
256
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000257class GLColorTableEffect : public GrGLEffect {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000258public:
bsalomon@google.comc7818882013-03-20 19:19:53 +0000259 GLColorTableEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000260
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000261 virtual void emitCode(GrGLShaderBuilder*,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000262 const GrDrawEffect&,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000263 EffectKey,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000264 const char* outputColor,
265 const char* inputColor,
266 const TextureSamplerArray&) SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000267
bsalomon@google.comc7818882013-03-20 19:19:53 +0000268 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000269
bsalomon@google.comc7818882013-03-20 19:19:53 +0000270 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000271
272private:
273
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000274 typedef GrGLEffect INHERITED;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000275};
276
bsalomon@google.comc7818882013-03-20 19:19:53 +0000277GLColorTableEffect::GLColorTableEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000278 : INHERITED(factory) {
279 }
280
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000281void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000282 const GrDrawEffect&,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000283 EffectKey,
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000284 const char* outputColor,
285 const char* inputColor,
286 const TextureSamplerArray& samplers) {
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000287
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000288 static const float kColorScaleFactor = 255.0f / 256.0f;
289 static const float kColorOffsetFactor = 1.0f / 512.0f;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000290 if (NULL == inputColor) {
291 // the input color is solid white (all ones).
292 static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000293 builder->fsCodeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
294 kMaxValue, kMaxValue, kMaxValue, kMaxValue);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000295
296 } else {
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000297 builder->fsCodeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", inputColor);
298 builder->fsCodeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n", inputColor);
299 builder->fsCodeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
300 kColorScaleFactor,
301 kColorOffsetFactor, kColorOffsetFactor,
302 kColorOffsetFactor, kColorOffsetFactor);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000303 }
304
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000305 builder->fsCodeAppendf("\t\t%s.a = ", outputColor);
306 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType, samplers[0], "vec2(coord.a, 0.125)");
307 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000308
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000309 builder->fsCodeAppendf("\t\t%s.r = ", outputColor);
310 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType, samplers[0], "vec2(coord.r, 0.375)");
311 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000312
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000313 builder->fsCodeAppendf("\t\t%s.g = ", outputColor);
314 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType, samplers[0], "vec2(coord.g, 0.625)");
315 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000316
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000317 builder->fsCodeAppendf("\t\t%s.b = ", outputColor);
318 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType, samplers[0], "vec2(coord.b, 0.875)");
319 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000320
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000321 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000322}
323
bsalomon@google.comc7818882013-03-20 19:19:53 +0000324GrGLEffect::EffectKey GLColorTableEffect::GenKey(const GrDrawEffect&, const GrGLCaps&) {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000325 return 0;
326}
327
328///////////////////////////////////////////////////////////////////////////////
329
bsalomon@google.com371e1052013-01-11 21:08:55 +0000330ColorTableEffect::ColorTableEffect(GrTexture* texture, unsigned flags)
331 : fTextureAccess(texture, "a")
332 , fFlags(flags) {
bsalomon@google.com50db75c2013-01-11 13:54:30 +0000333 this->addTextureAccess(&fTextureAccess);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000334}
335
336ColorTableEffect::~ColorTableEffect() {
337}
338
bsalomon@google.com396e61f2012-10-25 19:00:29 +0000339const GrBackendEffectFactory& ColorTableEffect::getFactory() const {
340 return GrTBackendEffectFactory<ColorTableEffect>::getInstance();
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000341}
342
bsalomon@google.com8a252f72013-01-22 20:35:13 +0000343bool ColorTableEffect::onIsEqual(const GrEffect& sBase) const {
344 return this->texture(0) == sBase.texture(0);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000345}
346
bsalomon@google.com371e1052013-01-11 21:08:55 +0000347void ColorTableEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
348 // If we kept the table in the effect then we could actually run known inputs through the
349 // table.
350 if (fFlags & SkTable_ColorFilter::kR_Flag) {
bsalomon@google.com61be7942013-01-14 14:36:40 +0000351 *validFlags &= ~kR_ValidComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000352 }
353 if (fFlags & SkTable_ColorFilter::kG_Flag) {
354 *validFlags &= ~kG_ValidComponentFlag;
355 }
356 if (fFlags & SkTable_ColorFilter::kB_Flag) {
357 *validFlags &= ~kB_ValidComponentFlag;
358 }
359 if (fFlags & SkTable_ColorFilter::kA_Flag) {
360 *validFlags &= ~kA_ValidComponentFlag;
361 }
362}
363
364
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000365///////////////////////////////////////////////////////////////////////////////
366
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000367GR_DEFINE_EFFECT_TEST(ColorTableEffect);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000368
bsalomon@google.com73a96942013-02-13 16:31:19 +0000369GrEffectRef* ColorTableEffect::TestCreate(SkMWCRandom* random,
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000370 GrContext* context,
371 GrTexture* textures[]) {
bsalomon@google.com371e1052013-01-11 21:08:55 +0000372 static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilter::kG_Flag |
373 SkTable_ColorFilter::kB_Flag | SkTable_ColorFilter::kA_Flag;
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000374 return ColorTableEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000375}
376
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000377GrEffectRef* SkTable_ColorFilter::asNewEffect(GrContext* context) const {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000378 SkBitmap bitmap;
379 this->asComponentTable(&bitmap);
bsalomon@google.com8ea78d82012-10-24 20:11:30 +0000380 // passing NULL because this effect does no tiling or filtering.
bsalomon@google.com95ed55a2013-01-24 14:46:47 +0000381 GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, bitmap, NULL);
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000382 GrEffectRef* effect = ColorTableEffect::Create(texture, fFlags);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000383
384 // Unlock immediately, this is not great, but we don't have a way of
385 // knowing when else to unlock it currently. TODO: Remove this when
386 // unref becomes the unlock replacement for all types of textures.
bsalomon@google.com95ed55a2013-01-24 14:46:47 +0000387 GrUnlockAndUnrefCachedBitmapTexture(texture);
bsalomon@google.com021fc732012-10-25 12:47:42 +0000388 return effect;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000389}
390
391#endif // SK_SUPPORT_GPU
392
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000393///////////////////////////////////////////////////////////////////////////////
394
395#ifdef SK_CPU_BENDIAN
396#else
397 #define SK_A32_INDEX (3 - (SK_A32_SHIFT >> 3))
398 #define SK_R32_INDEX (3 - (SK_R32_SHIFT >> 3))
399 #define SK_G32_INDEX (3 - (SK_G32_SHIFT >> 3))
400 #define SK_B32_INDEX (3 - (SK_B32_SHIFT >> 3))
401#endif
402
403///////////////////////////////////////////////////////////////////////////////
404
405SkColorFilter* SkTableColorFilter::Create(const uint8_t table[256]) {
406 return SkNEW_ARGS(SkTable_ColorFilter, (table, table, table, table));
407}
408
409SkColorFilter* SkTableColorFilter::CreateARGB(const uint8_t tableA[256],
410 const uint8_t tableR[256],
411 const uint8_t tableG[256],
412 const uint8_t tableB[256]) {
413 return SkNEW_ARGS(SkTable_ColorFilter, (tableA, tableR, tableG, tableB));
414}
djsollen@google.coma2ca41e2012-03-23 19:00:34 +0000415
416SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkTableColorFilter)
417 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTable_ColorFilter)
418SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END