1fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
2fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com/*
3fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com * Copyright 2011 Google Inc.
4fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com *
5fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
6fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com * found in the LICENSE file.
7fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com */
8fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com#include "gm.h"
9b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com#include "SkBlurMask.h"
107d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com#include "SkBlurMaskFilter.h"
11b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com#include "SkColorPriv.h"
12fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com#include "SkGradientShader.h"
13b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com#include "SkShader.h"
14fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
15fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.comnamespace skiagm {
16fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
177d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.comstatic SkBitmap make_chessbm(int w, int h) {
187d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com    SkBitmap bm;
19eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com    bm.allocN32Pixels(w, h);
207d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com
217d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com    for (int y = 0; y < bm.height(); y++) {
227d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com        uint32_t* p = bm.getAddr32(0, y);
237d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com        for (int x = 0; x < bm.width(); x++) {
247d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            p[x] = ((x + y) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
257d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com        }
267d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com    }
277d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com    bm.unlockPixels();
287d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com    return bm;
297d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com}
307d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com
31dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.orgstatic void makebm(SkBitmap* bm, int w, int h) {
32dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org    bm->allocN32Pixels(w, h);
33dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com    bm->eraseColor(SK_ColorTRANSPARENT);
34fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
35fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkCanvas    canvas(*bm);
36fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
37fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkScalar wScalar = SkIntToScalar(w);
38fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkScalar hScalar = SkIntToScalar(h);
39fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
40fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkPoint     pt = { wScalar / 2, hScalar / 2 };
41fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
42fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkScalar    radius = 4 * SkMaxScalar(wScalar, hScalar);
43fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
44fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkColor     colors[] = { SK_ColorRED, SK_ColorYELLOW,
45fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                             SK_ColorGREEN, SK_ColorMAGENTA,
46fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                             SK_ColorBLUE, SK_ColorCYAN,
47fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                             SK_ColorRED};
48fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
49fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkScalar    pos[] = {0,
50fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                         SK_Scalar1 / 6,
51fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                         2 * SK_Scalar1 / 6,
52fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                         3 * SK_Scalar1 / 6,
53fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                         4 * SK_Scalar1 / 6,
54fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                         5 * SK_Scalar1 / 6,
55fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                         SK_Scalar1};
56fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
57fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkPaint     paint;
58fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkRect rect = SkRect::MakeWH(wScalar, hScalar);
59fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkMatrix mat = SkMatrix::I();
60fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    for (int i = 0; i < 4; ++i) {
619c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org        paint.setShader(SkGradientShader::CreateRadial(
629c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                        pt, radius,
639c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                        colors, pos,
649c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                        SK_ARRAY_COUNT(colors),
659c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                        SkShader::kRepeat_TileMode,
6683f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                        0, &mat))->unref();
67fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        canvas.drawRect(rect, paint);
68fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        rect.inset(wScalar / 8, hScalar / 8);
69fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        mat.postScale(SK_Scalar1 / 4, SK_Scalar1 / 4);
70fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    }
715d415079fcd955e8b96f9b942e71dfc517819bd2commit-bot@chromium.org    // Let backends know we won't change this, so they don't have to deep copy it defensively.
725d415079fcd955e8b96f9b942e71dfc517819bd2commit-bot@chromium.org    bm->setImmutable();
73fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com}
74fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
75fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.comstatic const int gSize = 1024;
76fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
77fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.comclass DrawBitmapRectGM : public GM {
78fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.compublic:
79fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    DrawBitmapRectGM() {
80fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    }
81fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
82fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkBitmap    fLargeBitmap;
83fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
84fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.comprotected:
85fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    SkString onShortName() {
86fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        return SkString("drawbitmaprect");
87fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    }
88ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
89f539318f0d3dba743ec1886d5d9df0fb1be628a1tfarina    SkISize onISize() { return SkISize::Make(gSize, gSize); }
90ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
91fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    virtual void onDraw(SkCanvas* canvas) {
92fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        static const int kBmpSize = 2048;
93fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        if (fLargeBitmap.isNull()) {
94dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org            makebm(&fLargeBitmap, kBmpSize, kBmpSize);
95fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        }
96663515bc59325092c4e47f5189782bd6fcd0586avandebo@chromium.org        SkRect dstRect = { 0, 0, SkIntToScalar(64), SkIntToScalar(64)};
97fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        static const int kMaxSrcRectSize = 1 << (SkNextLog2(kBmpSize) + 2);
98fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
99fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        static const int kPadX = 30;
100fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        static const int kPadY = 40;
101fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        SkPaint paint;
102fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        paint.setAlpha(0x20);
103fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        canvas->drawBitmapRect(fLargeBitmap, NULL,
104fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                               SkRect::MakeWH(gSize * SK_Scalar1,
105fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                                              gSize * SK_Scalar1),
106fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                               &paint);
107fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        canvas->translate(SK_Scalar1 * kPadX / 2,
108fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                          SK_Scalar1 * kPadY / 2);
109fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        SkPaint blackPaint;
110fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        SkScalar titleHeight = SK_Scalar1 * 24;
111fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        blackPaint.setColor(SK_ColorBLACK);
112fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        blackPaint.setTextSize(titleHeight);
113fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        blackPaint.setAntiAlias(true);
114fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        SkString title;
115fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        title.printf("Bitmap size: %d x %d", kBmpSize, kBmpSize);
116fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        canvas->drawText(title.c_str(), title.size(), 0,
117fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                         titleHeight, blackPaint);
118fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
119fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        canvas->translate(0, SK_Scalar1 * kPadY / 2  + titleHeight);
120fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        int rowCount = 0;
121fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        canvas->save();
122fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        for (int w = 1; w <= kMaxSrcRectSize; w *= 4) {
123fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com            for (int h = 1; h <= kMaxSrcRectSize; h *= 4) {
124fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
125fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                SkIRect srcRect = SkIRect::MakeXYWH((kBmpSize - w) / 2,
126fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                                                    (kBmpSize - h) / 2,
127fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                                                    w, h);
128fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                canvas->drawBitmapRect(fLargeBitmap, &srcRect, dstRect);
129fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
130fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                SkString label;
131fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                label.appendf("%d x %d", w, h);
132fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                blackPaint.setAntiAlias(true);
133fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                blackPaint.setStyle(SkPaint::kFill_Style);
134fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                blackPaint.setTextSize(SK_Scalar1 * 10);
135fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                SkScalar baseline = dstRect.height() +
136fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                                    blackPaint.getTextSize() + SK_Scalar1 * 3;
137fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                canvas->drawText(label.c_str(), label.size(),
138fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                                    0, baseline,
139fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                                    blackPaint);
140fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                blackPaint.setStyle(SkPaint::kStroke_Style);
141fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                blackPaint.setStrokeWidth(SK_Scalar1);
142fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                blackPaint.setAntiAlias(false);
143fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                canvas->drawRect(dstRect, blackPaint);
144fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
145fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                canvas->translate(dstRect.width() + SK_Scalar1 * kPadX, 0);
146fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                ++rowCount;
147fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                if ((dstRect.width() + kPadX) * rowCount > gSize) {
148fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                    canvas->restore();
149fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                    canvas->translate(0, dstRect.height() + SK_Scalar1 * kPadY);
150fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                    canvas->save();
151fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                    rowCount = 0;
152fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                }
153fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com            }
154fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com        }
1557d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com
1567d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com        {
1577d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            // test the following code path:
1587d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            // SkGpuDevice::drawPath() -> SkGpuDevice::drawWithMaskFilter()
1597d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            SkIRect srcRect;
1607d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            SkPaint paint;
1617d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            SkBitmap bm;
1627d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com
1637d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            bm = make_chessbm(5, 5);
1644469938e92d779dff05e745559e67907bbf21e78reed@google.com            paint.setFilterLevel(SkPaint::kLow_FilterLevel);
1657d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com
1667d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            srcRect.setXYWH(1, 1, 3, 3);
1677d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            SkMaskFilter* mf = SkBlurMaskFilter::Create(
168e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org                kNormal_SkBlurStyle,
169b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com                SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)),
1707d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com                SkBlurMaskFilter::kHighQuality_BlurFlag |
1717d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com                SkBlurMaskFilter::kIgnoreTransform_BlurFlag);
1727d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            paint.setMaskFilter(mf)->unref();
1737d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com            canvas->drawBitmapRect(bm, &srcRect, dstRect, &paint);
1747d30a213156bcf50d05dbf60401cc7ab98d286c6bsalomon@google.com        }
175fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    }
176fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
177fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.comprivate:
178fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    typedef GM INHERITED;
179fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com};
180fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
181fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com//////////////////////////////////////////////////////////////////////////////
182fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
183fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.comstatic GM* MyFactory(void*) { return new DrawBitmapRectGM; }
184fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.comstatic GMRegistry reg(MyFactory);
185fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com}
186