/*
 * Copyright 2022 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/KeyContext.h"

#include "include/effects/SkRuntimeEffect.h"
#include "src/core/SkRuntimeEffectPriv.h"
#include "src/gpu/graphite/DrawContext.h"
#include "src/gpu/graphite/PaintParams.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/RuntimeEffectDictionary.h"

namespace skgpu::graphite {

KeyContext::KeyContext(const Caps* caps,
                       PaintParamsKeyBuilder* paintParamsKeyBuilder,
                       PipelineDataGatherer* pipelineDataGatherer,
                       ShaderCodeDictionary* dict,
                       sk_sp<RuntimeEffectDictionary> rtEffectDict,
                       const SkColorInfo& dstColorInfo)
        : fCaps(caps)
        , fRecorder(nullptr)
        , fPaintParamsKeyBuilder(paintParamsKeyBuilder)
        , fPipelineDataGatherer(pipelineDataGatherer)
        , fDictionary(dict)
        , fRTEffectDict(std::move(rtEffectDict))
        , fDstColorInfo(dstColorInfo) {}

KeyContext::KeyContext(skgpu::graphite::Recorder* recorder,
                       DrawContext* drawContext,
                       PaintParamsKeyBuilder* paintParamsKeyBuilder,
                       PipelineDataGatherer* pipelineDataGatherer,
                       const SkM44& local2Dev,
                       const SkRect& clipDrawBounds,
                       const SkColorInfo& dstColorInfo,
                       SkEnumBitMask<KeyGenFlags> initialFlags,
                       const SkColor4f& paintColor)
        : fCaps(recorder->priv().caps())
        , fRecorder(recorder)
        , fDC(drawContext)
        , fPaintParamsKeyBuilder(paintParamsKeyBuilder)
        , fPipelineDataGatherer(pipelineDataGatherer)
        , fDictionary(recorder->priv().shaderCodeDictionary())
        , fRTEffectDict(recorder->priv().runtimeEffectDictionary())
        , fLocal2Dev(local2Dev)
        , fClipDrawBounds(clipDrawBounds)
        , fLocalMatrix(nullptr)
        , fDstColorInfo(dstColorInfo)
        , fKeyGenFlags(initialFlags) {
    fPaintColor = PaintParams::Color4fPrepForDst(paintColor, fDstColorInfo).makeOpaque().premul();
    fPaintColor.fA = paintColor.fA;
}

KeyContext::KeyContext(const KeyContext& other,
                       SkEnumBitMask<KeyGenFlags> xtraFlags)
        : fCaps(other.fCaps)
        , fRecorder(other.fRecorder)
        , fDC(other.fDC)
        , fPaintParamsKeyBuilder(other.fPaintParamsKeyBuilder)
        , fPipelineDataGatherer(other.fPipelineDataGatherer)
        , fDictionary(other.fDictionary)
        , fRTEffectDict(other.fRTEffectDict)
        , fLocal2Dev(other.fLocal2Dev)
        , fClipDrawBounds(other.fClipDrawBounds)
        , fLocalMatrix(other.fLocalMatrix)
        , fDstColorInfo(other.fDstColorInfo)
        , fPaintColor(other.fPaintColor)
        , fKeyGenFlags(other.fKeyGenFlags | xtraFlags) {}

KeyContext::~KeyContext() {}

KeyContext& KeyContext::operator=(const KeyContext&) = default;

sk_sp<RuntimeEffectDictionary> KeyContext::rtEffectDict() const { return fRTEffectDict; }

// Runtime effects always disable paint-color colorization of alpha-only image shaders
static constexpr SkEnumBitMask<KeyGenFlags> kRuntimeEffectChildDefaultFlags
        = KeyGenFlags::kDisableAlphaOnlyImageColorization;

KeyContext KeyContext::forRuntimeEffect(const SkRuntimeEffect* effect, int child) const {
    SkEnumBitMask<KeyGenFlags> xtraFlags = kRuntimeEffectChildDefaultFlags;

    if (SkRuntimeEffectPriv::ChildSampleUsage(effect, child).isExplicit()) {
        // Assume explicit sampling as a proxy for either a likely data lookup (e.g. raw shader)
        // or an effect that might sample the child many times. This means it's worth using
        // eliding colorspace conversions, and we have to disable sampling optimization.
        xtraFlags |= KeyGenFlags::kSpecializeColorSpaceXform |
                     KeyGenFlags::kDisableSamplingOptimization;
    }

    return this->withExtraFlags(xtraFlags);
}

KeyContext KeyContext::forMeshSpecChild() const {
    return this->withExtraFlags(kRuntimeEffectChildDefaultFlags);
}

} // namespace skgpu::graphite
