1c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org/*
2c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org * Copyright 2014 Google Inc.
3c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org *
4c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
5c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org * found in the LICENSE file.
6c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org */
7c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
8c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org#include "gm.h"
9c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
10c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org#include "SkBitmap.h"
11c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org#include "SkPaint.h"
12c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org#include "SkPicture.h"
13770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com#include "SkPictureRecorder.h"
14c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org#include "SkShader.h"
15c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
16c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.orgstatic struct {
17c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    SkShader::TileMode tmx;
18c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    SkShader::TileMode tmy;
19c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org} kTileConfigs[] = {
20c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    { SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode },
21c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    { SkShader::kRepeat_TileMode, SkShader::kClamp_TileMode  },
22c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    { SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode },
23c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org};
24c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
255aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.orgclass PictureShaderGM : public skiagm::GM {
26c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.orgpublic:
27c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    PictureShaderGM(SkScalar tileSize, SkScalar sceneSize)
28c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        : fTileSize(tileSize)
29c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        , fSceneSize(sceneSize) {
30c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
31c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        // Build the picture.
3284b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com        SkPictureRecorder recorder;
33a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips        SkCanvas* pictureCanvas = recorder.beginRecording(tileSize, tileSize, NULL, 0);
34c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawTile(pictureCanvas);
355aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org        fPicture.reset(recorder.endRecording());
36c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
37c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        // Build a reference bitmap.
38a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips        fBitmap.allocN32Pixels(SkScalarCeilToInt(tileSize), SkScalarCeilToInt(tileSize));
395aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org        fBitmap.eraseColor(SK_ColorTRANSPARENT);
405aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org        SkCanvas bitmapCanvas(fBitmap);
41c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawTile(&bitmapCanvas);
42c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
43c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
44c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.orgprotected:
45a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org    virtual uint32_t onGetFlags() const SK_OVERRIDE {
46a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org        return kSkipTiled_Flag;
47a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org    }
48a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org
49c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    virtual SkString onShortName() SK_OVERRIDE {
50c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        return SkString("pictureshader");
51c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
52c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
53c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    virtual SkISize onISize() SK_OVERRIDE {
54c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        return SkISize::Make(1400, 1250);
55c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
56c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
57c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
58c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(0, 0), 1, 1, 0);
59c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(0, fSceneSize * 6.4f), 1, 2, 0);
60c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, 0), 1, 1, 1);
61c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, fSceneSize * 6.4f), 1, 1, 2);
62c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 4.8f, 0), 2, 1, 0);
63c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 9.6f, 0), 2, 2, 0);
64c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
65c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
66c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.orgprivate:
67c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    void drawSceneColumn(SkCanvas* canvas, const SkPoint& pos, SkScalar scale, SkScalar localScale,
68c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org                         unsigned tileMode) {
69c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        SkMatrix ctm, localMatrix;
70c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
71c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.setTranslate(pos.x(), pos.y());
72c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.preScale(scale, scale);
73c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.setScale(localScale, localScale);
74c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawScene(canvas, ctm, localMatrix, tileMode);
75c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
76c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 1.2f * scale);
77c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.preScale(scale, scale);
78c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
79c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.preScale(localScale, localScale);
80c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawScene(canvas, ctm, localMatrix, tileMode);
81c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
82c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 2.4f * scale);
83c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.preScale(scale, scale);
84c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.setRotate(45);
85c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.preScale(localScale, localScale);
86c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawScene(canvas, ctm, localMatrix, tileMode);
87c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
88c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 3.6f * scale);
89c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.preScale(scale, scale);
90c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.setSkew(1, 0);
91c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.preScale(localScale, localScale);
92c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawScene(canvas, ctm, localMatrix, tileMode);
93c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
94c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 4.8f * scale);
95c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.preScale(scale, scale);
96c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
97c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.preRotate(45);
98c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.preScale(localScale, localScale);
99c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawScene(canvas, ctm, localMatrix, tileMode);
100c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
101c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
102c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    void drawTile(SkCanvas* canvas) {
103c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        SkPaint paint;
104c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setColor(SK_ColorGREEN);
105c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setStyle(SkPaint::kFill_Style);
106c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setAntiAlias(true);
107c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
108c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawCircle(fTileSize / 4, fTileSize / 4, fTileSize / 4, paint);
109c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawRect(SkRect::MakeXYWH(fTileSize / 2, fTileSize / 2,
110c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org                                          fTileSize / 2, fTileSize / 2), paint);
111c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
112c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setColor(SK_ColorRED);
113c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawLine(fTileSize / 2, fTileSize * 1 / 3,
114c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org                         fTileSize / 2, fTileSize * 2 / 3, paint);
115c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawLine(fTileSize * 1 / 3, fTileSize / 2,
116c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org                         fTileSize * 2 / 3, fTileSize / 2, paint);
117c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
118c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
119c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    void drawScene(SkCanvas* canvas, const SkMatrix& matrix, const SkMatrix& localMatrix,
120c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org                   unsigned tileMode) {
121c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        SkASSERT(tileMode < SK_ARRAY_COUNT(kTileConfigs));
122c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
123c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        SkPaint paint;
124c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setStyle(SkPaint::kFill_Style);
125c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setColor(SK_ColorLTGRAY);
126c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
127c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->save();
128c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->concat(matrix);
129c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
130c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawRect(SkRect::MakeXYWH(fSceneSize * 1.1f, 0, fSceneSize, fSceneSize), paint);
131c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
1325aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org        SkAutoTUnref<SkShader> pictureShader(SkShader::CreatePictureShader(
1335aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org                    fPicture,
1345aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org                    kTileConfigs[tileMode].tmx,
1355aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org                    kTileConfigs[tileMode].tmy,
136b5f7826c51af2862aebcabe61e1ba684f925e488fmalita                    &localMatrix,
137b5f7826c51af2862aebcabe61e1ba684f925e488fmalita                    NULL));
1385aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org        paint.setShader(pictureShader.get());
139c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
140c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
141c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->translate(fSceneSize * 1.1f, 0);
142c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
1435aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org        SkAutoTUnref<SkShader> bitmapShader(SkShader::CreateBitmapShader(
1445aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org                    fBitmap,
1455aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org                    kTileConfigs[tileMode].tmx,
1465aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org                    kTileConfigs[tileMode].tmy,
1475aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org                    &localMatrix));
1485aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org        paint.setShader(bitmapShader.get());
149c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
150c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
151c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->restore();
152c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
153c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
154c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    SkScalar    fTileSize;
155c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    SkScalar    fSceneSize;
156c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
1575aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org    SkAutoTUnref<SkPicture> fPicture;
1585aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org    SkBitmap fBitmap;
159c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
160c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    typedef GM INHERITED;
161c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org};
162c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
163c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.orgDEF_GM( return SkNEW_ARGS(PictureShaderGM, (50, 100)); )
164