Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2015 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 // This test only works with the GPU backend.
      9 
     10 #include "gm.h"
     11 #include "sk_tool_utils.h"
     12 
     13 #include "GrContext.h"
     14 #include "GrRenderTargetContextPriv.h"
     15 #include "SkGr.h"
     16 #include "SkGradientShader.h"
     17 #include "effects/GrConstColorProcessor.h"
     18 #include "ops/GrDrawOp.h"
     19 #include "ops/GrFillRectOp.h"
     20 
     21 namespace skiagm {
     22 /**
     23  * This GM directly exercises GrConstColorProcessor.
     24  */
     25 class ConstColorProcessor : public GM {
     26 public:
     27     ConstColorProcessor() {
     28         this->setBGColor(0xFFDDDDDD);
     29     }
     30 
     31 protected:
     32     SkString onShortName() override {
     33         return SkString("const_color_processor");
     34     }
     35 
     36     SkISize onISize() override {
     37         return SkISize::Make(kWidth, kHeight);
     38     }
     39 
     40     void onOnceBeforeDraw() override {
     41         SkColor colors[] = { 0xFFFF0000, 0x2000FF00, 0xFF0000FF};
     42         SkPoint pts[] = { SkPoint::Make(0, 0), SkPoint::Make(kRectSize, kRectSize) };
     43         fShader = SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
     44                                                SkShader::kClamp_TileMode);
     45     }
     46 
     47     void onDraw(SkCanvas* canvas) override {
     48         GrRenderTargetContext* renderTargetContext =
     49             canvas->internal_private_accessTopLayerRenderTargetContext();
     50         if (!renderTargetContext) {
     51             skiagm::GM::DrawGpuOnlyMessage(canvas);
     52             return;
     53         }
     54 
     55         GrContext* context = canvas->getGrContext();
     56         if (!context) {
     57             return;
     58         }
     59 
     60         constexpr GrColor kColors[] = {
     61             0xFFFFFFFF,
     62             0xFFFF00FF,
     63             0x80000000,
     64             0x00000000,
     65         };
     66 
     67         constexpr SkColor kPaintColors[] = {
     68             0xFFFFFFFF,
     69             0xFFFF0000,
     70             0x80FF0000,
     71             0x00000000,
     72         };
     73 
     74         const char* kModeStrs[] {
     75             "kIgnore",
     76             "kModulateRGBA",
     77             "kModulateA",
     78         };
     79         GR_STATIC_ASSERT(SK_ARRAY_COUNT(kModeStrs) == GrConstColorProcessor::kInputModeCnt);
     80 
     81         SkScalar y = kPad;
     82         SkScalar x = kPad;
     83         SkScalar maxW = 0;
     84         for (size_t paintType = 0; paintType < SK_ARRAY_COUNT(kPaintColors) + 1; ++paintType) {
     85             for (size_t procColor = 0; procColor < SK_ARRAY_COUNT(kColors); ++procColor) {
     86                 for (int m = 0; m < GrConstColorProcessor::kInputModeCnt; ++m) {
     87                     // translate by x,y for the canvas draws and the test target draws.
     88                     canvas->save();
     89                     canvas->translate(x, y);
     90                     const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y);
     91 
     92                     // rect to draw
     93                     SkRect renderRect = SkRect::MakeXYWH(0, 0, kRectSize, kRectSize);
     94 
     95                     GrPaint grPaint;
     96                     SkPaint skPaint;
     97                     if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
     98                         skPaint.setShader(fShader);
     99                     } else {
    100                         skPaint.setColor(kPaintColors[paintType]);
    101                     }
    102                     SkAssertResult(SkPaintToGrPaint(context, renderTargetContext->colorSpaceInfo(),
    103                                                     skPaint, viewMatrix, &grPaint));
    104 
    105                     GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
    106                     SkPMColor4f color = SkPMColor4f::FromBytes_RGBA(kColors[procColor]);
    107                     auto fp = GrConstColorProcessor::Make(color, mode);
    108 
    109                     grPaint.addColorFragmentProcessor(std::move(fp));
    110                     renderTargetContext->priv().testingOnly_addDrawOp(
    111                             GrFillRectOp::Make(context, std::move(grPaint), GrAAType::kNone,
    112                                                viewMatrix, renderRect));
    113 
    114                     // Draw labels for the input to the processor and the processor to the right of
    115                     // the test rect. The input label appears above the processor label.
    116                     SkFont labelFont;
    117                     labelFont.setTypeface(sk_tool_utils::create_portable_typeface());
    118                     labelFont.setEdging(SkFont::Edging::kAntiAlias);
    119                     labelFont.setSize(10.f);
    120                     SkPaint labelPaint;
    121                     labelPaint.setAntiAlias(true);
    122                     SkString inputLabel;
    123                     inputLabel.set("Input: ");
    124                     if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
    125                         inputLabel.append("gradient");
    126                     } else {
    127                         inputLabel.appendf("0x%08x", kPaintColors[paintType]);
    128                     }
    129                     SkString procLabel;
    130                     procLabel.printf("Proc: [0x%08x, %s]", kColors[procColor], kModeStrs[m]);
    131 
    132                     SkRect inputLabelBounds;
    133                     // get the bounds of the text in order to position it
    134                     labelFont.measureText(inputLabel.c_str(), inputLabel.size(),
    135                                           kUTF8_SkTextEncoding, &inputLabelBounds);
    136                     canvas->drawString(inputLabel, renderRect.fRight + kPad, -inputLabelBounds.fTop,
    137                                        labelFont, labelPaint);
    138                     // update the bounds to reflect the offset we used to draw it.
    139                     inputLabelBounds.offset(renderRect.fRight + kPad, -inputLabelBounds.fTop);
    140 
    141                     SkRect procLabelBounds;
    142                     labelFont.measureText(procLabel.c_str(), procLabel.size(),
    143                                           kUTF8_SkTextEncoding, &procLabelBounds);
    144                     canvas->drawString(procLabel, renderRect.fRight + kPad,
    145                                        inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop,
    146                                        labelFont, labelPaint);
    147                     procLabelBounds.offset(renderRect.fRight + kPad,
    148                                            inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop);
    149 
    150                     labelPaint.setStrokeWidth(0);
    151                     labelPaint.setStyle(SkPaint::kStroke_Style);
    152                     canvas->drawRect(renderRect, labelPaint);
    153 
    154                     canvas->restore();
    155 
    156                     // update x and y for the next test case.
    157                     SkScalar height = renderRect.height();
    158                     SkScalar width = SkTMax(inputLabelBounds.fRight, procLabelBounds.fRight);
    159                     maxW = SkTMax(maxW, width);
    160                     y += height + kPad;
    161                     if (y + height > kHeight) {
    162                         y = kPad;
    163                         x += maxW + kPad;
    164                         maxW = 0;
    165                     }
    166                 }
    167             }
    168         }
    169     }
    170 
    171 private:
    172     // Use this as a way of generating and input FP
    173     sk_sp<SkShader> fShader;
    174 
    175     static constexpr SkScalar       kPad = 10.f;
    176     static constexpr SkScalar       kRectSize = 20.f;
    177     static constexpr int            kWidth  = 820;
    178     static constexpr int            kHeight = 500;
    179 
    180     typedef GM INHERITED;
    181 };
    182 
    183 DEF_GM(return new ConstColorProcessor;)
    184 }
    185