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