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

#include "include/core/SkAlphaType.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrDirectContext.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"

#include <initializer_list>

struct GrContextOptions;

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(crbug_1271431,
                                       reporter,
                                       context_info,
                                       CtsEnforcement::kApiLevel_T) {
    GrDirectContext* dc = context_info.directContext();

    // Make sure we don't get recycled render targets that already have stencil attachments.
    dc->freeGpuResources();

    SkImageInfo ii = SkImageInfo::Make({100, 100},
                                       kRGBA_8888_SkColorType,
                                       kPremul_SkAlphaType,
                                       nullptr);
    sk_sp<SkSurface> surfs[2]{
            SkSurface::MakeRenderTarget(dc, skgpu::Budgeted::kYes, ii, 1, nullptr),
            SkSurface::MakeRenderTarget(dc, skgpu::Budgeted::kYes, ii, 1, nullptr)};

    // Make sure the surfaces' proxies are instantiated without stencil. Creating textures lazily
    // can invalidate the current tracked FBO since FBO state must be modified to during
    // GrGLRenderTarget creation.
    for (int i = 0; i < 2; ++i) {
        surfs[i]->getCanvas()->clear(SK_ColorWHITE);
        surfs[i]->flushAndSubmit();
    }

    auto drawWithStencilClip = [&](SkSurface& surf, SkColor color) {
        SkPath clip;
        clip.addCircle(50, 50, 50);
        clip.addCircle(50, 50, 10, SkPathDirection::kCCW);
        SkPaint paint;
        paint.setColor(color);
        surf.getCanvas()->clipPath(clip, false);
        surf.getCanvas()->drawRect(SkRect::MakeLTRB(0,0, 100, 100), paint);
    };

    // Use surfs[0] create to create a cached stencil buffer that is also sized for surfs[1].
    drawWithStencilClip(*surfs[0], SK_ColorRED);
    surfs[0]->flushAndSubmit();

    // Make sure surf[1]'s FBO is bound but without using draws that would attach stencil.
    surfs[1]->getCanvas()->clear(SK_ColorGREEN);
    surfs[1]->flushAndSubmit();

    // Now use stencil for clipping. We should now have the following properties:
    // 1) surf[1]'s FBO is already bound
    // 2) surf[1] doesn't have a stencil buffer
    // 3) There is an appropriately sized stencil buffer in the cache (used with surf[0]). This is
    //    important because creating a new stencil buffer will invalidate the bound FBO tracking.
    // The bug was that because the correct FBO was already bound we would not rebind and would
    // skip the lazy stencil attachment in GrGLRenderTarget. This would cause the clip to fail.
    drawWithStencilClip(*surfs[1], SK_ColorBLUE);

    // Check that four pixels that should have been clipped out of the blue draw are green.
    SkAutoPixmapStorage rb;
    rb.alloc(surfs[1]->imageInfo().makeWH(1, 1));
    for (int x : {5, 95}) {
        for (int y : {5, 95}) {
            if (!surfs[1]->readPixels(rb, x, y)) {
                ERRORF(reporter, "readback failed");
                return;
            }
            if (*rb.addr32() != SK_ColorGREEN) {
                ERRORF(reporter,
                       "Expected green at (%d, %d), instead got 0x%08x.",
                       x,
                       y,
                       *rb.addr32());
                return;
            }
        }
    }
}
