17faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
27faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "SkBitmap.h"
37faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "SkTableColorFilter.h"
47faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "SkColorPriv.h"
57faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "SkReadBuffer.h"
67faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "SkWriteBuffer.h"
77faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "SkUnPreMultiply.h"
87faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "SkString.h"
97faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass SkTable_ColorFilter : public SkColorFilter {
117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezpublic:
127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SkTable_ColorFilter(const uint8_t tableA[], const uint8_t tableR[],
137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                        const uint8_t tableG[], const uint8_t tableB[]) {
147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        fBitmap = NULL;
157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        fFlags = 0;
167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        uint8_t* dst = fStorage;
187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        if (tableA) {
197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            memcpy(dst, tableA, 256);
207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            dst += 256;
217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            fFlags |= kA_Flag;
227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        }
237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        if (tableR) {
247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            memcpy(dst, tableR, 256);
257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            dst += 256;
267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            fFlags |= kR_Flag;
277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        }
287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        if (tableG) {
297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            memcpy(dst, tableG, 256);
307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            dst += 256;
317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            fFlags |= kG_Flag;
327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        }
337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        if (tableB) {
347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            memcpy(dst, tableB, 256);
357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            fFlags |= kB_Flag;
367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        }
377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual ~SkTable_ColorFilter() {
407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        SkDELETE(fBitmap);
417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual bool asComponentTable(SkBitmap* table) const SK_OVERRIDE;
447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#if SK_SUPPORT_GPU
467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual GrEffectRef* asNewEffect(GrContext* context) const SK_OVERRIDE;
477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#endif
487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual void filterSpan(const SkPMColor src[], int count,
507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                            SkPMColor dst[]) const SK_OVERRIDE;
517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SK_TO_STRING_OVERRIDE()
537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTable_ColorFilter)
557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    enum {
577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        kA_Flag = 1 << 0,
587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        kR_Flag = 1 << 1,
597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        kG_Flag = 1 << 2,
607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        kB_Flag = 1 << 3,
617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    };
627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezprotected:
647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SkTable_ColorFilter(SkReadBuffer& buffer);
657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezprivate:
687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    mutable const SkBitmap* fBitmap; // lazily allocated
697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    uint8_t fStorage[256 * 4];
717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    unsigned fFlags;
727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    typedef SkColorFilter INHERITED;
747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstatic const uint8_t gIdentityTable[] = {
777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
1007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
1017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
1027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
1037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
1047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
1057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
1067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
1077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
1087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
1097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
1107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid SkTable_ColorFilter::filterSpan(const SkPMColor src[], int count,
1127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                     SkPMColor dst[]) const {
1137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    const uint8_t* table = fStorage;
1147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    const uint8_t* tableA = gIdentityTable;
1157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    const uint8_t* tableR = gIdentityTable;
1167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    const uint8_t* tableG = gIdentityTable;
1177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    const uint8_t* tableB = gIdentityTable;
1187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (fFlags & kA_Flag) {
1197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        tableA = table; table += 256;
1207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
1217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (fFlags & kR_Flag) {
1227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        tableR = table; table += 256;
1237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
1247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (fFlags & kG_Flag) {
1257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        tableG = table; table += 256;
1267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
1277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (fFlags & kB_Flag) {
1287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        tableB = table;
1297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
1307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    const SkUnPreMultiply::Scale* scaleTable = SkUnPreMultiply::GetScaleTable();
1327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    for (int i = 0; i < count; ++i) {
1337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        SkPMColor c = src[i];
1347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        unsigned a, r, g, b;
1357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        if (0 == c) {
1367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            a = r = g = b = 0;
1377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        } else {
1387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            a = SkGetPackedA32(c);
1397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            r = SkGetPackedR32(c);
1407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            g = SkGetPackedG32(c);
1417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            b = SkGetPackedB32(c);
1427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            if (a < 255) {
1447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                SkUnPreMultiply::Scale scale = scaleTable[a];
1457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                r = SkUnPreMultiply::ApplyScale(scale, r);
1467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                g = SkUnPreMultiply::ApplyScale(scale, g);
1477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                b = SkUnPreMultiply::ApplyScale(scale, b);
1487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            }
1497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        }
1507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        dst[i] = SkPremultiplyARGBInline(tableA[a], tableR[r],
1517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                         tableG[g], tableB[b]);
1527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
1537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
1547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#ifndef SK_IGNORE_TO_STRING
1567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid SkTable_ColorFilter::toString(SkString* str) const {
1577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    str->append("SkTable_ColorFilter");
1587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
1597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#endif
1607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstatic const uint8_t gCountNibBits[] = {
1627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    0, 1, 1, 2,
1637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    1, 2, 2, 3,
1647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    1, 2, 2, 3,
1657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    2, 3, 3, 4
1667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
1677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "SkPackBits.h"
1697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid SkTable_ColorFilter::flatten(SkWriteBuffer& buffer) const {
1717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    this->INHERITED::flatten(buffer);
1727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    uint8_t storage[5*256];
1747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    int count = gCountNibBits[fFlags & 0xF];
1757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    size_t size = SkPackBits::Pack8(fStorage, count * 256, storage);
1767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SkASSERT(size <= sizeof(storage));
1777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//    SkDebugf("raw %d packed %d\n", count * 256, size);
1797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    buffer.writeInt(fFlags);
1817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    buffer.writeByteArray(storage, size);
1827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
1837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezSkTable_ColorFilter::SkTable_ColorFilter(SkReadBuffer& buffer) : INHERITED(buffer) {
1857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    fBitmap = NULL;
1867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    uint8_t storage[5*256];
1887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    fFlags = buffer.readInt();
1907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    size_t size = buffer.getArrayCount();
1927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SkASSERT(size <= sizeof(storage));
1937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    buffer.validate(size <= sizeof(storage));
1947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    buffer.readByteArray(storage, size);
1957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SkDEBUGCODE(size_t raw = ) SkPackBits::Unpack8(storage, size, fStorage);
1977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SkASSERT(raw <= sizeof(fStorage));
1997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SkDEBUGCODE(size_t count = gCountNibBits[fFlags & 0xF]);
2007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SkASSERT(raw == count * 256);
2017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
2027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezbool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
2047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (table) {
2057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        if (NULL == fBitmap) {
2067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            SkBitmap* bmp = SkNEW(SkBitmap);
2077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            bmp->allocPixels(SkImageInfo::MakeA8(256, 4));
2087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            uint8_t* bitmapPixels = bmp->getAddr8(0, 0);
2097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            int offset = 0;
2107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            static const unsigned kFlags[] = { kA_Flag, kR_Flag, kG_Flag, kB_Flag };
2117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            for (int x = 0; x < 4; ++x) {
2137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                if (!(fFlags & kFlags[x])) {
2147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                    memcpy(bitmapPixels, gIdentityTable, sizeof(gIdentityTable));
2157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                } else {
2167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                    memcpy(bitmapPixels, fStorage + offset, 256);
2177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                    offset += 256;
2187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                }
2197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                bitmapPixels += 256;
2207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            }
2217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez            fBitmap = bmp;
2227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        }
2237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        *table = *fBitmap;
2247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
2257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return true;
2267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
2277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#if SK_SUPPORT_GPU
2297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "GrEffect.h"
2317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "GrTBackendEffectFactory.h"
2327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "gl/GrGLEffect.h"
2337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "SkGr.h"
2347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass GLColorTableEffect;
2367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass ColorTableEffect : public GrEffect {
2387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezpublic:
2397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    static GrEffectRef* Create(GrTexture* texture, unsigned flags) {
2407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        AutoEffectUnref effect(SkNEW_ARGS(ColorTableEffect, (texture, flags)));
2417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        return CreateEffectRef(effect);
2427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
2437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual ~ColorTableEffect();
2457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    static const char* Name() { return "ColorTable"; }
2477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
2487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
2507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    typedef GLColorTableEffect GLEffect;
2527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezprivate:
2547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
2557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    explicit ColorTableEffect(GrTexture* texture, unsigned flags);
2577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    GR_DECLARE_EFFECT_TEST;
2597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    GrTextureAccess fTextureAccess;
2617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    unsigned        fFlags; // currently not used in shader code, just to assist
2627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                            // getConstantColorComponents().
2637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    typedef GrEffect INHERITED;
2657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
2667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass GLColorTableEffect : public GrGLEffect {
2687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezpublic:
2697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    GLColorTableEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
2707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual void emitCode(GrGLShaderBuilder*,
2727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                          const GrDrawEffect&,
2737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                          EffectKey,
2747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                          const char* outputColor,
2757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                          const char* inputColor,
2767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                          const TransformedCoordsArray&,
2777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                          const TextureSamplerArray&) SK_OVERRIDE;
2787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
2807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
2827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezprivate:
2847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    typedef GrGLEffect INHERITED;
2867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
2877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezGLColorTableEffect::GLColorTableEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
2897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    : INHERITED(factory) {
2907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez }
2917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
2927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
2937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                  const GrDrawEffect&,
2947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                  EffectKey,
2957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                  const char* outputColor,
2967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                  const char* inputColor,
2977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                  const TransformedCoordsArray&,
2987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                  const TextureSamplerArray& samplers) {
2997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    static const float kColorScaleFactor = 255.0f / 256.0f;
3017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    static const float kColorOffsetFactor = 1.0f / 512.0f;
3027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (NULL == inputColor) {
3037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        // the input color is solid white (all ones).
3047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
3057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        builder->fsCodeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
3067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                               kMaxValue, kMaxValue, kMaxValue, kMaxValue);
3077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    } else {
3097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        builder->fsCodeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", inputColor);
3107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        builder->fsCodeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n", inputColor);
3117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        builder->fsCodeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
3127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                              kColorScaleFactor,
3137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                              kColorOffsetFactor, kColorOffsetFactor,
3147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                              kColorOffsetFactor, kColorOffsetFactor);
3157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
3167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsCodeAppendf("\t\t%s.a = ", outputColor);
3187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsAppendTextureLookup(samplers[0], "vec2(coord.a, 0.125)");
3197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsCodeAppend(";\n");
3207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsCodeAppendf("\t\t%s.r = ", outputColor);
3227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsAppendTextureLookup(samplers[0], "vec2(coord.r, 0.375)");
3237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsCodeAppend(";\n");
3247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsCodeAppendf("\t\t%s.g = ", outputColor);
3267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsAppendTextureLookup(samplers[0], "vec2(coord.g, 0.625)");
3277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsCodeAppend(";\n");
3287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsCodeAppendf("\t\t%s.b = ", outputColor);
3307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsAppendTextureLookup(samplers[0], "vec2(coord.b, 0.875)");
3317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsCodeAppend(";\n");
3327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
3347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
3357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezGrGLEffect::EffectKey GLColorTableEffect::GenKey(const GrDrawEffect&, const GrGLCaps&) {
3377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return 0;
3387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
3397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez///////////////////////////////////////////////////////////////////////////////
3417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezColorTableEffect::ColorTableEffect(GrTexture* texture, unsigned flags)
3437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    : fTextureAccess(texture, "a")
3447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    , fFlags(flags) {
3457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    this->addTextureAccess(&fTextureAccess);
3467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
3477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezColorTableEffect::~ColorTableEffect() {
3497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
3507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezconst GrBackendEffectFactory&  ColorTableEffect::getFactory() const {
3527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return GrTBackendEffectFactory<ColorTableEffect>::getInstance();
3537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
3547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezbool ColorTableEffect::onIsEqual(const GrEffect& sBase) const {
3567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return this->texture(0) == sBase.texture(0);
3577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
3587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid ColorTableEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
3607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // If we kept the table in the effect then we could actually run known inputs through the
3617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // table.
3627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (fFlags & SkTable_ColorFilter::kR_Flag) {
3637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        *validFlags &= ~kR_GrColorComponentFlag;
3647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
3657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (fFlags & SkTable_ColorFilter::kG_Flag) {
3667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        *validFlags &= ~kG_GrColorComponentFlag;
3677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
3687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (fFlags & SkTable_ColorFilter::kB_Flag) {
3697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        *validFlags &= ~kB_GrColorComponentFlag;
3707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
3717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (fFlags & SkTable_ColorFilter::kA_Flag) {
3727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        *validFlags &= ~kA_GrColorComponentFlag;
3737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
3747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
3757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez///////////////////////////////////////////////////////////////////////////////
3787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezGR_DEFINE_EFFECT_TEST(ColorTableEffect);
3807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezGrEffectRef* ColorTableEffect::TestCreate(SkRandom* random,
3827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                          GrContext* context,
3837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                          const GrDrawTargetCaps&,
3847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                          GrTexture* textures[]) {
3857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilter::kG_Flag |
3867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                SkTable_ColorFilter::kB_Flag | SkTable_ColorFilter::kA_Flag;
3877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return ColorTableEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags);
3887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
3897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezGrEffectRef* SkTable_ColorFilter::asNewEffect(GrContext* context) const {
3917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SkBitmap bitmap;
3927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    GrEffectRef* effect = NULL;
3937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    this->asComponentTable(&bitmap);
3947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // passing NULL because this effect does no tiling or filtering.
3957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, bitmap, NULL);
3967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (NULL != texture) {
3977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        effect = ColorTableEffect::Create(texture, fFlags);
3987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
3997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        // Unlock immediately, this is not great, but we don't have a way of
4007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        // knowing when else to unlock it currently. TODO: Remove this when
4017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        // unref becomes the unlock replacement for all types of textures.
4027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        GrUnlockAndUnrefCachedBitmapTexture(texture);
4037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
4047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return effect;
4057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
4067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#endif // SK_SUPPORT_GPU
4087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez///////////////////////////////////////////////////////////////////////////////
4107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#ifdef SK_CPU_BENDIAN
4127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#else
4137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    #define SK_A32_INDEX    (3 - (SK_A32_SHIFT >> 3))
4147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    #define SK_R32_INDEX    (3 - (SK_R32_SHIFT >> 3))
4157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    #define SK_G32_INDEX    (3 - (SK_G32_SHIFT >> 3))
4167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    #define SK_B32_INDEX    (3 - (SK_B32_SHIFT >> 3))
4177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#endif
4187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez///////////////////////////////////////////////////////////////////////////////
4207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezSkColorFilter* SkTableColorFilter::Create(const uint8_t table[256]) {
4227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return SkNEW_ARGS(SkTable_ColorFilter, (table, table, table, table));
4237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
4247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezSkColorFilter* SkTableColorFilter::CreateARGB(const uint8_t tableA[256],
4267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                              const uint8_t tableR[256],
4277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                              const uint8_t tableG[256],
4287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                              const uint8_t tableB[256]) {
4297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    return SkNEW_ARGS(SkTable_ColorFilter, (tableA, tableR, tableG, tableB));
4307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
4317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkTableColorFilter)
4337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTable_ColorFilter)
4347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
4357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez