Home | History | Annotate | Download | only in effects
      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 "SkOverdrawColorFilter.h"
      9 
     10 void SkOverdrawColorFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
     11     for (int x = 0; x < count; x++) {
     12         uint8_t alpha = SkGetPackedA32(src[x]);
     13         if (alpha >= kNumColors) {
     14             alpha = kNumColors - 1;
     15         }
     16 
     17         dst[x] = fColors[alpha];
     18     }
     19 }
     20 
     21 void SkOverdrawColorFilter::toString(SkString* str) const {
     22     str->append("SkOverdrawColorFilter (");
     23     for (int i = 0; i < kNumColors; i++) {
     24         str->appendf("%d: %x\n", i, fColors[i]);
     25     }
     26     str->append(")");
     27 }
     28 
     29 void SkOverdrawColorFilter::flatten(SkWriteBuffer& buffer) const {
     30     buffer.writeByteArray(fColors, kNumColors * sizeof(SkPMColor));
     31 }
     32 
     33 sk_sp<SkFlattenable> SkOverdrawColorFilter::CreateProc(SkReadBuffer& buffer) {
     34     SkPMColor colors[kNumColors];
     35     size_t size = buffer.getArrayCount();
     36     if (!buffer.validate(size == sizeof(colors))) {
     37         return nullptr;
     38     }
     39     if (!buffer.readByteArray(colors, sizeof(colors))) {
     40         return nullptr;
     41     }
     42 
     43     return SkOverdrawColorFilter::Make(colors);
     44 }
     45 
     46 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkOverdrawColorFilter)
     47     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOverdrawColorFilter)
     48 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
     49 
     50 #if SK_SUPPORT_GPU
     51 
     52 #include "GrFragmentProcessor.h"
     53 #include "glsl/GrGLSLFragmentProcessor.h"
     54 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     55 
     56 class OverdrawFragmentProcessor : public GrFragmentProcessor {
     57 public:
     58     static sk_sp<GrFragmentProcessor> Make(const SkPMColor* colors);
     59 
     60     const char* name() const override { return "Overdraw"; }
     61 private:
     62     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
     63     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
     64     bool onIsEqual(const GrFragmentProcessor&) const override;
     65 
     66     OverdrawFragmentProcessor(const GrColor4f* colors);
     67 
     68     GrColor4f fColors[SkOverdrawColorFilter::kNumColors];
     69 
     70     typedef GrFragmentProcessor INHERITED;
     71 };
     72 
     73 class GLOverdrawFragmentProcessor : public GrGLSLFragmentProcessor {
     74 public:
     75     GLOverdrawFragmentProcessor(const GrColor4f* colors);
     76 
     77     void emitCode(EmitArgs&) override;
     78 
     79 protected:
     80     void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override {}
     81 
     82 private:
     83     GrColor4f fColors[SkOverdrawColorFilter::kNumColors];
     84 
     85     typedef GrGLSLFragmentProcessor INHERITED;
     86 };
     87 
     88 sk_sp<GrFragmentProcessor> SkOverdrawColorFilter::asFragmentProcessor(GrContext*,
     89                                                                       SkColorSpace*) const {
     90     return OverdrawFragmentProcessor::Make(fColors);
     91 }
     92 
     93 sk_sp<GrFragmentProcessor> OverdrawFragmentProcessor::Make(const SkPMColor* colors) {
     94     GrColor4f grColors[SkOverdrawColorFilter::kNumColors];
     95     for (int i = 0; i < SkOverdrawColorFilter::kNumColors; i++) {
     96         grColors[i] = GrColor4f::FromGrColor(GrColorPackRGBA(SkGetPackedR32(colors[i]),
     97                                                              SkGetPackedG32(colors[i]),
     98                                                              SkGetPackedB32(colors[i]),
     99                                                              SkGetPackedA32(colors[i])));
    100     }
    101 
    102     return sk_sp<OverdrawFragmentProcessor>(new OverdrawFragmentProcessor(grColors));
    103 }
    104 
    105 // This could implement the constant input -> constant output optimization, but we don't really
    106 // care given how this is used.
    107 OverdrawFragmentProcessor::OverdrawFragmentProcessor(const GrColor4f* colors)
    108         : INHERITED(kNone_OptimizationFlags) {
    109     this->initClassID<OverdrawFragmentProcessor>();
    110     memcpy(fColors, colors, SkOverdrawColorFilter::kNumColors * sizeof(GrColor4f));
    111 }
    112 
    113 GrGLSLFragmentProcessor* OverdrawFragmentProcessor::onCreateGLSLInstance() const {
    114     return new GLOverdrawFragmentProcessor(fColors);
    115 }
    116 
    117 bool OverdrawFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
    118     const OverdrawFragmentProcessor& that = other.cast<OverdrawFragmentProcessor>();
    119     return 0 == memcmp(fColors, that.fColors,
    120                        sizeof(GrColor4f) * SkOverdrawColorFilter::kNumColors);
    121 }
    122 
    123 GLOverdrawFragmentProcessor::GLOverdrawFragmentProcessor(const GrColor4f* colors) {
    124     memcpy(fColors, colors, SkOverdrawColorFilter::kNumColors * sizeof(GrColor4f));
    125 }
    126 
    127 void GLOverdrawFragmentProcessor::emitCode(EmitArgs& args) {
    128     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
    129     if (nullptr == args.fInputColor) {
    130         fragBuilder->codeAppendf("%s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
    131                                                                     fColors[5].fRGBA[0],
    132                                                                     fColors[5].fRGBA[1],
    133                                                                     fColors[5].fRGBA[2],
    134                                                                     fColors[5].fRGBA[3]);
    135     } else {
    136         fragBuilder->codeAppendf("float alpha = 255.0 * %s.a;", args.fInputColor);
    137         fragBuilder->codeAppendf("if (alpha < 0.5) {");
    138         fragBuilder->codeAppendf("    %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
    139                                                                         fColors[0].fRGBA[0],
    140                                                                         fColors[0].fRGBA[1],
    141                                                                         fColors[0].fRGBA[2],
    142                                                                         fColors[0].fRGBA[3]);
    143         fragBuilder->codeAppendf("} else if (alpha < 1.5) {");
    144         fragBuilder->codeAppendf("    %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
    145                                                                         fColors[1].fRGBA[0],
    146                                                                         fColors[1].fRGBA[1],
    147                                                                         fColors[1].fRGBA[2],
    148                                                                         fColors[1].fRGBA[3]);
    149         fragBuilder->codeAppendf("} else if (alpha < 2.5) {");
    150         fragBuilder->codeAppendf("    %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
    151                                                                         fColors[2].fRGBA[0],
    152                                                                         fColors[2].fRGBA[1],
    153                                                                         fColors[2].fRGBA[2],
    154                                                                         fColors[2].fRGBA[3]);
    155         fragBuilder->codeAppendf("} else if (alpha < 3.5) {");
    156         fragBuilder->codeAppendf("    %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
    157                                                                         fColors[3].fRGBA[0],
    158                                                                         fColors[3].fRGBA[1],
    159                                                                         fColors[3].fRGBA[2],
    160                                                                         fColors[3].fRGBA[3]);
    161         fragBuilder->codeAppendf("} else if (alpha < 4.5) {");
    162         fragBuilder->codeAppendf("    %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
    163                                                                         fColors[4].fRGBA[0],
    164                                                                         fColors[4].fRGBA[1],
    165                                                                         fColors[4].fRGBA[2],
    166                                                                         fColors[4].fRGBA[3]);
    167         fragBuilder->codeAppendf("} else {");
    168         fragBuilder->codeAppendf("    %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
    169                                                                         fColors[5].fRGBA[0],
    170                                                                         fColors[5].fRGBA[1],
    171                                                                         fColors[5].fRGBA[2],
    172                                                                         fColors[5].fRGBA[3]);
    173         fragBuilder->codeAppendf("}");
    174     }
    175 }
    176 
    177 #endif
    178