blob: e9ce20f6c1d3837025969af3df711d8c5bf334df [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:
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000064 SkTable_ColorFilter(SkReadBuffer& buffer);
65 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000066
67private:
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000068 mutable const SkBitmap* fBitmap; // lazily allocated
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +000069
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +000070 uint8_t fStorage[256 * 4];
71 unsigned fFlags;
72
73 typedef SkColorFilter INHERITED;
74};
75
76static const uint8_t gIdentityTable[] = {
rmistry@google.comfbfcd562012-08-23 18:09:54 +000077 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
78 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
79 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
80 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
81 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
82 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
83 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
84 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
85 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
86 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
87 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
88 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
89 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
90 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
91 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
92 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
93 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
94 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
95 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
96 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
97 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
98 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
99 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
100 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
101 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
102 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
103 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
104 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
105 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
106 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
107 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000108 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
109};
110
111void SkTable_ColorFilter::filterSpan(const SkPMColor src[], int count,
reed@google.combada6442012-12-17 20:21:44 +0000112 SkPMColor dst[]) const {
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000113 const uint8_t* table = fStorage;
114 const uint8_t* tableA = gIdentityTable;
115 const uint8_t* tableR = gIdentityTable;
116 const uint8_t* tableG = gIdentityTable;
117 const uint8_t* tableB = gIdentityTable;
118 if (fFlags & kA_Flag) {
119 tableA = table; table += 256;
120 }
121 if (fFlags & kR_Flag) {
122 tableR = table; table += 256;
123 }
124 if (fFlags & kG_Flag) {
125 tableG = table; table += 256;
126 }
127 if (fFlags & kB_Flag) {
128 tableB = table;
129 }
130
131 const SkUnPreMultiply::Scale* scaleTable = SkUnPreMultiply::GetScaleTable();
132 for (int i = 0; i < count; ++i) {
133 SkPMColor c = src[i];
134 unsigned a, r, g, b;
135 if (0 == c) {
136 a = r = g = b = 0;
137 } else {
138 a = SkGetPackedA32(c);
139 r = SkGetPackedR32(c);
140 g = SkGetPackedG32(c);
141 b = SkGetPackedB32(c);
142
143 if (a < 255) {
144 SkUnPreMultiply::Scale scale = scaleTable[a];
145 r = SkUnPreMultiply::ApplyScale(scale, r);
146 g = SkUnPreMultiply::ApplyScale(scale, g);
147 b = SkUnPreMultiply::ApplyScale(scale, b);
148 }
149 }
150 dst[i] = SkPremultiplyARGBInline(tableA[a], tableR[r],
151 tableG[g], tableB[b]);
152 }
153}
154
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +0000155#ifndef SK_IGNORE_TO_STRING
robertphillips@google.com1202c2a2013-05-23 14:00:17 +0000156void SkTable_ColorFilter::toString(SkString* str) const {
157 str->append("SkTable_ColorFilter");
158}
159#endif
160
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000161static const uint8_t gCountNibBits[] = {
162 0, 1, 1, 2,
163 1, 2, 2, 3,
164 1, 2, 2, 3,
165 2, 3, 3, 4
166};
167
168#include "SkPackBits.h"
169
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000170void SkTable_ColorFilter::flatten(SkWriteBuffer& buffer) const {
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000171 this->INHERITED::flatten(buffer);
172
173 uint8_t storage[5*256];
174 int count = gCountNibBits[fFlags & 0xF];
175 size_t size = SkPackBits::Pack8(fStorage, count * 256, storage);
176 SkASSERT(size <= sizeof(storage));
177
178// SkDebugf("raw %d packed %d\n", count * 256, size);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000179
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000180 buffer.writeInt(fFlags);
djsollen@google.comc73dd5c2012-08-07 15:54:32 +0000181 buffer.writeByteArray(storage, size);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000182}
183
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000184SkTable_ColorFilter::SkTable_ColorFilter(SkReadBuffer& buffer) : INHERITED(buffer) {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000185 fBitmap = NULL;
186
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000187 uint8_t storage[5*256];
188
189 fFlags = buffer.readInt();
djsollen@google.comc73dd5c2012-08-07 15:54:32 +0000190
191 size_t size = buffer.getArrayCount();
192 SkASSERT(size <= sizeof(storage));
commit-bot@chromium.orgef74fa12013-12-17 20:49:46 +0000193 buffer.validate(size <= sizeof(storage));
commit-bot@chromium.org02512882013-10-31 18:37:50 +0000194 buffer.readByteArray(storage, size);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000195
humper@google.com0e515772013-01-07 19:54:40 +0000196 SkDEBUGCODE(size_t raw = ) SkPackBits::Unpack8(storage, size, fStorage);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000197
198 SkASSERT(raw <= sizeof(fStorage));
humper@google.com0e515772013-01-07 19:54:40 +0000199 SkDEBUGCODE(size_t count = gCountNibBits[fFlags & 0xF]);
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000200 SkASSERT(raw == count * 256);
201}
202
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000203bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000204 if (table) {
205 if (NULL == fBitmap) {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000206 SkBitmap* bmp = SkNEW(SkBitmap);
reed@google.com9ebcac52014-01-24 18:53:42 +0000207 bmp->allocPixels(SkImageInfo::MakeA8(256, 4));
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000208 uint8_t* bitmapPixels = bmp->getAddr8(0, 0);
twiz@google.com58071162012-07-18 21:41:50 +0000209 int offset = 0;
210 static const unsigned kFlags[] = { kA_Flag, kR_Flag, kG_Flag, kB_Flag };
211
212 for (int x = 0; x < 4; ++x) {
213 if (!(fFlags & kFlags[x])) {
214 memcpy(bitmapPixels, gIdentityTable, sizeof(gIdentityTable));
215 } else {
216 memcpy(bitmapPixels, fStorage + offset, 256);
217 offset += 256;
218 }
219 bitmapPixels += 256;
220 }
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000221 fBitmap = bmp;
mike@reedtribe.orgf23f5f72012-01-07 03:48:45 +0000222 }
223 *table = *fBitmap;
224 }
225 return true;
226}
227
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000228#if SK_SUPPORT_GPU
229
bsalomon@google.coma469c282012-10-24 18:28:34 +0000230#include "GrEffect.h"
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +0000231#include "GrTBackendEffectFactory.h"
bsalomon@google.comd698f772012-10-25 13:22:00 +0000232#include "gl/GrGLEffect.h"
bsalomon848faf02014-07-11 10:01:02 -0700233#include "gl/GrGLShaderBuilder.h"
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000234#include "SkGr.h"
235
236class GLColorTableEffect;
237
bsalomon@google.coma469c282012-10-24 18:28:34 +0000238class ColorTableEffect : public GrEffect {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000239public:
bsalomon83d081a2014-07-08 09:56:10 -0700240 static GrEffect* Create(GrTexture* texture, unsigned flags) {
bsalomon55fad7a2014-07-08 07:34:20 -0700241 return SkNEW_ARGS(ColorTableEffect, (texture, flags));
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000242 }
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000243
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000244 virtual ~ColorTableEffect();
245
246 static const char* Name() { return "ColorTable"; }
bsalomon@google.com396e61f2012-10-25 19:00:29 +0000247 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000248
bsalomon@google.com371e1052013-01-11 21:08:55 +0000249 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
250
bsalomon@google.com422e81a2012-10-25 14:11:03 +0000251 typedef GLColorTableEffect GLEffect;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000252
253private:
bsalomon@google.com8a252f72013-01-22 20:35:13 +0000254 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
bsalomon@google.com68b58c92013-01-17 16:50:08 +0000255
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000256 explicit ColorTableEffect(GrTexture* texture, unsigned flags);
257
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000258 GR_DECLARE_EFFECT_TEST;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000259
260 GrTextureAccess fTextureAccess;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000261 unsigned fFlags; // currently not used in shader code, just to assist
262 // getConstantColorComponents().
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000263
bsalomon@google.coma469c282012-10-24 18:28:34 +0000264 typedef GrEffect INHERITED;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000265};
266
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000267class GLColorTableEffect : public GrGLEffect {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000268public:
bsalomon@google.comc7818882013-03-20 19:19:53 +0000269 GLColorTableEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000270
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000271 virtual void emitCode(GrGLShaderBuilder*,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000272 const GrDrawEffect&,
bsalomon63e99f72014-07-21 08:03:14 -0700273 const GrEffectKey&,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000274 const char* outputColor,
275 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000276 const TransformedCoordsArray&,
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000277 const TextureSamplerArray&) SK_OVERRIDE;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000278
bsalomon@google.comc7818882013-03-20 19:19:53 +0000279 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000280
bsalomon63e99f72014-07-21 08:03:14 -0700281 static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder* b) {}
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000282
283private:
284
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000285 typedef GrGLEffect INHERITED;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000286};
287
bsalomon@google.comc7818882013-03-20 19:19:53 +0000288GLColorTableEffect::GLColorTableEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000289 : INHERITED(factory) {
290 }
291
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000292void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000293 const GrDrawEffect&,
bsalomon63e99f72014-07-21 08:03:14 -0700294 const GrEffectKey&,
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000295 const char* outputColor,
296 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000297 const TransformedCoordsArray&,
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000298 const TextureSamplerArray& samplers) {
bsalomon@google.com22a800a2012-10-26 19:16:46 +0000299
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000300 static const float kColorScaleFactor = 255.0f / 256.0f;
301 static const float kColorOffsetFactor = 1.0f / 512.0f;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000302 if (NULL == inputColor) {
303 // the input color is solid white (all ones).
304 static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000305 builder->fsCodeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
306 kMaxValue, kMaxValue, kMaxValue, kMaxValue);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000307
308 } else {
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000309 builder->fsCodeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", inputColor);
310 builder->fsCodeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n", inputColor);
311 builder->fsCodeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
312 kColorScaleFactor,
313 kColorOffsetFactor, kColorOffsetFactor,
314 kColorOffsetFactor, kColorOffsetFactor);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000315 }
316
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000317 builder->fsCodeAppendf("\t\t%s.a = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000318 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.a, 0.125)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000319 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.r = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000322 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.r, 0.375)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000323 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000324
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000325 builder->fsCodeAppendf("\t\t%s.g = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000326 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.g, 0.625)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000327 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000328
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000329 builder->fsCodeAppendf("\t\t%s.b = ", outputColor);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000330 builder->fsAppendTextureLookup(samplers[0], "vec2(coord.b, 0.875)");
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000331 builder->fsCodeAppend(";\n");
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000332
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000333 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000334}
335
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000336///////////////////////////////////////////////////////////////////////////////
337
bsalomon@google.com371e1052013-01-11 21:08:55 +0000338ColorTableEffect::ColorTableEffect(GrTexture* texture, unsigned flags)
339 : fTextureAccess(texture, "a")
340 , fFlags(flags) {
bsalomon@google.com50db75c2013-01-11 13:54:30 +0000341 this->addTextureAccess(&fTextureAccess);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000342}
343
344ColorTableEffect::~ColorTableEffect() {
345}
346
bsalomon@google.com396e61f2012-10-25 19:00:29 +0000347const GrBackendEffectFactory& ColorTableEffect::getFactory() const {
348 return GrTBackendEffectFactory<ColorTableEffect>::getInstance();
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000349}
350
bsalomon@google.com8a252f72013-01-22 20:35:13 +0000351bool ColorTableEffect::onIsEqual(const GrEffect& sBase) const {
352 return this->texture(0) == sBase.texture(0);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000353}
354
bsalomon@google.com371e1052013-01-11 21:08:55 +0000355void ColorTableEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
356 // If we kept the table in the effect then we could actually run known inputs through the
357 // table.
358 if (fFlags & SkTable_ColorFilter::kR_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000359 *validFlags &= ~kR_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000360 }
361 if (fFlags & SkTable_ColorFilter::kG_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000362 *validFlags &= ~kG_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000363 }
364 if (fFlags & SkTable_ColorFilter::kB_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000365 *validFlags &= ~kB_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000366 }
367 if (fFlags & SkTable_ColorFilter::kA_Flag) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +0000368 *validFlags &= ~kA_GrColorComponentFlag;
bsalomon@google.com371e1052013-01-11 21:08:55 +0000369 }
370}
371
372
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000373///////////////////////////////////////////////////////////////////////////////
374
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000375GR_DEFINE_EFFECT_TEST(ColorTableEffect);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000376
bsalomon83d081a2014-07-08 09:56:10 -0700377GrEffect* ColorTableEffect::TestCreate(SkRandom* random,
378 GrContext* context,
379 const GrDrawTargetCaps&,
380 GrTexture* textures[]) {
bsalomon@google.com371e1052013-01-11 21:08:55 +0000381 static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilter::kG_Flag |
382 SkTable_ColorFilter::kB_Flag | SkTable_ColorFilter::kA_Flag;
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000383 return ColorTableEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000384}
385
bsalomon83d081a2014-07-08 09:56:10 -0700386GrEffect* SkTable_ColorFilter::asNewEffect(GrContext* context) const {
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000387 SkBitmap bitmap;
bsalomon83d081a2014-07-08 09:56:10 -0700388 GrEffect* effect = NULL;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000389 this->asComponentTable(&bitmap);
bsalomon@google.com8ea78d82012-10-24 20:11:30 +0000390 // passing NULL because this effect does no tiling or filtering.
bsalomon@google.com95ed55a2013-01-24 14:46:47 +0000391 GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, bitmap, NULL);
commit-bot@chromium.orgc7d624e2013-05-28 13:13:56 +0000392 if (NULL != texture) {
393 effect = ColorTableEffect::Create(texture, fFlags);
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000394
commit-bot@chromium.orgc7d624e2013-05-28 13:13:56 +0000395 // Unlock immediately, this is not great, but we don't have a way of
396 // knowing when else to unlock it currently. TODO: Remove this when
397 // unref becomes the unlock replacement for all types of textures.
398 GrUnlockAndUnrefCachedBitmapTexture(texture);
399 }
bsalomon@google.com021fc732012-10-25 12:47:42 +0000400 return effect;
bsalomon@google.comb2ad1012012-10-17 15:00:32 +0000401}
402
403#endif // SK_SUPPORT_GPU
404
mike@reedtribe.orga69b48c2011-12-28 20:31:00 +0000405///////////////////////////////////////////////////////////////////////////////
406
407#ifdef SK_CPU_BENDIAN
408#else
409 #define SK_A32_INDEX (3 - (SK_A32_SHIFT >> 3))
410 #define SK_R32_INDEX (3 - (SK_R32_SHIFT >> 3))
411 #define SK_G32_INDEX (3 - (SK_G32_SHIFT >> 3))
412 #define SK_B32_INDEX (3 - (SK_B32_SHIFT >> 3))
413#endif
414
415///////////////////////////////////////////////////////////////////////////////
416
417SkColorFilter* SkTableColorFilter::Create(const uint8_t table[256]) {
418 return SkNEW_ARGS(SkTable_ColorFilter, (table, table, table, table));
419}
420
421SkColorFilter* SkTableColorFilter::CreateARGB(const uint8_t tableA[256],
422 const uint8_t tableR[256],
423 const uint8_t tableG[256],
424 const uint8_t tableB[256]) {
425 return SkNEW_ARGS(SkTable_ColorFilter, (tableA, tableR, tableG, tableB));
426}
djsollen@google.coma2ca41e2012-03-23 19:00:34 +0000427
428SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkTableColorFilter)
429 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTable_ColorFilter)
430SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END