180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// This test only works with the GPU backend.
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gm.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if SK_SUPPORT_GPU
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrContext.h"
15d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "effects/GrSimpleTextureEffect.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h"
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkDevice.h"
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace skiagm {
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruextern GrContext* GetGr();
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int S = 200;
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass TexDataGM : public GM {
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    TexDataGM() {
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->setBGColor(0xff000000);
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected:
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual SkString onShortName() {
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return SkString("texdata");
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual SkISize onISize() {
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return make_isize(2*S, 2*S);
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void onDraw(SkCanvas* canvas) {
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDevice* device = canvas->getDevice();
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrRenderTarget* target = (GrRenderTarget*) device->accessRenderTarget();
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrContext* ctx = GetGr();
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (ctx && target) {
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkPMColor gTextureData[(2 * S) * (2 * S)];
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            static const int stride = 2 * S;
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            static const SkPMColor gray  = SkPackARGB32(0x40, 0x40, 0x40, 0x40);
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            static const SkPMColor white = SkPackARGB32(0xff, 0xff, 0xff, 0xff);
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            static const SkPMColor red   = SkPackARGB32(0x80, 0x80, 0x00, 0x00);
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            static const SkPMColor blue  = SkPackARGB32(0x80, 0x00, 0x00, 0x80);
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            static const SkPMColor green = SkPackARGB32(0x80, 0x00, 0x80, 0x00);
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            static const SkPMColor black = SkPackARGB32(0x00, 0x00, 0x00, 0x00);
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (int i = 0; i < 2; ++i) {
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int offset = 0;
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // fill upper-left
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                for (int y = 0; y < S; ++y) {
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    for (int x = 0; x < S; ++x) {
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        gTextureData[offset + y * stride + x] = gray;
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    }
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // fill upper-right
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                offset = S;
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                for (int y = 0; y < S; ++y) {
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    for (int x = 0; x < S; ++x) {
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        gTextureData[offset + y * stride + x] = white;
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    }
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // fill lower left
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                offset = S * stride;
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                for (int y = 0; y < S; ++y) {
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    for (int x = 0; x < S; ++x) {
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        gTextureData[offset + y * stride + x] = black;
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    }
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // fill lower right
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                offset = S * stride + S;
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                for (int y = 0; y < S; ++y) {
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    for (int x = 0; x < S; ++x) {
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        gTextureData[offset + y * stride + x] = gray;
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    }
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                GrTextureDesc desc;
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // use RT flag bit because in GL it makes the texture be bottom-up
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                desc.fFlags     = i ? kRenderTarget_GrTextureFlagBit :
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                      kNone_GrTextureFlags;
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                desc.fConfig    = kSkia8888_PM_GrPixelConfig;
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                desc.fWidth     = 2 * S;
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                desc.fHeight    = 2 * S;
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                GrTexture* texture =
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    ctx->createUncachedTexture(desc, gTextureData, 0);
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (!texture) {
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    return;
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                GrAutoUnref au(texture);
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                GrContext::AutoClip acs(ctx, GrRect::MakeWH(2*S, 2*S));
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                ctx->setRenderTarget(target);
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                GrPaint paint;
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                paint.setBlendFunc(kOne_GrBlendCoeff, kISA_GrBlendCoeff);
104363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                SkMatrix vm;
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (i) {
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    vm.setRotate(90 * SK_Scalar1,
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                 S * SK_Scalar1,
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                 S * SK_Scalar1);
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                } else {
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    vm.reset();
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                ctx->setMatrix(vm);
113363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                SkMatrix tm;
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                tm = vm;
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                tm.postIDiv(2*S, 2*S);
116d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(texture, tm))->unref();
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                ctx->drawRect(paint, GrRect::MakeWH(2*S, 2*S));
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // now update the lower right of the texture in first pass
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // or upper right in second pass
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                offset = 0;
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                for (int y = 0; y < S; ++y) {
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    for (int x = 0; x < S; ++x) {
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        gTextureData[offset + y * stride + x] =
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            ((x + y) % 2) ? (i ? green : red) : blue;
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    }
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                texture->writePixels(S, (i ? 0 : S), S, S,
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                     texture->config(), gTextureData,
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                     4 * stride);
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                ctx->drawRect(paint, GrRect::MakeWH(2*S, 2*S));
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef GM INHERITED;
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GM* MyFactory(void*) { return new TexDataGM; }
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GMRegistry reg(MyFactory);
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
149