1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkArenaAlloc.h"
9#include "SkOverdrawColorFilter.h"
10#include "SkPM4f.h"
11#include "SkRasterPipeline.h"
12#include "SkReadBuffer.h"
13#include "../jumper/SkJumper.h"
14
15void SkOverdrawColorFilter::onAppendStages(SkRasterPipeline* p,
16                                           SkColorSpace* dstCS,
17                                           SkArenaAlloc* alloc,
18                                           bool shader_is_opaque) const {
19    struct Ctx : public SkJumper_CallbackCtx {
20        const SkPMColor* colors;
21    };
22    // TODO: do we care about transforming to dstCS?
23    auto ctx = alloc->make<Ctx>();
24    ctx->colors = fColors;
25    ctx->fn = [](SkJumper_CallbackCtx* arg, int active_pixels) {
26        auto ctx = (Ctx*)arg;
27        auto pixels = (SkPM4f*)ctx->rgba;
28        for (int i = 0; i < active_pixels; i++) {
29            uint8_t alpha = (int)(pixels[i].a() * 255);
30            if (alpha >= kNumColors) {
31                alpha = kNumColors - 1;
32            }
33            pixels[i] = SkPM4f::FromPMColor(ctx->colors[alpha]);
34        }
35    };
36    p->append(SkRasterPipeline::callback, ctx);
37}
38
39void SkOverdrawColorFilter::toString(SkString* str) const {
40    str->append("SkOverdrawColorFilter (");
41    for (int i = 0; i < kNumColors; i++) {
42        str->appendf("%d: %x\n", i, fColors[i]);
43    }
44    str->append(")");
45}
46
47void SkOverdrawColorFilter::flatten(SkWriteBuffer& buffer) const {
48    buffer.writeByteArray(fColors, kNumColors * sizeof(SkPMColor));
49}
50
51sk_sp<SkFlattenable> SkOverdrawColorFilter::CreateProc(SkReadBuffer& buffer) {
52    SkPMColor colors[kNumColors];
53    size_t size = buffer.getArrayCount();
54    if (!buffer.validate(size == sizeof(colors))) {
55        return nullptr;
56    }
57    if (!buffer.readByteArray(colors, sizeof(colors))) {
58        return nullptr;
59    }
60
61    return SkOverdrawColorFilter::Make(colors);
62}
63
64SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkOverdrawColorFilter)
65    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOverdrawColorFilter)
66SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
67#if SK_SUPPORT_GPU
68
69#include "effects/GrOverdrawFragmentProcessor.h"
70
71std::unique_ptr<GrFragmentProcessor> SkOverdrawColorFilter::asFragmentProcessor(
72        GrContext*, const GrColorSpaceInfo&) const {
73    return GrOverdrawFragmentProcessor::Make(fColors[0], fColors[1], fColors[2], fColors[3],
74                                             fColors[4], fColors[5]);
75}
76
77#endif
78