drawminibitmaprect.cpp revision 2ad1aa67c6894696cdd65ec56057f81031d1c24a
12ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt/*
22ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt * Copyright 2015 Google Inc.
32ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt *
42ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt * Use of this source code is governed by a BSD-style license that can be
52ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt * found in the LICENSE file.
62ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt */
72ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
82ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt#include "gm.h"
92ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt#include "SkColorPriv.h"
102ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt#include "SkGradientShader.h"
112ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt#include "SkImage.h"
122ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt#include "SkRandom.h"
132ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt#include "SkShader.h"
142ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt#include "SkSurface.h"
152ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
162ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualittstatic SkImage* makebm(SkCanvas* caller, int w, int h) {
172ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);
182ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkAutoTUnref<SkSurface> surface(caller->newSurface(info));
1996fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == surface) {
202ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        surface.reset(SkSurface::NewRaster(info));
212ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    }
222ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkCanvas* canvas = surface->getCanvas();
232ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
242ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    const SkScalar wScalar = SkIntToScalar(w);
252ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    const SkScalar hScalar = SkIntToScalar(h);
262ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
272ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    const SkPoint     pt = { wScalar / 2, hScalar / 2 };
282ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
292ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    const SkScalar    radius = 4 * SkMaxScalar(wScalar, hScalar);
302ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
312ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    static const SkColor     colors[] = { SK_ColorRED, SK_ColorYELLOW,
322ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                                          SK_ColorGREEN, SK_ColorMAGENTA,
332ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                                          SK_ColorBLUE, SK_ColorCYAN,
342ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                                          SK_ColorRED};
352ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
362ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    static const SkScalar    pos[] = {0,
372ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                                      SK_Scalar1 / 6,
382ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                                      2 * SK_Scalar1 / 6,
392ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                                      3 * SK_Scalar1 / 6,
402ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                                      4 * SK_Scalar1 / 6,
412ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                                      5 * SK_Scalar1 / 6,
422ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                                      SK_Scalar1};
432ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
442ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkASSERT(SK_ARRAY_COUNT(colors) == SK_ARRAY_COUNT(pos));
452ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkPaint     paint;
462ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkRect rect = SkRect::MakeWH(wScalar, hScalar);
472ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkMatrix mat = SkMatrix::I();
482ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    for (int i = 0; i < 4; ++i) {
492ad1aa67c6894696cdd65ec56057f81031d1c24areed        paint.setShader(SkGradientShader::MakeRadial(
502ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        pt, radius,
512ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        colors, pos,
522ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        SK_ARRAY_COUNT(colors),
532ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        SkShader::kRepeat_TileMode,
542ad1aa67c6894696cdd65ec56057f81031d1c24areed                        0, &mat));
552ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        canvas->drawRect(rect, paint);
562ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        rect.inset(wScalar / 8, hScalar / 8);
572ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        mat.postScale(SK_Scalar1 / 4, SK_Scalar1 / 4);
582ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    }
592ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    return surface->newImageSnapshot();
602ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt}
612ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
622ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualittstatic const int gSize = 1024;
632ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualittstatic const int gSurfaceSize = 2048;
642ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
652ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt// This GM calls drawImageRect several times using the same texture. This is
662ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt// intended to exercise batching of these calls.
672ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualittclass DrawMiniBitmapRectGM : public skiagm::GM {
682ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualittpublic:
692ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    DrawMiniBitmapRectGM(bool antiAlias) : fAA(antiAlias) {
702ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        fName.set("drawminibitmaprect");
712ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        if (fAA) {
722ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt            fName.appendf("_aa");
732ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        }
742ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    }
752ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
762ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualittprotected:
772ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkString onShortName() override { return fName; }
782ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
792ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkISize onISize() override { return SkISize::Make(gSize, gSize); }
802ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
812ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    void onDraw(SkCanvas* canvas) override {
8296fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == fImage) {
832ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt            fImage.reset(makebm(canvas, gSurfaceSize, gSurfaceSize));
842ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        }
852ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
862ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        const SkRect dstRect = { 0, 0, SkIntToScalar(64), SkIntToScalar(64)};
872ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        static const int kMaxSrcRectSize = 1 << (SkNextLog2(gSurfaceSize) + 2);
882ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
892ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        static const int kPadX = 30;
902ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        static const int kPadY = 40;
912ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
922ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        int rowCount = 0;
932ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        canvas->translate(SkIntToScalar(kPadX), SkIntToScalar(kPadY));
942ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        canvas->save();
952ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        SkRandom random;
962ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
972ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        SkPaint paint;
982ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        paint.setAntiAlias(fAA);
992ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        for (int w = 1; w <= kMaxSrcRectSize; w *= 3) {
1002ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt            for (int h = 1; h <= kMaxSrcRectSize; h *= 3) {
1012ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
1022ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                const SkIRect srcRect =
1032ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        SkIRect::MakeXYWH((gSurfaceSize - w) / 2, (gSurfaceSize - h) / 2, w, h);
1042ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                canvas->save();
1052ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                switch (random.nextU() % 3) {
1062ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                    case 0:
1072ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        canvas->rotate(random.nextF() * 10.f);
1082ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        break;
1092ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                    case 1:
1102ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        canvas->rotate(-random.nextF() * 10.f);
1112ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        break;
1122ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                    case 2:
1132ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        // rect stays rect
1142ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                        break;
1152ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                }
1162ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                canvas->drawImageRect(fImage, srcRect, dstRect, &paint,
1172ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                                      SkCanvas::kFast_SrcRectConstraint);
1182ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                canvas->restore();
1192ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
1202ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                canvas->translate(dstRect.width() + SK_Scalar1 * kPadX, 0);
1212ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                ++rowCount;
1222ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                if ((dstRect.width() + 2 * kPadX) * rowCount > gSize) {
1232ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                    canvas->restore();
1242ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                    canvas->translate(0, dstRect.height() + SK_Scalar1 * kPadY);
1252ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                    canvas->save();
1262ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                    rowCount = 0;
1272ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt                }
1282ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt            }
1292ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        }
1302ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt        canvas->restore();
1312ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    }
1322ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
1332ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualittprivate:
1342ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    bool                  fAA;
1352ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkAutoTUnref<SkImage> fImage;
1362ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    SkString              fName;
1372ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
1382ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt    typedef skiagm::GM INHERITED;
1392ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt};
1402ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
1412ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualittDEF_GM( return new DrawMiniBitmapRectGM(true); )
1422ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualittDEF_GM( return new DrawMiniBitmapRectGM(false); )
1432ba70995f8a69285dd35968aa3a3e19d5429bdd0joshualitt
144