1d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed/*
2d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed * Copyright 2012 Google Inc.
3d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed *
4d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed * Use of this source code is governed by a BSD-style license that can be
5d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed * found in the LICENSE file.
6d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed */
7d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
8d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed#include "gm.h"
9d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed#include "SkCanvas.h"
10d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed#include "SkShader.h"
11d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed#include "SkBlurMaskFilter.h"
12d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
13d7127e7b835b4c5d4767ee9d8794e9865c81f1acreednamespace skiagm {
14d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
15d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed/**
16d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed * Stress test the GPU samplers by rendering a textured glyph with a mask and
17d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed * an AA clip
18d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed */
19d7127e7b835b4c5d4767ee9d8794e9865c81f1acreedclass SamplerStressGM : public GM {
20d7127e7b835b4c5d4767ee9d8794e9865c81f1acreedpublic:
21d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    SamplerStressGM()
22d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    : fTextureCreated(false)
23d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    , fShader(NULL)
24d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    , fMaskFilter(NULL) {
25d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    }
26d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
27d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    virtual ~SamplerStressGM() {
28d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    }
29d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
30d7127e7b835b4c5d4767ee9d8794e9865c81f1acreedprotected:
31d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    virtual uint32_t onGetFlags() const SK_OVERRIDE {
32d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        return kSkipTiled_Flag;
33d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    }
34d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
35d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    virtual SkString onShortName() {
36d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        return SkString("gpusamplerstress");
37d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    }
38d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
39d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    virtual SkISize onISize() {
40d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        return SkISize::Make(640, 480);
41d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    }
42d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
43d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    /**
44d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed     * Create a red & green stripes on black texture
45d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed     */
46d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    void createTexture() {
47d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        if (fTextureCreated) {
48d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed            return;
49d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        }
50d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
51d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        static const int xSize = 16;
52d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        static const int ySize = 16;
53d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
54d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        fTexture.allocN32Pixels(xSize, ySize);
55d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        SkPMColor* addr = fTexture.getAddr32(0, 0);
56d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
57d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        for (int y = 0; y < ySize; ++y) {
58d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed            for (int x = 0; x < xSize; ++x) {
59d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorBLACK);
60d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
61d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                if ((y % 5) == 0) {
62d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                    addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorRED);
63d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                }
64d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                if ((x % 7) == 0) {
65d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                    addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorGREEN);
66d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                }
67d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed            }
68d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        }
69d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
70d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        fTextureCreated = true;
71d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    }
72d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
73d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    void createShader() {
7449f085dddff10473b6ebf832a974288300224e60bsalomon        if (fShader.get()) {
75d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed            return;
76d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        }
77d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
78d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        createTexture();
79d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
80d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        fShader.reset(SkShader::CreateBitmapShader(fTexture,
81d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                                                   SkShader::kRepeat_TileMode,
82d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                                                   SkShader::kRepeat_TileMode));
83d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    }
84d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
85d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    void createMaskFilter() {
8649f085dddff10473b6ebf832a974288300224e60bsalomon        if (fMaskFilter.get()) {
87d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed            return;
88d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        }
89d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
90d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        const SkScalar sigma = 1;
91d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        fMaskFilter.reset(SkBlurMaskFilter::Create(kNormal_SkBlurStyle, sigma));
92d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    }
93d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
94d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    virtual void onDraw(SkCanvas* canvas) {
95d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
96d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        createShader();
97d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        createMaskFilter();
98d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
99d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        canvas->save();
100d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
101d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        // draw a letter "M" with a green & red striped texture and a
102d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        // stipple mask with a round rect soft clip
103d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        SkPaint paint;
104d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        paint.setAntiAlias(true);
105d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        paint.setTextSize(72);
106d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        paint.setShader(fShader.get());
107d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        paint.setMaskFilter(fMaskFilter.get());
108d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
109d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        SkRect temp;
110d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        temp.set(SkIntToScalar(115),
111d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                 SkIntToScalar(75),
112d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                 SkIntToScalar(144),
113d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                 SkIntToScalar(110));
114d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
115d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        SkPath path;
116d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        path.addRoundRect(temp, SkIntToScalar(5), SkIntToScalar(5));
117d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
118d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        canvas->clipPath(path, SkRegion::kReplace_Op, true); // AA is on
119d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
120d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        canvas->drawText("M", 1,
121d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                         SkIntToScalar(100), SkIntToScalar(100),
122d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                         paint);
123d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
124d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        canvas->restore();
125d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
126d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        // Now draw stroked versions of the "M" and the round rect so we can
127d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        // see what is going on
128d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        SkPaint paint2;
129d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        paint2.setColor(SK_ColorBLACK);
130d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        paint2.setAntiAlias(true);
131d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        paint2.setTextSize(72);
132d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        paint2.setStyle(SkPaint::kStroke_Style);
133d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        paint2.setStrokeWidth(1);
134d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        canvas->drawText("M", 1,
135d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                         SkIntToScalar(100), SkIntToScalar(100),
136d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed                         paint2);
137d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
138d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        paint2.setColor(SK_ColorGRAY);
139d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
140d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed        canvas->drawPath(path, paint2);
141d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    }
142d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
143d7127e7b835b4c5d4767ee9d8794e9865c81f1acreedprivate:
144d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    SkBitmap      fTexture;
145d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    bool          fTextureCreated;
146d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    SkAutoTUnref<SkShader>     fShader;
147d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    SkAutoTUnref<SkMaskFilter> fMaskFilter;
148d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
149d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed    typedef GM INHERITED;
150d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed};
151d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
152d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed//////////////////////////////////////////////////////////////////////////////
153d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
154d7127e7b835b4c5d4767ee9d8794e9865c81f1acreedstatic GM* MyFactory(void*) { return new SamplerStressGM; }
155d7127e7b835b4c5d4767ee9d8794e9865c81f1acreedstatic GMRegistry reg(MyFactory);
156d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed
157d7127e7b835b4c5d4767ee9d8794e9865c81f1acreed}
158