1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9// This test only works with the GPU backend.
10
11#include "gm.h"
12
13#if SK_SUPPORT_GPU
14#include "GrContext.h"
15#include "effects/GrSimpleTextureEffect.h"
16#include "SkColorPriv.h"
17
18namespace skiagm {
19
20static const int S = 200;
21
22class TexDataGM : public GM {
23public:
24    TexDataGM() {
25        this->setBGColor(0xff000000);
26    }
27
28protected:
29    virtual SkString onShortName() {
30        return SkString("texdata");
31    }
32
33    virtual SkISize onISize() {
34        return SkISize::Make(2*S, 2*S);
35    }
36
37    virtual uint32_t onGetFlags() const SK_OVERRIDE { return kGPUOnly_Flag; }
38
39    virtual void onDraw(SkCanvas* canvas) {
40        GrRenderTarget* target = canvas->internal_private_accessTopLayerRenderTarget();
41        GrContext* ctx = canvas->getGrContext();
42        if (ctx && target) {
43            SkAutoTArray<SkPMColor> gTextureData((2 * S) * (2 * S));
44            static const int stride = 2 * S;
45            static const SkPMColor gray  = SkPackARGB32(0x40, 0x40, 0x40, 0x40);
46            static const SkPMColor white = SkPackARGB32(0xff, 0xff, 0xff, 0xff);
47            static const SkPMColor red   = SkPackARGB32(0x80, 0x80, 0x00, 0x00);
48            static const SkPMColor blue  = SkPackARGB32(0x80, 0x00, 0x00, 0x80);
49            static const SkPMColor green = SkPackARGB32(0x80, 0x00, 0x80, 0x00);
50            static const SkPMColor black = SkPackARGB32(0x00, 0x00, 0x00, 0x00);
51            for (int i = 0; i < 2; ++i) {
52                int offset = 0;
53                // fill upper-left
54                for (int y = 0; y < S; ++y) {
55                    for (int x = 0; x < S; ++x) {
56                        gTextureData[offset + y * stride + x] = gray;
57                    }
58                }
59                // fill upper-right
60                offset = S;
61                for (int y = 0; y < S; ++y) {
62                    for (int x = 0; x < S; ++x) {
63                        gTextureData[offset + y * stride + x] = white;
64                    }
65                }
66                // fill lower left
67                offset = S * stride;
68                for (int y = 0; y < S; ++y) {
69                    for (int x = 0; x < S; ++x) {
70                        gTextureData[offset + y * stride + x] = black;
71                    }
72                }
73                // fill lower right
74                offset = S * stride + S;
75                for (int y = 0; y < S; ++y) {
76                    for (int x = 0; x < S; ++x) {
77                        gTextureData[offset + y * stride + x] = gray;
78                    }
79                }
80
81                GrTextureDesc desc;
82                // use RT flag bit because in GL it makes the texture be bottom-up
83                desc.fFlags     = i ? kRenderTarget_GrTextureFlagBit :
84                                      kNone_GrTextureFlags;
85                desc.fConfig    = kSkia8888_GrPixelConfig;
86                desc.fWidth     = 2 * S;
87                desc.fHeight    = 2 * S;
88                GrTexture* texture =
89                    ctx->createUncachedTexture(desc, gTextureData.get(), 0);
90
91                if (!texture) {
92                    return;
93                }
94                SkAutoUnref au(texture);
95
96                GrContext::AutoClip acs(ctx, SkRect::MakeWH(2*S, 2*S));
97
98                ctx->setRenderTarget(target);
99
100                GrPaint paint;
101                paint.setBlendFunc(kOne_GrBlendCoeff, kISA_GrBlendCoeff);
102                SkMatrix vm;
103                if (i) {
104                    vm.setRotate(90 * SK_Scalar1,
105                                 S * SK_Scalar1,
106                                 S * SK_Scalar1);
107                } else {
108                    vm.reset();
109                }
110                ctx->setMatrix(vm);
111                SkMatrix tm;
112                tm = vm;
113                tm.postIDiv(2*S, 2*S);
114                paint.addColorTextureEffect(texture, tm);
115
116                ctx->drawRect(paint, SkRect::MakeWH(2*S, 2*S));
117
118                // now update the lower right of the texture in first pass
119                // or upper right in second pass
120                offset = 0;
121                for (int y = 0; y < S; ++y) {
122                    for (int x = 0; x < S; ++x) {
123                        gTextureData[offset + y * stride + x] =
124                            ((x + y) % 2) ? (i ? green : red) : blue;
125                    }
126                }
127                texture->writePixels(S, (i ? 0 : S), S, S,
128                                     texture->config(), gTextureData.get(),
129                                     4 * stride);
130                ctx->drawRect(paint, SkRect::MakeWH(2*S, 2*S));
131            }
132        }
133    }
134
135private:
136    typedef GM INHERITED;
137};
138
139//////////////////////////////////////////////////////////////////////////////
140
141static GM* MyFactory(void*) { return new TexDataGM; }
142static GMRegistry reg(MyFactory);
143
144}
145
146#endif
147