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