rrects.cpp revision c2f7824436d05da6e8514d06a54773538aace028
14e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com/*
24e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com * Copyright 2012 Google Inc.
34e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com *
44e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
54e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com * found in the LICENSE file.
64e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com */
74e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
84e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com#include "gm.h"
94e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com#include "SkRRect.h"
104e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
114e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.comnamespace skiagm {
124e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
134e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com///////////////////////////////////////////////////////////////////////////////
144e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
154e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.comclass RRectGM : public GM {
164e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.compublic:
174e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    RRectGM(bool doAA, bool doClip) : fDoAA(doAA), fDoClip(doClip) {
184e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        this->setBGColor(0xFFDDDDDD);
194e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        this->setUpRRects();
204e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    }
214e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
224e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.comprotected:
234e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    SkString onShortName() {
244e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        SkString name("rrect");
254e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        if (fDoClip) {
264e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com            name.append("_clip");
274e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        }
284e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        if (fDoAA) {
294e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com            name.append("_aa");
304e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        } else {
314e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com            name.append("_bw");
324e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        }
334e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
344e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        return name;
354e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    }
364e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
374e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    virtual SkISize onISize() { return make_isize(kImageWidth, kImageHeight); }
384e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
394e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    virtual void onDraw(SkCanvas* canvas) {
404e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
414e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        SkPaint paint;
424e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        // when clipping the AA is pushed into the clip operation
437a03d86a3d9adcb13432fbd82039725149487c97skia.committer@gmail.com        paint.setAntiAlias(fDoClip ? false : fDoAA);
444e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
454e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        static const SkRect kMaxTileBound = SkRect::MakeWH(SkIntToScalar(kTileX), SkIntToScalar(kTileY));
464e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
474e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        int curRRect = 0;
484e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        for (int y = 1; y < kImageHeight; y += kTileY) {
494e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com            for (int x = 1; x < kImageWidth; x += kTileX) {
504e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                if (curRRect >= kNumRRects) {
514e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                    break;
524e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                }
534e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                SkASSERT(kMaxTileBound.contains(fRRects[curRRect].getBounds()));
544e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
554e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                canvas->save();
564e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                    canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
574e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                    if (fDoClip) {
584e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                        canvas->clipRRect(fRRects[curRRect], SkRegion::kReplace_Op, fDoAA);
594e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                        canvas->drawRect(kMaxTileBound, paint);
604e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                    } else {
614e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                        canvas->drawRRect(fRRects[curRRect], paint);
624e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                    }
634e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                    ++curRRect;
644e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com                canvas->restore();
654e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com            }
664e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        }
674e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    }
684e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
694e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    void setUpRRects() {
707a03d86a3d9adcb13432fbd82039725149487c97skia.committer@gmail.com        // each RRect must fit in a 0x0 -> (kTileX-2)x(kTileY-2) block. These will be tiled across
714e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        // the screen in kTileX x kTileY tiles. The extra empty pixels on each side are for AA.
724e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
734e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        // simple cases
744e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        fRRects[0].setRect(SkRect::MakeWH(kTileX-2, kTileY-2));
754e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        fRRects[1].setOval(SkRect::MakeWH(kTileX-2, kTileY-2));
764e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        fRRects[2].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 10, 10);
77c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org        fRRects[3].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 10, 5);
78c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org        // small circular corners are an interesting test case for gpu clipping
79c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org        fRRects[4].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 1, 1);
80c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org        fRRects[5].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 0.5f, 0.5f);
81c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org        fRRects[6].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 0.2f, 0.2f);
824e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
834e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        // The first complex case needs special handling since it is a square
844e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        fRRects[kNumSimpleCases].setRectRadii(SkRect::MakeWH(kTileY-2, kTileY-2), gRadii[0]);
85f6100c8b1aba89027cf74da8a324a744fd1d53famike@reedtribe.org        for (size_t i = 1; i < SK_ARRAY_COUNT(gRadii); ++i) {
864e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com            fRRects[kNumSimpleCases+i].setRectRadii(SkRect::MakeWH(kTileX-2, kTileY-2), gRadii[i]);
874e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com        }
884e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    }
894e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
904e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.comprivate:
914e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    bool fDoAA;
924e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    bool fDoClip;   // use clipRRect & drawRect instead of drawRRect
934e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
944e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    static const int kImageWidth = 640;
954e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    static const int kImageHeight = 480;
964e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
974e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    static const int kTileX = 80;
984e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    static const int kTileY = 40;
994e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
100c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    static const int kNumSimpleCases = 7;
1014e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    static const int kNumComplexCases = 19;
1025683d42d3aa9c0b2a680a1c4766205a06565f196robertphillips@google.com    static const SkVector gRadii[kNumComplexCases][4];
1034e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1044e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    static const int kNumRRects = kNumSimpleCases + kNumComplexCases;
1054e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    SkRRect fRRects[kNumRRects];
1064e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1074e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    typedef GM INHERITED;
1084e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com};
1094e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1104e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com// Radii for the various test cases. Order is UL, UR, LR, LL
1114e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.comconst SkVector RRectGM::gRadii[kNumComplexCases][4] = {
1124e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    // a circle
1134e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { kTileY, kTileY }, { kTileY, kTileY }, { kTileY, kTileY }, { kTileY, kTileY } },
1144e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1154e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    // odd ball cases
1164e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 8, 8 }, { 32, 32 }, { 8, 8 }, { 32, 32 } },
1174e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 16, 8 }, { 8, 16 }, { 16, 8 }, { 8, 16 } },
1184e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 16, 16 }, { 8, 8 }, { 32, 32 } },
1194e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1204e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    // UL
1214e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 30, 30 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
1224e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 30, 15 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
1234e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 15, 30 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
1244e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1254e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    // UR
1264e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 30, 30 }, { 0, 0 }, { 0, 0 } },
1274e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 30, 15 }, { 0, 0 }, { 0, 0 } },
1284e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 15, 30 }, { 0, 0 }, { 0, 0 } },
1294e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1304e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    // LR
1314e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 0, 0 }, { 30, 30 }, { 0, 0 } },
1324e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 0, 0 }, { 30, 15 }, { 0, 0 } },
1334e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 0, 0 }, { 15, 30 }, { 0, 0 } },
1344e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1354e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    // LL
1364e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 30 } },
1374e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 15 } },
1384e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 15, 30 } },
1394e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1404e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    // over-sized radii
1414e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 100, 400 }, { 0, 0 }, { 0, 0 } },
1424e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 0, 0 }, { 400, 400 }, { 0, 0 }, { 0, 0 } },
1434e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com    { { 400, 400 }, { 400, 400 }, { 400, 400 }, { 400, 400 } },
1444e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com};
1454e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1464e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com///////////////////////////////////////////////////////////////////////////////
1474e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1484e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.comDEF_GM( return new RRectGM(false, false); )
1494e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.comDEF_GM( return new RRectGM(true, false); )
1504e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.comDEF_GM( return new RRectGM(false, true); )
1514e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.comDEF_GM( return new RRectGM(true, true); )
1524e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com
1534e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com}
154