Home | History | Annotate | Download | only in debugger
      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 "SkColorPriv.h"
      9 #include "SkOverdrawMode.h"
     10 #include "SkString.h"
     11 #include "SkXfermode.h"
     12 
     13 #if SK_SUPPORT_GPU
     14 #include "GrFragmentProcessor.h"
     15 #include "GrInvariantOutput.h"
     16 #include "GrXferProcessor.h"
     17 #include "glsl/GrGLSLFragmentProcessor.h"
     18 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     19 #include "glsl/GrGLSLXferProcessor.h"
     20 
     21  ///////////////////////////////////////////////////////////////////////////////
     22  // Fragment Processor
     23  ///////////////////////////////////////////////////////////////////////////////
     24 
     25 class GLOverdrawFP;
     26 
     27 class GrOverdrawFP : public GrFragmentProcessor {
     28 public:
     29     static const GrFragmentProcessor* Create(const GrFragmentProcessor* dst) {
     30         return new GrOverdrawFP(dst);
     31     }
     32 
     33     ~GrOverdrawFP() override { }
     34 
     35     const char* name() const override { return "Overdraw"; }
     36 
     37     SkString dumpInfo() const override {
     38         SkString str;
     39         return str;
     40     }
     41 
     42 private:
     43     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
     44 
     45     void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder* b) const override;
     46 
     47     bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
     48 
     49     void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
     50         inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
     51     }
     52 
     53     GrOverdrawFP(const GrFragmentProcessor* dst) {
     54         this->initClassID<GrOverdrawFP>();
     55 
     56         SkASSERT(dst);
     57         SkDEBUGCODE(int dstIndex = )this->registerChildProcessor(dst);
     58         SkASSERT(0 == dstIndex);
     59     }
     60 
     61     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
     62     typedef GrFragmentProcessor INHERITED;
     63 };
     64 
     65 ///////////////////////////////////////////////////////////////////////////////
     66 
     67 static void add_overdraw_code(GrGLSLFragmentBuilder* fragBuilder,
     68                               const char* dstColor,
     69                               const char* outputColor) {
     70 
     71     static const GrGLSLShaderVar gColorTableArgs[] = {
     72         // TODO: once kInt_GrSLType lands - switch this over
     73         GrGLSLShaderVar("index", kFloat_GrSLType),
     74     };
     75     SkString colorTableFuncName;
     76 
     77     // The 'colorTable' function exists to work around older GLSL's prohibition
     78     // of initialized arrays. It takes an integer index and just returns the
     79     // corresponding color.
     80    fragBuilder->emitFunction(kVec4f_GrSLType,
     81                              "colorTable",
     82                              SK_ARRAY_COUNT(gColorTableArgs),
     83                              gColorTableArgs,
     84                              "if (index < 1.5) { return vec4(0.5,   0.617, 1.0,   1.0); }"
     85                              "if (index < 2.5) { return vec4(0.664, 0.723, 0.83,  1.0); }"
     86                              "if (index < 3.5) { return vec4(0.832, 0.762, 0.664, 1.0); }"
     87                              "if (index < 4.5) { return vec4(1,     0.75,  0.496, 1.0); }"
     88                              "if (index < 5.5) { return vec4(1,     0.723, 0.332, 1.0); }"
     89                              "if (index < 6.5) { return vec4(1,     0.645, 0.164, 1.0); }"
     90                              "if (index < 7.5) { return vec4(1,     0.527, 0,     1.0); }"
     91                              "if (index < 8.5) { return vec4(1,     0.371, 0,     1.0); }"
     92                              "if (index < 9.5) { return vec4(1,     0.195, 0,     1.0); }"
     93                              "return vec4(1,     0,     0,     1.0);",
     94                              &colorTableFuncName);
     95 
     96     fragBuilder->codeAppend("int nextIdx;");
     97     fragBuilder->codeAppendf("vec4 dst = %s;", dstColor);
     98     fragBuilder->codeAppend("if (dst.r < 0.25) { nextIdx = 1; }");
     99     // cap 'idx' at 10
    100     fragBuilder->codeAppend("else if (dst.g < 0.0977) { nextIdx = 10; }");
    101     fragBuilder->codeAppend("else if (dst.b > 0.08) { nextIdx = 8 - int(6.0 * dst.b + 0.5); }");
    102     fragBuilder->codeAppend("else { nextIdx = 11 - int(5.7 * dst.g + 0.5); }");
    103     fragBuilder->codeAppendf("%s = %s(float(nextIdx));", outputColor, colorTableFuncName.c_str());
    104 }
    105 
    106 class GLOverdrawFP : public GrGLSLFragmentProcessor {
    107 public:
    108     void emitCode(EmitArgs& args) override {
    109         GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
    110         SkString dstColor("dstColor");
    111         this->emitChild(0, nullptr, &dstColor, args);
    112 
    113         add_overdraw_code(fragBuilder, dstColor.c_str(), args.fOutputColor);
    114     }
    115 
    116     static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*) { }
    117 
    118 private:
    119     typedef GrGLSLFragmentProcessor INHERITED;
    120 };
    121 
    122 ///////////////////////////////////////////////////////////////////////////////
    123 
    124 GrGLSLFragmentProcessor* GrOverdrawFP::onCreateGLSLInstance() const {
    125     return new GLOverdrawFP;
    126 }
    127 
    128 void GrOverdrawFP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
    129     GLOverdrawFP::GenKey(*this, caps, b);
    130 }
    131 
    132 const GrFragmentProcessor* GrOverdrawFP::TestCreate(GrProcessorTestData* d) {
    133     SkAutoTUnref<const GrFragmentProcessor> dst(GrProcessorUnitTest::CreateChildFP(d));
    134     return new GrOverdrawFP(dst);
    135 }
    136 
    137 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrOverdrawFP);
    138 
    139 ///////////////////////////////////////////////////////////////////////////////
    140 // Xfer Processor
    141 ///////////////////////////////////////////////////////////////////////////////
    142 
    143 class OverdrawXP : public GrXferProcessor {
    144 public:
    145     OverdrawXP(const DstTexture* dstTexture, bool hasMixedSamples)
    146         : INHERITED(dstTexture, true, hasMixedSamples) {
    147         this->initClassID<OverdrawXP>();
    148     }
    149 
    150     const char* name() const override { return "Overdraw"; }
    151 
    152     GrGLSLXferProcessor* createGLSLInstance() const override;
    153 
    154 private:
    155     GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
    156                                                  bool doesStencilWrite,
    157                                                  GrColor* overrideColor,
    158                                                  const GrCaps& caps) const override {
    159         // We never look at the color input
    160         return GrXferProcessor::kIgnoreColor_OptFlag;
    161     }
    162 
    163     void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
    164 
    165     bool onIsEqual(const GrXferProcessor&) const override { return true; }
    166 
    167     typedef GrXferProcessor INHERITED;
    168 };
    169 
    170 ///////////////////////////////////////////////////////////////////////////////
    171 
    172 class GLOverdrawXP : public GrGLSLXferProcessor {
    173 public:
    174     GLOverdrawXP(const OverdrawXP&) { }
    175 
    176     ~GLOverdrawXP() override {}
    177 
    178     static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*) { }
    179 
    180 private:
    181     void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder* fragBuilder,
    182                                  GrGLSLUniformHandler* uniformHandler,
    183                                  const char* srcColor,
    184                                  const char* srcCoverage,
    185                                  const char* dstColor,
    186                                  const char* outColor,
    187                                  const char* outColorSecondary,
    188                                  const GrXferProcessor& proc) override {
    189         add_overdraw_code(fragBuilder, dstColor, outColor);
    190 
    191         // Apply coverage.
    192         INHERITED::DefaultCoverageModulation(fragBuilder, srcCoverage, dstColor, outColor,
    193                                              outColorSecondary, proc);
    194     }
    195 
    196     void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override { };
    197 
    198     typedef GrGLSLXferProcessor INHERITED;
    199 };
    200 
    201 ///////////////////////////////////////////////////////////////////////////////
    202 
    203 void OverdrawXP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
    204     GLOverdrawXP::GenKey(*this, caps, b);
    205 }
    206 
    207 GrGLSLXferProcessor* OverdrawXP::createGLSLInstance() const { return new GLOverdrawXP(*this); }
    208 
    209 ///////////////////////////////////////////////////////////////////////////////
    210 class GrOverdrawXPFactory : public GrXPFactory {
    211 public:
    212     static GrXPFactory* Create() { return new GrOverdrawXPFactory(); }
    213 
    214     void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
    215                                   GrXPFactory::InvariantBlendedColor* blendedColor) const override {
    216         blendedColor->fWillBlendWithDst = true;
    217         blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
    218     }
    219 
    220 private:
    221     GrOverdrawXPFactory() {
    222         this->initClassID<GrOverdrawXPFactory>();
    223     }
    224 
    225     GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
    226                                            const GrPipelineOptimizations& optimizations,
    227                                            bool hasMixedSamples,
    228                                            const DstTexture* dstTexture) const override {
    229         return new OverdrawXP(dstTexture, hasMixedSamples);
    230     }
    231 
    232     bool onWillReadDstColor(const GrCaps& caps,
    233                             const GrPipelineOptimizations& optimizations,
    234                             bool hasMixedSamples) const override {
    235         return true;
    236     }
    237 
    238     bool onIsEqual(const GrXPFactory& xpfBase) const override { return true; }
    239 
    240     GR_DECLARE_XP_FACTORY_TEST;
    241 
    242     typedef GrXPFactory INHERITED;
    243 };
    244 
    245 GR_DEFINE_XP_FACTORY_TEST(GrOverdrawXPFactory);
    246 
    247 const GrXPFactory* GrOverdrawXPFactory::TestCreate(GrProcessorTestData* d) {
    248     return GrOverdrawXPFactory::Create();
    249 }
    250 #endif
    251 
    252 ///////////////////////////////////////////////////////////////////////////////
    253 class SkOverdrawXfermode : public SkXfermode {
    254 public:
    255     static SkXfermode* Create() {
    256         return new SkOverdrawXfermode;
    257     }
    258 
    259     SkPMColor xferColor(SkPMColor src, SkPMColor dst) const override {
    260         // This table encodes the color progression of the overdraw visualization
    261         static const SkPMColor gTable[] = {
    262             SkPackARGB32(0x00, 0x00, 0x00, 0x00),
    263             SkPackARGB32(0xFF, 128, 158, 255),
    264             SkPackARGB32(0xFF, 170, 185, 212),
    265             SkPackARGB32(0xFF, 213, 195, 170),
    266             SkPackARGB32(0xFF, 255, 192, 127),
    267             SkPackARGB32(0xFF, 255, 185, 85),
    268             SkPackARGB32(0xFF, 255, 165, 42),
    269             SkPackARGB32(0xFF, 255, 135, 0),
    270             SkPackARGB32(0xFF, 255,  95, 0),
    271             SkPackARGB32(0xFF, 255,  50, 0),
    272             SkPackARGB32(0xFF, 255,  0, 0)
    273         };
    274 
    275 
    276         int nextIdx;
    277         if (SkColorGetR(dst) < 64) { // dst color is the 0th color so the next color is 1
    278             nextIdx = 1;
    279         } else if (SkColorGetG(dst) < 25) { // dst color is the 10th color so cap there
    280             nextIdx = 10;
    281         } else if ((SkColorGetB(dst)+21)/42 > 0) { // dst color is one of 1-6
    282             nextIdx = 8 - (SkColorGetB(dst)+21)/42;
    283         } else { // dst color is between 7 and 9
    284             nextIdx = 11 - (SkColorGetG(dst)+22)/45;
    285         }
    286         SkASSERT(nextIdx < (int)SK_ARRAY_COUNT(gTable));
    287 
    288         return gTable[nextIdx];
    289     }
    290 
    291     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOverdrawXfermode)
    292 
    293 #if SK_SUPPORT_GPU
    294     const GrFragmentProcessor* getFragmentProcessorForImageFilter(
    295                                                 const GrFragmentProcessor* dst) const override {
    296         return GrOverdrawFP::Create(dst);
    297     }
    298 
    299     GrXPFactory* asXPFactory() const override {
    300         return GrOverdrawXPFactory::Create();
    301     }
    302 #endif
    303 
    304 #ifndef SK_IGNORE_TO_STRING
    305     void toString(SkString* str) const override { str->set("SkOverdrawXfermode"); }
    306 #endif
    307 
    308 private:
    309     friend class SkOverdrawMode;
    310 
    311     void flatten(SkWriteBuffer& buffer) const override { }
    312 
    313     typedef SkXfermode INHERITED;
    314 };
    315 
    316 SkFlattenable* SkOverdrawXfermode::CreateProc(SkReadBuffer& buffer) {
    317     return Create();
    318 }
    319 
    320 SkXfermode* SkOverdrawMode::Create() { return new SkOverdrawXfermode; }
    321 
    322 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkOverdrawMode)
    323     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOverdrawXfermode)
    324 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
    325