/*
 * 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 "src/gpu/ganesh/ops/AtlasRenderTask.h"

#include "include/core/SkBlendMode.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/private/SkDebug.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkIPoint16.h"
#include "src/gpu/ganesh/GrGpu.h"
#include "src/gpu/ganesh/GrNativeRect.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrRenderTargetProxy.h"
#include "src/gpu/ganesh/GrRenderTask.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyPriv.h"
#include "src/gpu/ganesh/GrUserStencilSettings.h"
#include "src/gpu/ganesh/GrXferProcessor.h"
#include "src/gpu/ganesh/geometry/GrQuad.h"
#include "src/gpu/ganesh/ops/FillPathFlags.h"
#include "src/gpu/ganesh/ops/FillRectOp.h"
#include "src/gpu/ganesh/ops/GrDrawOp.h"
#include "src/gpu/ganesh/ops/PathStencilCoverOp.h"

#include <initializer_list>

namespace skgpu::ganesh {

AtlasRenderTask::AtlasRenderTask(GrRecordingContext* rContext,
                                 sk_sp<GrArenas> arenas,
                                 std::unique_ptr<GrDynamicAtlas> dynamicAtlas)
        : OpsTask(rContext->priv().drawingManager(),
                  dynamicAtlas->writeView(*rContext->priv().caps()),
                  rContext->priv().auditTrail(),
                  std::move(arenas))
        , fDynamicAtlas(std::move(dynamicAtlas)) {
}

bool AtlasRenderTask::addPath(const SkMatrix& viewMatrix, const SkPath& path,
                              SkIPoint pathDevTopLeft, int widthInAtlas, int heightInAtlas,
                              bool transposedInAtlas, SkIPoint16* locationInAtlas) {
    SkASSERT(!this->isClosed());
    SkASSERT(this->isEmpty());
    SkASSERT(!fDynamicAtlas->isInstantiated());  // Paths can't be added after instantiate().

    // Check for room in the list first and return false if prior draws need to be flushed first.
    if (GrFillRuleForSkPath(path) == GrFillRule::kNonzero) {
        if (!fWindingPathList.canAdd(path)) {
            return false;
        }
    } else {
        if (!fEvenOddPathList.canAdd(path)) {
            return false;
        }
    }

    if (!fDynamicAtlas->addRect(widthInAtlas, heightInAtlas, locationInAtlas)) {
        return false;
    }

    SkMatrix pathToAtlasMatrix = viewMatrix;
    if (transposedInAtlas) {
        std::swap(pathToAtlasMatrix[0], pathToAtlasMatrix[3]);
        std::swap(pathToAtlasMatrix[1], pathToAtlasMatrix[4]);
        float tx=pathToAtlasMatrix.getTranslateX(), ty=pathToAtlasMatrix.getTranslateY();
        pathToAtlasMatrix.setTranslateX(ty - pathDevTopLeft.y() + locationInAtlas->x());
        pathToAtlasMatrix.setTranslateY(tx - pathDevTopLeft.x() + locationInAtlas->y());
    } else {
        pathToAtlasMatrix.postTranslate(locationInAtlas->x() - pathDevTopLeft.x(),
                                        locationInAtlas->y() - pathDevTopLeft.y());
    }

    if (GrFillRuleForSkPath(path) == GrFillRule::kNonzero) {
        fWindingPathList.add(&fPathDrawAllocator, pathToAtlasMatrix, path);
    } else {
        fEvenOddPathList.add(&fPathDrawAllocator, pathToAtlasMatrix, path);
    }
    return true;
}

GrRenderTask::ExpectedOutcome AtlasRenderTask::onMakeClosed(GrRecordingContext* rContext,
                                                            SkIRect* targetUpdateBounds) {
    // We don't add our ops until now, at which point we know the atlas is done being built.
    SkASSERT(this->isEmpty());
    SkASSERT(!fDynamicAtlas->isInstantiated());  // Instantiation happens after makeClosed().

    const GrCaps& caps = *rContext->priv().caps();

    // Set our dimensions now. OpsTask will need them when we add our ops.
    this->target(0)->priv().setLazyDimensions(fDynamicAtlas->drawBounds());
    this->target(0)->asRenderTargetProxy()->setNeedsStencil();
    SkRect drawRect = target(0)->getBoundsRect();

    // Clear the atlas.
    if (caps.performColorClearsAsDraws() || caps.performStencilClearsAsDraws()) {
        this->setColorLoadOp(GrLoadOp::kDiscard);
        this->setInitialStencilContent(StencilContent::kDontCare);

        constexpr static GrUserStencilSettings kClearStencil(
            GrUserStencilSettings::StaticInit<
                0x0000,
                GrUserStencilTest::kAlways,
                0xffff,
                GrUserStencilOp::kReplace,
                GrUserStencilOp::kReplace,
                0xffff>());

        this->stencilAtlasRect(rContext, drawRect, SK_PMColor4fTRANSPARENT, &kClearStencil);
    } else {
        this->setColorLoadOp(GrLoadOp::kClear);
        this->setInitialStencilContent(StencilContent::kUserBitsCleared);
    }

    // Add ops to stencil the atlas paths.
    for (const auto* pathList : {&fWindingPathList, &fEvenOddPathList}) {
        if (pathList->pathCount() > 0) {
            auto op = GrOp::Make<PathStencilCoverOp>(
                    rContext,
                    pathList->pathDrawList(),
                    pathList->totalCombinedPathVerbCnt(),
                    pathList->pathCount(),
                    GrPaint(),
                    GrAAType::kMSAA,
                    FillPathFlags::kStencilOnly,
                    drawRect);
            this->addAtlasDrawOp(std::move(op), caps);
        }
    }

    // Finally, draw a fullscreen rect to cover our stencilled paths.
    const GrUserStencilSettings* stencil;
    if (caps.discardStencilValuesAfterRenderPass()) {
        constexpr static GrUserStencilSettings kTestStencil(
            GrUserStencilSettings::StaticInit<
                0x0000,
                GrUserStencilTest::kNotEqual,
                0xffff,
                GrUserStencilOp::kKeep,
                GrUserStencilOp::kKeep,
                0xffff>());

        // This is the final op in the task. Since Ganesh is planning to discard the stencil values
        // anyway, there is no need to reset the stencil values back to 0.
        stencil = &kTestStencil;
    } else {
        constexpr static GrUserStencilSettings kTestAndResetStencil(
            GrUserStencilSettings::StaticInit<
                0x0000,
                GrUserStencilTest::kNotEqual,
                0xffff,
                GrUserStencilOp::kZero,
                GrUserStencilOp::kKeep,
                0xffff>());

        // Outset the cover rect to make extra sure we clear every stencil value touched by the
        // atlas.
        drawRect.outset(1, 1);
        stencil = &kTestAndResetStencil;
    }
    this->stencilAtlasRect(rContext, drawRect, SK_PMColor4fWHITE, stencil);

    this->OpsTask::onMakeClosed(rContext, targetUpdateBounds);

    // Don't mark msaa dirty. Since this op defers being closed, the drawing manager's dirty
    // tracking doesn't work anyway. We will just resolve msaa manually during onExecute.
    return ExpectedOutcome::kTargetUnchanged;
}

void AtlasRenderTask::stencilAtlasRect(GrRecordingContext* rContext, const SkRect& rect,
                                       const SkPMColor4f& color,
                                       const GrUserStencilSettings* stencil) {
    GrPaint paint;
    paint.setColor4f(color);
    paint.setXPFactory(GrXPFactory::FromBlendMode(SkBlendMode::kSrc));
    GrQuad quad(rect);
    DrawQuad drawQuad{quad, quad, GrQuadAAFlags::kAll};
    auto op = FillRectOp::Make(rContext, std::move(paint), GrAAType::kMSAA, &drawQuad, stencil);
    this->addAtlasDrawOp(std::move(op), *rContext->priv().caps());
}

void AtlasRenderTask::addAtlasDrawOp(GrOp::Owner op, const GrCaps& caps) {
    SkASSERT(!this->isClosed());

    auto drawOp = static_cast<GrDrawOp*>(op.get());
    SkDEBUGCODE(drawOp->fAddDrawOpCalled = true;)

    auto processorAnalysis = drawOp->finalize(caps, nullptr,
                                              GrColorTypeClampType(fDynamicAtlas->colorType()));
    SkASSERT(!processorAnalysis.requiresDstTexture());
    SkASSERT(!processorAnalysis.usesNonCoherentHWBlending());

    drawOp->setClippedBounds(drawOp->bounds());
    this->recordOp(std::move(op), true/*usesMSAA*/, processorAnalysis, nullptr, nullptr, caps);
}

bool AtlasRenderTask::onExecute(GrOpFlushState* flushState) {
    if (!this->OpsTask::onExecute(flushState)) {
        return false;
    }
    if (this->target(0)->requiresManualMSAAResolve()) {
        // Since atlases don't get closed until they are done being built, the drawingManager
        // doesn't detect that they need an MSAA resolve. Do it here manually.
        auto nativeRect = GrNativeRect::MakeIRectRelativeTo(
                GrDynamicAtlas::kTextureOrigin,
                this->target(0)->backingStoreDimensions().height(),
                SkIRect::MakeSize(fDynamicAtlas->drawBounds()));
        flushState->gpu()->resolveRenderTarget(this->target(0)->peekRenderTarget(), nativeRect);
    }
    return true;
}

}  // namespace skgpu::ganesh
