SkOverdrawColorFilter.cpp revision cb30bb2cb727e276792812c6390547dba474c831
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 10void 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 21void 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 29void SkOverdrawColorFilter::flatten(SkWriteBuffer& buffer) const { 30 buffer.writeByteArray(fColors, kNumColors * sizeof(SkPMColor)); 31} 32 33sk_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 46SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkOverdrawColorFilter) 47 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOverdrawColorFilter) 48SK_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 56class OverdrawFragmentProcessor : public GrFragmentProcessor { 57public: 58 static sk_sp<GrFragmentProcessor> Make(const SkPMColor* colors); 59 60 const char* name() const override { return "Overdraw"; } 61private: 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 73class GLOverdrawFragmentProcessor : public GrGLSLFragmentProcessor { 74public: 75 GLOverdrawFragmentProcessor(const GrColor4f* colors); 76 77 void emitCode(EmitArgs&) override; 78 79protected: 80 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override {} 81 82private: 83 GrColor4f fColors[SkOverdrawColorFilter::kNumColors]; 84 85 typedef GrGLSLFragmentProcessor INHERITED; 86}; 87 88sk_sp<GrFragmentProcessor> SkOverdrawColorFilter::asFragmentProcessor(GrContext*, 89 SkColorSpace*) const { 90 return OverdrawFragmentProcessor::Make(fColors); 91} 92 93sk_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. 107OverdrawFragmentProcessor::OverdrawFragmentProcessor(const GrColor4f* colors) 108 : INHERITED(kNone_OptimizationFlags) { 109 this->initClassID<OverdrawFragmentProcessor>(); 110 memcpy(fColors, colors, SkOverdrawColorFilter::kNumColors * sizeof(GrColor4f)); 111} 112 113GrGLSLFragmentProcessor* OverdrawFragmentProcessor::onCreateGLSLInstance() const { 114 return new GLOverdrawFragmentProcessor(fColors); 115} 116 117bool 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 123GLOverdrawFragmentProcessor::GLOverdrawFragmentProcessor(const GrColor4f* colors) { 124 memcpy(fColors, colors, SkOverdrawColorFilter::kNumColors * sizeof(GrColor4f)); 125} 126 127void 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