
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

// This test only works with the GPU backend.

#include "gm.h"

#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "SkColorPriv.h"
#include "effects/GrPorterDuffXferProcessor.h"
#include "effects/GrSimpleTextureEffect.h"

namespace skiagm {

static const int S = 200;

class TexDataGM : public GM {
public:
    TexDataGM() {
        this->setBGColor(0xff000000);
    }

protected:
    SkString onShortName() override {
        return SkString("texdata");
    }

    SkISize onISize() override {
        return SkISize::Make(2*S, 2*S);
    }

    void onDraw(SkCanvas* canvas) override {
        GrRenderTarget* target = canvas->internal_private_accessTopLayerRenderTarget();
        GrContext* ctx = canvas->getGrContext();
        if (ctx && target) {
            SkAutoTArray<SkPMColor> gTextureData((2 * S) * (2 * S));
            static const int stride = 2 * S;
            static const SkPMColor gray  = SkPackARGB32(0x40, 0x40, 0x40, 0x40);
            static const SkPMColor white = SkPackARGB32(0xff, 0xff, 0xff, 0xff);
            static const SkPMColor red   = SkPackARGB32(0x80, 0x80, 0x00, 0x00);
            static const SkPMColor blue  = SkPackARGB32(0x80, 0x00, 0x00, 0x80);
            static const SkPMColor green = SkPackARGB32(0x80, 0x00, 0x80, 0x00);
            static const SkPMColor black = SkPackARGB32(0x00, 0x00, 0x00, 0x00);
            for (int i = 0; i < 2; ++i) {
                int offset = 0;
                // fill upper-left
                for (int y = 0; y < S; ++y) {
                    for (int x = 0; x < S; ++x) {
                        gTextureData[offset + y * stride + x] = gray;
                    }
                }
                // fill upper-right
                offset = S;
                for (int y = 0; y < S; ++y) {
                    for (int x = 0; x < S; ++x) {
                        gTextureData[offset + y * stride + x] = white;
                    }
                }
                // fill lower left
                offset = S * stride;
                for (int y = 0; y < S; ++y) {
                    for (int x = 0; x < S; ++x) {
                        gTextureData[offset + y * stride + x] = black;
                    }
                }
                // fill lower right
                offset = S * stride + S;
                for (int y = 0; y < S; ++y) {
                    for (int x = 0; x < S; ++x) {
                        gTextureData[offset + y * stride + x] = gray;
                    }
                }

                GrSurfaceDesc desc;
                // use RT flag bit because in GL it makes the texture be bottom-up
                desc.fFlags     = i ? kRenderTarget_GrSurfaceFlag :
                                      kNone_GrSurfaceFlags;
                desc.fConfig    = kSkia8888_GrPixelConfig;
                desc.fWidth     = 2 * S;
                desc.fHeight    = 2 * S;
                GrTexture* texture = ctx->createTexture(desc, false, gTextureData.get(), 0);

                if (!texture) {
                    return;
                }
                SkAutoTUnref<GrTexture> au(texture);

                // setup new clip
                GrClip clip(SkRect::MakeWH(2*S, 2*S));

                GrPaint paint;
                paint.setPorterDuffXPFactory(SkXfermode::kSrcOver_Mode);

                SkMatrix vm;
                if (i) {
                    vm.setRotate(90 * SK_Scalar1,
                                 S * SK_Scalar1,
                                 S * SK_Scalar1);
                } else {
                    vm.reset();
                }
                SkMatrix tm;
                tm = vm;
                tm.postIDiv(2*S, 2*S);
                paint.addColorTextureProcessor(texture, tm);

                ctx->drawRect(target, clip, paint, vm, SkRect::MakeWH(2*S, 2*S));

                // now update the lower right of the texture in first pass
                // or upper right in second pass
                offset = 0;
                for (int y = 0; y < S; ++y) {
                    for (int x = 0; x < S; ++x) {
                        gTextureData[offset + y * stride + x] =
                            ((x + y) % 2) ? (i ? green : red) : blue;
                    }
                }
                texture->writePixels(S, (i ? 0 : S), S, S,
                                     texture->config(), gTextureData.get(),
                                     4 * stride);
                ctx->drawRect(target, clip, paint, vm, SkRect::MakeWH(2*S, 2*S));
            }
        } else {
            this->drawGpuOnlyMessage(canvas);
        }
    }

private:
    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static GM* MyFactory(void*) { return new TexDataGM; }
static GMRegistry reg(MyFactory);

}

#endif
