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
2574b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-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;
3384b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com        SkCanvas* pictureCanvas = recorder.beginRecording(SkScalarRoundToInt(tileSize),
345fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org                                                          SkScalarRoundToInt(tileSize),
355fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org                                                          NULL, 0);
36c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawTile(pictureCanvas);
3774b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org        fPicture.reset(recorder.endRecording());
38c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
39c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        // Build a reference bitmap.
4074b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org        fBitmap.allocN32Pixels(SkScalarRoundToInt(tileSize), SkScalarRoundToInt(tileSize));
4174b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org        fBitmap.eraseColor(SK_ColorTRANSPARENT);
4274b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org        SkCanvas bitmapCanvas(fBitmap);
43c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawTile(&bitmapCanvas);
44c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
45c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
46c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.orgprotected:
47a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org    virtual uint32_t onGetFlags() const SK_OVERRIDE {
48a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org        return kSkipTiled_Flag;
49a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org    }
50a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org
51c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    virtual SkString onShortName() SK_OVERRIDE {
52c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        return SkString("pictureshader");
53c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
54c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
55c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    virtual SkISize onISize() SK_OVERRIDE {
56c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        return SkISize::Make(1400, 1250);
57c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
58c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
59c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
60c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(0, 0), 1, 1, 0);
61c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(0, fSceneSize * 6.4f), 1, 2, 0);
62c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, 0), 1, 1, 1);
63c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, fSceneSize * 6.4f), 1, 1, 2);
64c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 4.8f, 0), 2, 1, 0);
65c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 9.6f, 0), 2, 2, 0);
66c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
67c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
68c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.orgprivate:
69c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    void drawSceneColumn(SkCanvas* canvas, const SkPoint& pos, SkScalar scale, SkScalar localScale,
70c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org                         unsigned tileMode) {
71c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        SkMatrix ctm, localMatrix;
72c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
73c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.setTranslate(pos.x(), pos.y());
74c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.preScale(scale, scale);
75c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.setScale(localScale, localScale);
76c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawScene(canvas, ctm, localMatrix, tileMode);
77c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
78c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 1.2f * scale);
79c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.preScale(scale, scale);
80c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
81c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.preScale(localScale, localScale);
82c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawScene(canvas, ctm, localMatrix, tileMode);
83c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
84c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 2.4f * scale);
85c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.preScale(scale, scale);
86c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.setRotate(45);
87c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.preScale(localScale, localScale);
88c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawScene(canvas, ctm, localMatrix, tileMode);
89c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
90c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 3.6f * scale);
91c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.preScale(scale, scale);
92c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.setSkew(1, 0);
93c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.preScale(localScale, localScale);
94c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawScene(canvas, ctm, localMatrix, tileMode);
95c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
96c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 4.8f * scale);
97c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        ctm.preScale(scale, scale);
98c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
99c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.preRotate(45);
100c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        localMatrix.preScale(localScale, localScale);
101c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        this->drawScene(canvas, ctm, localMatrix, tileMode);
102c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
103c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
104c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    void drawTile(SkCanvas* canvas) {
105c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        SkPaint paint;
106c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setColor(SK_ColorGREEN);
107c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setStyle(SkPaint::kFill_Style);
108c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setAntiAlias(true);
109c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
110c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawCircle(fTileSize / 4, fTileSize / 4, fTileSize / 4, paint);
111c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawRect(SkRect::MakeXYWH(fTileSize / 2, fTileSize / 2,
112c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org                                          fTileSize / 2, fTileSize / 2), paint);
113c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
114c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setColor(SK_ColorRED);
115c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawLine(fTileSize / 2, fTileSize * 1 / 3,
116c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org                         fTileSize / 2, fTileSize * 2 / 3, paint);
117c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawLine(fTileSize * 1 / 3, fTileSize / 2,
118c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org                         fTileSize * 2 / 3, fTileSize / 2, paint);
119c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
120c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
121c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    void drawScene(SkCanvas* canvas, const SkMatrix& matrix, const SkMatrix& localMatrix,
122c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org                   unsigned tileMode) {
123c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        SkASSERT(tileMode < SK_ARRAY_COUNT(kTileConfigs));
124c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
125c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        SkPaint paint;
126c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setStyle(SkPaint::kFill_Style);
127c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        paint.setColor(SK_ColorLTGRAY);
128c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
129c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->save();
130c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->concat(matrix);
131c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
132c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawRect(SkRect::MakeXYWH(fSceneSize * 1.1f, 0, fSceneSize, fSceneSize), paint);
133c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
13474b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org        SkAutoTUnref<SkShader> pictureShader(SkShader::CreatePictureShader(
13574b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org                    fPicture,
13674b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org                    kTileConfigs[tileMode].tmx,
13774b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org                    kTileConfigs[tileMode].tmy,
13874b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org                    &localMatrix));
13974b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org        paint.setShader(pictureShader.get());
140c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
141c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
142c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->translate(fSceneSize * 1.1f, 0);
143c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
14474b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org        SkAutoTUnref<SkShader> bitmapShader(SkShader::CreateBitmapShader(
14574b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org                    fBitmap,
14674b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org                    kTileConfigs[tileMode].tmx,
14774b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org                    kTileConfigs[tileMode].tmy,
14874b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org                    &localMatrix));
14974b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org        paint.setShader(bitmapShader.get());
150c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
151c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
152c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org        canvas->restore();
153c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    }
154c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
155c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    SkScalar    fTileSize;
156c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    SkScalar    fSceneSize;
157c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
15874b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org    SkAutoTUnref<SkPicture> fPicture;
15974b8cb15e4fb330e8d10856f6620e8b92b39a9cecommit-bot@chromium.org    SkBitmap fBitmap;
160c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
161c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org    typedef GM INHERITED;
162c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org};
163c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org
164c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.orgDEF_GM( return SkNEW_ARGS(PictureShaderGM, (50, 100)); )
165