blob: 083b54c4886691a9c3f7663e0e702533c2de1839 [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,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000275 const TransformedCoordsArray&,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000276 const TextureSamplerArray&) SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000277
bsalomon@google.comc7818882013-03-20 19:19:53 +0000278 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000279
bsalomon@google.comc7818882013-03-20 19:19:53 +0000280 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000281
282private:
283
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000284 typedef GrGLEffect INHERITED;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000285};
286
bsalomon@google.comc7818882013-03-20 19:19:53 +0000287GLColorTableEffect::GLColorTableEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000288 : INHERITED(factory) {
289 }
290
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000291void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000292 const GrDrawEffect&,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000293 EffectKey,
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000294 const char* outputColor,
295 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000296 const TransformedCoordsArray&,
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000297 const TextureSamplerArray& samplers) {
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000298
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000299 static const float kColorScaleFactor = 255.0f / 256.0f;
300 static const float kColorOffsetFactor = 1.0f / 512.0f;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000301 if (NULL == inputColor) {
302 // the input color is solid white (all ones).
303 static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000304 builder->fsCodeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
305 kMaxValue, kMaxValue, kMaxValue, kMaxValue);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000306
307 } else {
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000308 builder->fsCodeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", inputColor);
309 builder->fsCodeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n", inputColor);
310 builder->fsCodeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
311 kColorScaleFactor,
312 kColorOffsetFactor, kColorOffsetFactor,
313 kColorOffsetFactor, kColorOffsetFactor);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000314 }
315
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000316 builder->fsCodeAppendf("\t\t%s.a = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000317 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.a, 0.125)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000318 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000319
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000320 builder->fsCodeAppendf("\t\t%s.r = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000321 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.r, 0.375)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000322 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000323
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000324 builder->fsCodeAppendf("\t\t%s.g = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000325 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.g, 0.625)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000326 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000327
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000328 builder->fsCodeAppendf("\t\t%s.b = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000329 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.b, 0.875)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000330 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000331
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000332 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000333}
334
bsalomon@google.comc7818882013-03-20 19:19:53 +0000335GrGLEffect::EffectKey GLColorTableEffect::GenKey(const GrDrawEffect&, const GrGLCaps&) {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000336 return 0;
337}
338
339///////////////////////////////////////////////////////////////////////////////
340
bsalomon@google.com371e1052013-01-11 21:08:55 +0000341ColorTableEffect::ColorTableEffect(GrTexture* texture, unsigned flags)
342 : fTextureAccess(texture, "a")
343 , fFlags(flags) {
bsalomon@google.com50db75c2013-01-11 13:54:30 +0000344 this->addTextureAccess(&fTextureAccess);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000345}
346
347ColorTableEffect::~ColorTableEffect() {
348}
349
bsalomon@google.com396e61f2012-10-25 19:00:29 +0000350const GrBackendEffectFactory& ColorTableEffect::getFactory() const {
351 return GrTBackendEffectFactory<ColorTableEffect>::getInstance();
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000352}
353
bsalomon@google.com8a252f72013-01-22 20:35:13 +0000354bool ColorTableEffect::onIsEqual(const GrEffect& sBase) const {
355 return this->texture(0) == sBase.texture(0);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000356}
357
bsalomon@google.com371e1052013-01-11 21:08:55 +0000358void ColorTableEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
359 // If we kept the table in the effect then we could actually run known inputs through the
360 // table.
361 if (fFlags & SkTable_ColorFilter::kR_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000362 *validFlags &= ~kR_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000363 }
364 if (fFlags & SkTable_ColorFilter::kG_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000365 *validFlags &= ~kG_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000366 }
367 if (fFlags & SkTable_ColorFilter::kB_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000368 *validFlags &= ~kB_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000369 }
370 if (fFlags & SkTable_ColorFilter::kA_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000371 *validFlags &= ~kA_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000372 }
373}
374
375
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000376///////////////////////////////////////////////////////////////////////////////
377
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000378GR_DEFINE_EFFECT_TEST(ColorTableEffect);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000379
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000380GrEffectRef* ColorTableEffect::TestCreate(SkRandom* random,
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000381 GrContext* context,
bsalomon@google.comc26d94f2013-03-25 18:19:00 +0000382 const GrDrawTargetCaps&,
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000383 GrTexture* textures[]) {
bsalomon@google.com371e1052013-01-11 21:08:55 +0000384 static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilter::kG_Flag |
385 SkTable_ColorFilter::kB_Flag | SkTable_ColorFilter::kA_Flag;
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000386 return ColorTableEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000387}
388
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000389GrEffectRef* SkTable_ColorFilter::asNewEffect(GrContext* context) const {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000390 SkBitmap bitmap;
commit-bot@chromium.orgc7d624e2013-05-28 13:13:56 +0000391 GrEffectRef* effect = NULL;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000392 this->asComponentTable(&bitmap);
bsalomon@google.com8ea78d82012-10-24 20:11:30 +0000393 // passing NULL because this effect does no tiling or filtering.
bsalomon@google.com95ed55a2013-01-24 14:46:47 +0000394 GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, bitmap, NULL);
commit-bot@chromium.orgc7d624e2013-05-28 13:13:56 +0000395 if (NULL != texture) {
396 effect = ColorTableEffect::Create(texture, fFlags);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000397
commit-bot@chromium.orgc7d624e2013-05-28 13:13:56 +0000398 // Unlock immediately, this is not great, but we don't have a way of
399 // knowing when else to unlock it currently. TODO: Remove this when
400 // unref becomes the unlock replacement for all types of textures.
401 GrUnlockAndUnrefCachedBitmapTexture(texture);
402 }
bsalomon@google.com021fc732012-10-25 12:47:42 +0000403 return effect;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000404}
405
406#endif // SK_SUPPORT_GPU
407
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000408///////////////////////////////////////////////////////////////////////////////
409
410#ifdef SK_CPU_BENDIAN
411#else
412 #define SK_A32_INDEX (3 - (SK_A32_SHIFT >> 3))
413 #define SK_R32_INDEX (3 - (SK_R32_SHIFT >> 3))
414 #define SK_G32_INDEX (3 - (SK_G32_SHIFT >> 3))
415 #define SK_B32_INDEX (3 - (SK_B32_SHIFT >> 3))
416#endif
417
418///////////////////////////////////////////////////////////////////////////////
419
420SkColorFilter* SkTableColorFilter::Create(const uint8_t table[256]) {
421 return SkNEW_ARGS(SkTable_ColorFilter, (table, table, table, table));
422}
423
424SkColorFilter* SkTableColorFilter::CreateARGB(const uint8_t tableA[256],
425 const uint8_t tableR[256],
426 const uint8_t tableG[256],
427 const uint8_t tableB[256]) {
428 return SkNEW_ARGS(SkTable_ColorFilter, (tableA, tableR, tableG, tableB));
429}
djsollen@google.coma2ca41e2012-03-23 19:00:34 +0000430
431SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkTableColorFilter)
432 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTable_ColorFilter)
433SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END