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

// This is a GPU-backend specific test.

#include "tests/Test.h"

#include "include/core/SkColorSpace.h"
#include "include/gpu/GrDirectContext.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/GrTextureProxy.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"

static const int kSize = 64;

static std::unique_ptr<skgpu::v1::SurfaceDrawContext> get_sdc(GrRecordingContext* rContext) {
    return skgpu::v1::SurfaceDrawContext::Make(rContext, GrColorType::kRGBA_8888, nullptr,
                                               SkBackingFit::kExact, {kSize, kSize},
                                               SkSurfaceProps(), /*label=*/{});
}

static void check_instantiation_status(skiatest::Reporter* reporter,
                                       skgpu::v1::SurfaceDrawContext* sdc,
                                       bool wrappedExpectation) {
    REPORTER_ASSERT(reporter, sdc->asRenderTargetProxy()->isInstantiated() == wrappedExpectation);

    GrTextureProxy* tProxy = sdc->asTextureProxy();
    REPORTER_ASSERT(reporter, tProxy);

    REPORTER_ASSERT(reporter, tProxy->isInstantiated() == wrappedExpectation);
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceDrawContextTest,
                                   reporter,
                                   ctxInfo,
                                   CtsEnforcement::kApiLevel_T) {
    auto dContext = ctxInfo.directContext();

    // Calling instantiate on a SurfaceDrawContext's textureProxy also instantiates the
    // SurfaceDrawContext
    {
        auto sdc = get_sdc(dContext);

        check_instantiation_status(reporter, sdc.get(), false);

        GrTextureProxy* tProxy = sdc->asTextureProxy();
        REPORTER_ASSERT(reporter, tProxy);

        REPORTER_ASSERT(reporter, tProxy->instantiate(dContext->priv().resourceProvider()));

        check_instantiation_status(reporter, sdc.get(), true);
    }

    // readPixels switches a deferred sdCtx to wrapped
    {
        auto sdc = get_sdc(dContext);

        check_instantiation_status(reporter, sdc.get(), false);

        SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(kSize, kSize);
        GrPixmap dstPM = GrPixmap::Allocate(dstInfo);

        bool result = sdc->readPixels(dContext, dstPM, {0, 0});
        REPORTER_ASSERT(reporter, result);

        check_instantiation_status(reporter, sdc.get(), true);
    }

    // TODO: in a future world we should be able to add a test that the majority of
    // SurfaceDrawContext calls do not force the instantiation of a deferred
    // SurfaceDrawContext
}
