1 /* 2 * Copyright 2021 Google LLC. 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 "gm/gm.h" 9 #include "include/core/SkCanvas.h" 10 #include "include/core/SkImageInfo.h" 11 #include "include/core/SkMatrix.h" 12 #include "include/core/SkRect.h" 13 #include "include/core/SkTypes.h" 14 #include "include/effects/SkImageFilters.h" 15 #include "src/core/SkCanvasPriv.h" 16 #include "src/gpu/GrDirectContextPriv.h" 17 #include "src/gpu/GrFragmentProcessor.h" 18 #include "src/gpu/GrStyle.h" 19 #include "src/gpu/SkGr.h" 20 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" 21 #include "src/gpu/v1/SurfaceDrawContext_v1.h" 22 #include "tools/Resources.h" 23 #include "tools/ToolUtils.h" 24 25 namespace { 26 27 class DestColorTestFP : public GrFragmentProcessor { 28 public: Make(std::unique_ptr<GrFragmentProcessor> child)29 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) { 30 return std::unique_ptr<GrFragmentProcessor>(new DestColorTestFP(std::move(child))); 31 } 32 clone() const33 std::unique_ptr<GrFragmentProcessor> clone() const override { 34 return std::unique_ptr<GrFragmentProcessor>(new DestColorTestFP(*this)); 35 } 36 37 private: DestColorTestFP(std::unique_ptr<GrFragmentProcessor> child)38 DestColorTestFP(std::unique_ptr<GrFragmentProcessor> child) 39 : INHERITED(kTestFP_ClassID, kNone_OptimizationFlags) { 40 this->registerChild(std::move(child)); 41 } 42 DestColorTestFP(const DestColorTestFP & that)43 explicit DestColorTestFP(const DestColorTestFP& that) 44 : INHERITED(that) {} 45 name() const46 const char* name() const override { return "DestColorTestFP"; } onAddToKey(const GrShaderCaps &,GrProcessorKeyBuilder *) const47 void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} onIsEqual(const GrFragmentProcessor &) const48 bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 49 onMakeProgramImpl() const50 std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override { 51 class Impl : public ProgramImpl { 52 public: 53 void emitCode(EmitArgs& args) override { 54 SkString result = this->invokeChild(0, args); 55 args.fFragBuilder->codeAppendf("return (half4(1) - (%s)).rgb1;", result.c_str()); 56 } 57 }; 58 59 return std::make_unique<Impl>(); 60 } 61 62 using INHERITED = GrFragmentProcessor; 63 }; 64 65 } // namespace 66 67 namespace skiagm { 68 69 DEF_SIMPLE_GPU_GM_CAN_FAIL(destcolor, rContext, canvas, errorMsg, 640, 640) { 70 SkRect bounds = SkRect::MakeIWH(512, 512); 71 72 auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(canvas); 73 if (!sdc) { 74 *errorMsg = GM::kErrorMsg_DrawSkippedGpuOnly; 75 return DrawResult::kSkip; 76 } 77 78 // Draw the mandrill. 79 SkPaint p; 80 p.setImageFilter(SkImageFilters::Image(GetResourceAsImage("images/mandrill_512.png"), 81 bounds, bounds, SkSamplingOptions())); 82 canvas->drawPaint(p); 83 84 // Now let's add our test FP on top. It reads back the original image and inverts it. 85 GrPaint invertPaint; 86 invertPaint.setColor4f(SK_PMColor4fWHITE); 87 invertPaint.setPorterDuffXPFactory(SkBlendMode::kSrcOver); 88 invertPaint.setColorFragmentProcessor( 89 DestColorTestFP::Make(GrFragmentProcessor::SurfaceColor())); 90 sdc->drawOval(/*clip*/ nullptr, std::move(invertPaint), GrAA::kYes, SkMatrix::I(), 91 SkRect::MakeLTRB(128, 128, 640, 640), GrStyle::SimpleFill()); 92 93 return DrawResult::kOk; 94 } 95 96 } // namespace skiagm 97