/*
 * 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 "GrContextPriv.h"
#include "GrProxyProvider.h"
#include "GrRenderTargetContext.h"
#include "GrTextureContext.h"
#include "GrFixedClip.h"
#include "SkColorPriv.h"
#include "SkGr.h"
#include "effects/GrPorterDuffXferProcessor.h"
#include "effects/GrSimpleTextureEffect.h"

constexpr int S = 200;
constexpr int kStride = 2 * S;

// Fill in the pixels:
//   gray  | white
//   -------------
//   black | gray
static void fill_in_pixels(SkPMColor* pixels) {
    const SkPMColor gray  = SkPackARGB32(0x40, 0x40, 0x40, 0x40);
    const SkPMColor white = SkPackARGB32(0xff, 0xff, 0xff, 0xff);
    const SkPMColor black = SkPackARGB32(0x00, 0x00, 0x00, 0x00);

    int offset = 0;

    // fill upper-left
    for (int y = 0; y < S; ++y) {
        for (int x = 0; x < S; ++x) {
            pixels[offset + y * kStride + x] = gray;
        }
    }
    // fill upper-right
    offset = S;
    for (int y = 0; y < S; ++y) {
        for (int x = 0; x < S; ++x) {
            pixels[offset + y * kStride + x] = white;
        }
    }
    // fill lower left
    offset = S * kStride;
    for (int y = 0; y < S; ++y) {
        for (int x = 0; x < S; ++x) {
            pixels[offset + y * kStride + x] = black;
        }
    }
    // fill lower right
    offset = S * kStride + S;
    for (int y = 0; y < S; ++y) {
        for (int x = 0; x < S; ++x) {
            pixels[offset + y * kStride + x] = gray;
        }
    }
}

DEF_SIMPLE_GM_BG(texdata, canvas, 2 * S, 2 * S, SK_ColorBLACK) {
    GrRenderTargetContext* renderTargetContext =
        canvas->internal_private_accessTopLayerRenderTargetContext();
    if (!renderTargetContext) {
        skiagm::GM::DrawGpuOnlyMessage(canvas);
        return;
    }

    GrContext* context = canvas->getGrContext();
    if (!context) {
        return;
    }

    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
    const SkImageInfo ii = SkImageInfo::Make(S, S, kBGRA_8888_SkColorType, kPremul_SkAlphaType);

    SkAutoTArray<SkPMColor> gTextureData((2 * S) * (2 * S));
    const SkPMColor red   = SkPackARGB32(0x80, 0x80, 0x00, 0x00);
    const SkPMColor blue  = SkPackARGB32(0x80, 0x00, 0x00, 0x80);
    const SkPMColor green = SkPackARGB32(0x80, 0x00, 0x80, 0x00);
    for (int i = 0; i < 2; ++i) {
        fill_in_pixels(gTextureData.get());

        GrSurfaceDesc desc;
        desc.fOrigin    = i ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
        desc.fWidth     = 2 * S;
        desc.fHeight    = 2 * S;
        desc.fConfig    = SkImageInfo2GrPixelConfig(ii, *context->caps());
        SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);

        sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kNo,
                                                                        gTextureData.get(), 0);
        if (!proxy) {
            return;
        }

        sk_sp<GrSurfaceContext> tContext = context->contextPriv().makeWrappedSurfaceContext(
                                                                                  std::move(proxy));

        if (!tContext) {
            return;
        }

        // setup new clip
        GrFixedClip clip(SkIRect::MakeWH(2*S, 2*S));

        GrPaint paint;
        paint.setPorterDuffXPFactory(SkBlendMode::kSrcOver);

        SkMatrix vm;
        if (i) {
            vm.setRotate(90 * SK_Scalar1, S * SK_Scalar1, S * SK_Scalar1);
        } else {
            vm.reset();
        }
        paint.addColorTextureProcessor(tContext->asTextureProxyRef(), vm);

        renderTargetContext->drawRect(clip, GrPaint::Clone(paint), GrAA::kNo, vm,
                                      SkRect::MakeWH(2 * S, 2 * S));

        // now update the lower right of the texture in first pass
        // or upper right in second pass
        for (int y = 0; y < S; ++y) {
            for (int x = 0; x < S; ++x) {
                gTextureData[y * kStride + x] = ((x + y) % 2) ? (i ? green : red) : blue;
            }
        }

        if (!tContext->writePixels(ii, gTextureData.get(), 4 * kStride, S, i ? 0 : S)) {
            continue;
        }

        renderTargetContext->drawRect(clip, std::move(paint), GrAA::kNo, vm,
                                      SkRect::MakeWH(2 * S, 2 * S));
    }
}
#endif

