/*
 * Copyright 2024 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/graphite/precompile/PaintOption.h"

#include "include/core/SkBlender.h"
#include "include/gpu/graphite/precompile/PrecompileBlender.h"
#include "include/gpu/graphite/precompile/PrecompileColorFilter.h"
#include "include/gpu/graphite/precompile/PrecompileShader.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/gpu/graphite/ContextUtils.h"
#include "src/gpu/graphite/KeyContext.h"
#include "src/gpu/graphite/KeyHelpers.h"
#include "src/gpu/graphite/PaintParams.h"
#include "src/gpu/graphite/PaintParamsKey.h"
#include "src/gpu/graphite/PrecompileInternal.h"
#include "src/gpu/graphite/precompile/PrecompileBasePriv.h"
#include "src/gpu/graphite/precompile/PrecompileBlenderPriv.h"
#include "src/gpu/graphite/precompile/PrecompileShaderPriv.h"

namespace skgpu::graphite {

PaintOption::PaintOption(bool opaquePaintColor,
                         const std::pair<sk_sp<PrecompileBlender>, int>& finalBlender,
                         const std::pair<sk_sp<PrecompileShader>, int>& shader,
                         const std::pair<sk_sp<PrecompileColorFilter>, int>& colorFilter,
                         bool hasPrimitiveBlender,
                         SkBlendMode primitiveBlendMode,
                         bool skipColorXform,
                         const std::pair<sk_sp<PrecompileShader>, int>& clipShader,
                         Coverage coverage,
                         TextureFormat targetFormat,
                         bool dither,
                         bool analyticClip)
        : fOpaquePaintColor(opaquePaintColor)
        , fFinalBlender(finalBlender)
        , fShader(shader)
        , fColorFilter(colorFilter)
        , fPrimitiveBlendMode(primitiveBlendMode)
        , fHasPrimitiveBlender(hasPrimitiveBlender)
        , fSkipColorXform(skipColorXform)
        , fClipShader(clipShader)
        , fRendererCoverage(coverage)
        , fTargetFormat(targetFormat)
        , fDither(dither)
        , fAnalyticClip(analyticClip) {
    if (!fHasPrimitiveBlender) {
        if (fShader.first && fShader.first->priv().isConstant(fShader.second)) {
            fShader = { nullptr, 0 };
        }
        if (!fShader.first && fColorFilter.first) {
            fColorFilter = { nullptr, 0 };
        }
    }
}

void PaintOption::toKey(const KeyContext& keyContext) const {
    // Root Node 0 is the source color, which is the output of all effects post dithering
    this->handleDithering(keyContext);

    // Root Node 1 is the final blender
    std::optional<SkBlendMode> finalBlendMode =
            this->finalBlender() ? this->finalBlender()->priv().asBlendMode()
                                 : SkBlendMode::kSrcOver;

    Coverage finalCoverage = fRendererCoverage;
    if ((fClipShader.first || fAnalyticClip) && fRendererCoverage == Coverage::kNone) {
        finalCoverage = Coverage::kSingleChannel;
    }
    bool dstReadReq = !CanUseHardwareBlending(keyContext.caps(),
                                              fTargetFormat,
                                              finalBlendMode,
                                              finalCoverage);

    if (finalBlendMode) {
        if (!dstReadReq) {
            AddFixedBlendMode(keyContext, *finalBlendMode);
        } else {
            AddBlendMode(keyContext, *finalBlendMode);
        }
    } else {
        SkASSERT(this->finalBlender());
        fFinalBlender.first->priv().addToKey(keyContext, fFinalBlender.second);
    }

    // Optional Root Node 2 is the clip
    this->handleClipping(keyContext);
}

void PaintOption::addPaintColorToKey(const KeyContext& keyContext) const {
    if (fShader.first) {
        fShader.first->priv().addToKey(keyContext, fShader.second);
    } else {
        RGBPaintColorBlock::AddBlock(keyContext);
    }
}

void PaintOption::handlePrimitiveColor(const KeyContext& keyContext) const {
    if (!fHasPrimitiveBlender) {
        this->addPaintColorToKey(keyContext);
        return;
    }

    if (fSkipColorXform && fPrimitiveBlendMode == SkBlendMode::kDst) {
        AddPrimitiveColor(keyContext, fSkipColorXform);
        return;
    }

    Blend(keyContext,
            /* addBlendToKey= */ [&] () -> void {
                /**
                 * TODO: Allow clients to provide precompile SkBlender options for primitive
                 * blending. For now we have a back door to internally specify an SkBlendMode.
                 */
                AddToKey(keyContext,
                         SkBlender::Mode(fPrimitiveBlendMode).get());
            },
            /* addSrcToKey= */ [&]() -> void {
                this->addPaintColorToKey(keyContext);
            },
            /* addDstToKey= */ [&]() -> void {
                AddPrimitiveColor(keyContext, fSkipColorXform);
            });
}

void PaintOption::handlePaintAlpha(const KeyContext& keyContext) const {

    if (!fShader.first && !fHasPrimitiveBlender) {
        // If there is no shader and no primitive blending the input to the colorFilter stage
        // is just the premultiplied paint color.
        SolidColorShaderBlock::AddBlock(keyContext, SK_PMColor4fWHITE);
        return;
    }

    if (!fOpaquePaintColor) {
        Blend(keyContext,
              /* addBlendToKey= */ [&] () -> void {
                  AddFixedBlendMode(keyContext, SkBlendMode::kSrcIn);
              },
              /* addSrcToKey= */ [&]() -> void {
                  this->handlePrimitiveColor(keyContext);
              },
              /* addDstToKey= */ [&]() -> void {
                  AlphaOnlyPaintColorBlock::AddBlock(keyContext);
              });
    } else {
        this->handlePrimitiveColor(keyContext);
    }
}

void PaintOption::handleColorFilter(const KeyContext& keyContext) const {
    if (fColorFilter.first) {
        Compose(keyContext,
                /* addInnerToKey= */ [&]() -> void {
                    this->handlePaintAlpha(keyContext);
                },
                /* addOuterToKey= */ [&]() -> void {
                    fColorFilter.first->priv().addToKey(keyContext, fColorFilter.second);
                });
    } else {
        this->handlePaintAlpha(keyContext);
    }
}

// This should be kept in sync w/ SkPaintPriv::ShouldDither and PaintParams::should_dither
bool PaintOption::shouldDither(SkColorType dstCT) const {
    // The paint dither flag can veto.
    if (!fDither) {
        return false;
    }

    if (dstCT == kUnknown_SkColorType) {
        return false;
    }

    // We always dither 565 or 4444 when requested.
    if (dstCT == kRGB_565_SkColorType || dstCT == kARGB_4444_SkColorType) {
        return true;
    }

    // Otherwise, dither is only needed for non-const paints.
    return fShader.first && !fShader.first->priv().isConstant(fShader.second);
}

void PaintOption::handleDithering(const KeyContext& keyContext) const {

#ifndef SK_IGNORE_GPU_DITHER
    SkColorType ct = keyContext.dstColorInfo().colorType();
    if (this->shouldDither(ct)) {
        Compose(keyContext,
                /* addInnerToKey= */ [&]() -> void {
                    this->handleColorFilter(keyContext);
                },
                /* addOuterToKey= */ [&]() -> void {
                    AddDitherBlock(keyContext, ct);
                });
    } else
#endif
    {
        this->handleColorFilter(keyContext);
    }
}

void PaintOption::handleClipping(const KeyContext& keyContext) const {
    if (fAnalyticClip) {
        NonMSAAClipBlock::NonMSAAClipData data(
                /* rect= */ {},
                /* radiusPlusHalf= */ {},
                /* edgeSelect= */ {},
                /* texCoordOffset= */ {},
                /* maskBounds= */ {},
                // TODO: the kAnalyticAndAtlasClip vs. kAnalyticClip decision is based on this
                // being a valid TextureProxy.
                /* atlasTexture= */ nullptr);
        if (fClipShader.first) {
            // For both an analytic clip and clip shader, we need to compose them together into
            // a single clipping root node.
            Blend(keyContext,
                    /* addBlendToKey= */ [&]() -> void {
                        AddFixedBlendMode(keyContext, SkBlendMode::kModulate);
                    },
                    /* addSrcToKey= */ [&]() -> void {
                        NonMSAAClipBlock::AddBlock(keyContext, data);
                    },
                    /* addDstToKey= */ [&]() -> void {
                        fClipShader.first->priv().addToKey(keyContext, fClipShader.second);
                    });
        } else {
            // Without a clip shader, the analytic clip can be the clipping root node.
            NonMSAAClipBlock::AddBlock(keyContext, data);
        }
    } else if (fClipShader.first) {
        // Since there's no analytic clip, the clipping root node can be fClipShader directly.
        fClipShader.first->priv().addToKey(keyContext, fClipShader.second);
    }
}

} // namespace skgpu::graphite
