1c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com/*
2c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com * Copyright 2012 Google Inc.
3c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com *
4c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
5c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com * found in the LICENSE file.
6c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com */
7c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
8c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com#include "gm.h"
9c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com#include "SkBitmapProcShader.h"
10c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com#include "SkColorFilter.h"
11c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com#include "SkGradientShader.h"
12c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
13c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com#define WIDTH 512
14c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com#define HEIGHT 1024
15c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
16c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comnamespace skiagm {
17c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
18c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com// Using gradients because GPU doesn't currently have an implementation of SkColorShader (duh!)
19c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comstatic SkShader* make_color_shader(SkColor color) {
20c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    static const SkPoint kPts[] = {{0, 0}, {1, 1}};
21c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    SkColor colors[] = {color, color};
22c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
23c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    return SkGradientShader::CreateLinear(kPts, colors, NULL, 2, SkShader::kClamp_TileMode);
24c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com}
25c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
26c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comstatic SkShader* make_solid_shader() {
27c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    return make_color_shader(SkColorSetARGB(0xFF, 0x40, 0x80, 0x20));
28c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com}
29c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
30c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comstatic SkShader* make_transparent_shader() {
31c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    return make_color_shader(SkColorSetARGB(0x80, 0x10, 0x70, 0x20));
32c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com}
33c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
34c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comstatic SkShader* make_trans_black_shader() {
35c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    return make_color_shader(0x0);
36c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com}
37c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
38c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com// draws a background behind each test rect to see transparency
39c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comstatic SkShader* make_bg_shader(int checkSize) {
40c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    SkBitmap bmp;
41eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com    bmp.allocN32Pixels(2 * checkSize, 2 * checkSize);
42c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    SkCanvas canvas(bmp);
43c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    canvas.clear(0xFF800000);
44c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    SkPaint paint;
45c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    paint.setColor(0xFF000080);
46c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    SkRect rect0 = SkRect::MakeXYWH(0, 0,
47c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                                    SkIntToScalar(checkSize), SkIntToScalar(checkSize));
48c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    SkRect rect1 = SkRect::MakeXYWH(SkIntToScalar(checkSize), SkIntToScalar(checkSize),
49c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                                    SkIntToScalar(checkSize), SkIntToScalar(checkSize));
50c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    canvas.drawRect(rect1, paint);
51c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    canvas.drawRect(rect0, paint);
52c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    return SkNEW_ARGS(SkBitmapProcShader, (bmp, SkShader::kRepeat_TileMode,
53c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                                                SkShader::kRepeat_TileMode));
54c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com}
55c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
56c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comclass ModeColorFilterGM : public GM {
57c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.compublic:
58c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    ModeColorFilterGM() {
59c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        this->setBGColor(0xFF303030);
60c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    }
61c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
62c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comprotected:
63c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    virtual SkString onShortName() {
64c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        return SkString("modecolorfilters");
65c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    }
66c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
67c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    virtual SkISize onISize() {
68f539318f0d3dba743ec1886d5d9df0fb1be628a1tfarina        return SkISize::Make(WIDTH, HEIGHT);
69c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    }
70c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
71c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    virtual void onDraw(SkCanvas* canvas) {
72c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        // size of rect for each test case
73c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        static const int kRectWidth  = 20;
7424c29d91caa4eaa31f9e77bad614627a252df35eskia.committer@gmail.com        static const int kRectHeight = 20;
75c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
76c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        static const int kCheckSize  = 10;
77c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
78c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        if (!fBmpShader) {
79c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            fBmpShader.reset(make_bg_shader(kCheckSize));
80c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        }
81c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        SkPaint bgPaint;
82c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        bgPaint.setShader(fBmpShader);
83c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        bgPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
84c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
85c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        SkShader* shaders[] = {
86c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            NULL,                                   // use a paint color instead of a shader
87c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            make_solid_shader(),
88c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            make_transparent_shader(),
89c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            make_trans_black_shader(),
90c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        };
91c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
92c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        // used without shader
93c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        SkColor colors[] = {
94c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF),
95c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkColorSetARGB(0xFF, 0x00, 0x00, 0x00),
96c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkColorSetARGB(0x00, 0x00, 0x00, 0x00),
97c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkColorSetARGB(0xFF, 0x10, 0x20, 0x40),
98c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkColorSetARGB(0xA0, 0x20, 0x30, 0x90),
99c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        };
100c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
101c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        // used with shaders
102c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        SkColor alphas[] = {0xFFFFFFFF, 0x80808080};
10324c29d91caa4eaa31f9e77bad614627a252df35eskia.committer@gmail.com
104c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        SkXfermode::Mode modes[]  = { // currently just doing the Modes expressible as Coeffs
105c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kClear_Mode,
106c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kSrc_Mode,
107c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kDst_Mode,
108c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kSrcOver_Mode,
109c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kDstOver_Mode,
110c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kSrcIn_Mode,
111c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kDstIn_Mode,
112c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kSrcOut_Mode,
113c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kDstOut_Mode,
114c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kSrcATop_Mode,
115c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kDstATop_Mode,
116c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kXor_Mode,
117c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkXfermode::kPlus_Mode,
1188d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com            SkXfermode::kModulate_Mode,
119c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        };
120c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
121c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        SkPaint paint;
122c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        int idx = 0;
123c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        static const int kRectsPerRow = SkMax32(this->getISize().fWidth / kRectWidth, 1);
124c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        for (size_t cfm = 0; cfm < SK_ARRAY_COUNT(modes); ++cfm) {
12593f03324189f211db95c312b3cb08b435cc5ac34robertphillips@google.com            for (size_t cfc = 0; cfc < SK_ARRAY_COUNT(colors); ++cfc) {
126c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(colors[cfc],
127c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                                                                               modes[cfm]));
128c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                paint.setColorFilter(cf);
12993f03324189f211db95c312b3cb08b435cc5ac34robertphillips@google.com                for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); ++s) {
130c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                    paint.setShader(shaders[s]);
131c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                    bool hasShader = NULL == paint.getShader();
132c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                    int paintColorCnt = hasShader ? SK_ARRAY_COUNT(alphas) : SK_ARRAY_COUNT(colors);
133c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                    SkColor* paintColors = hasShader ? alphas : colors;
134c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                    for (int pc = 0; pc < paintColorCnt; ++pc) {
135c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                        paint.setColor(paintColors[pc]);
136c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                        SkScalar x = SkIntToScalar(idx % kRectsPerRow);
137c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                        SkScalar y = SkIntToScalar(idx / kRectsPerRow);
138c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                        SkRect rect = SkRect::MakeXYWH(x * kRectWidth, y * kRectHeight,
139306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com                                                       SkIntToScalar(kRectWidth),
140ca47aae7ecfdafb5e88baee13737908b79a4c716robertphillips@google.com                                                       SkIntToScalar(kRectHeight));
1418d8d9a560619b48bae0b375b3a133999134a570fvandebo@chromium.org                        canvas->saveLayer(&rect, NULL);
142c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                        canvas->drawRect(rect, bgPaint);
143c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                        canvas->drawRect(rect, paint);
1448d8d9a560619b48bae0b375b3a133999134a570fvandebo@chromium.org                        canvas->restore();
145c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                        ++idx;
146c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                    }
147c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com                }
148c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            }
149c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        }
150c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
15193f03324189f211db95c312b3cb08b435cc5ac34robertphillips@google.com        for (size_t i = 0; i < SK_ARRAY_COUNT(shaders); ++i) {
152c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com            SkSafeUnref(shaders[i]);
153c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com        }
154c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    }
155c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
156c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comprivate:
157c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    SkAutoTUnref<SkShader> fBmpShader;
158c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com    typedef GM INHERITED;
159c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com};
160c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
161c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com//////////////////////////////////////////////////////////////////////////////
162c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
163c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comstatic GM* MyFactory(void*) { return new ModeColorFilterGM; }
164c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.comstatic GMRegistry reg(MyFactory);
165c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com
166c6126c182882512fce0b40be5f02a521b7e3ee8ebsalomon@google.com}
167