/*
 * 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/Renderer.h"

#include "src/gpu/graphite/DrawParams.h"
#include "src/gpu/graphite/UniformManager.h"

namespace skgpu::graphite {

RenderStep::RenderStep(Layout layout,
                       RenderStepID renderStepID,
                       SkEnumBitMask<Flags> flags,
                       std::initializer_list<Uniform> uniforms,
                       PrimitiveType primitiveType,
                       StencilSettings stencilSettings,
                       SkSpan<const Attribute> staticAttrs,
                       SkSpan<const Attribute> appendAttrs,
                       SkSpan<const Uniform> storageUniforms,
                       SkSpan<const Varying> varyings)
        : fRenderStepID(renderStepID)
        , fFlags(flags)
        , fStorageBufferStages(
                  (SkToBool(flags & Flags::kVsUsesStorage) ? PipelineStageFlags::kVertexShader
                                                           : PipelineStageFlags{}) |
                  (SkToBool(flags & Flags::kFsUsesStorage) ? PipelineStageFlags::kFragmentShader
                                                           : PipelineStageFlags{}))
        , fPrimitiveType(primitiveType)
        , fUniforms(uniforms)
        , fStaticAttrs(staticAttrs.begin(), staticAttrs.end())
        , fAppendAttrs(appendAttrs.begin(), appendAttrs.end())
        , fStorageUniforms(storageUniforms.begin(), storageUniforms.end())
        , fVaryings(varyings.begin(), varyings.end())
        , fUniformAlignment(0)
        , fStaticDataStride(0)
        , fAppendDataStride(0)
        , fStorageUniformStride(0)
        , fStorageUniformAlignment(1) {
    // If declaring storage uniforms, the flags must specify their visibility
    SkASSERT(fStorageUniforms.empty() ||
             SkToBool(fStorageBufferStages & (PipelineStageFlags::kVertexShader |
                                              PipelineStageFlags::kFragmentShader)));

    // kAllowSelfIntersection and kNoSelfIntersection are mutually exclusive
    SkASSERT(!(SkToBool(fFlags & Flags::kAllowsSelfIntersection) &&
               SkToBool(fFlags & Flags::kNoSelfIntersections)));

    // TODO(michaelludwig): Pull the depth settings out of RenderStep entirely as part of building
    // the ShaderInfo's settings, combining flags with renderpass requirements. At that point,
    // RenderStep can just store the stencil settings directly.
    fDepthStencilSettings.second = stencilSettings;

    // Ensure that the depth-related flags are consistent with the depth settings provided
    if (this->requiresDepth()) {
        // This mode requires the depth buffer to prevent double blending, so writes need to be
        // enabled and the test needs to be LESS to fail subsequent pixel touches.
        fDepthStencilSettings.first = {CompareOp::kLess, /*write=*/true};
    } else if (this->useNonAAInnerFill()) {
        // Currently, inner fill draws use the same z value as the main draw, so a render step
        // opting into this feature needs to use LESS even if otherwise could use LEQUAL. This
        // could be relaxed by changing how Device assigns z values but there's no pressing need.
        // Opting into a non-aa inner fill does not require depth writes, since this step is being
        // rendered after the inner fill (which would write depth).
        // TODO(michaelludwig): But for now set depthWrite=true since there's no renderpass logic
        // to detect when depth writes are necessary.
        fDepthStencilSettings.first = {CompareOp::kLess, /*write=*/true};
    } else {
        // These flags have the same effective behavior, which is that the test is LEQUAL
        // (either necessary to show self-intersections, or desired to highlight bugs that indicate
        // a violation of kNoSelfIntersection). They do not mandate depth writes being enabled.
        // TODO(michaelludwig): For now, also allow kLess to support scenarios where multiple
        // recordDraws() depend on the Z value being the same; use presence of stencil to select
        // LESS over LEQUAL.
        // TODO(michaelludwig): But for now set depthWrite=true when we perform shading since there
        // is no render pass detection logic yet.
        fDepthStencilSettings.first = {stencilSettings.enabled() ? CompareOp::kLess
                                                                 : CompareOp::kLEqual,
                                       /*write=*/this->performsShading()};
    }

    for (auto v : this->staticAttributes()) {
        fStaticDataStride += v.sizeAlign4();
    }
    for (auto i : this->appendAttributes()) {
        fAppendDataStride += i.sizeAlign4();
    }

    if (!fStorageUniforms.empty()) {
        // Storage uniforms are backed by a storage buffer or emulated via a fallback texture.
        // In both cases the struct layout follows Std430.
        UniformOffsetCalculator calculator = UniformOffsetCalculator::ForStruct(Layout::kStd430);
        for (const auto& u : fStorageUniforms) {
            calculator.advanceOffset(u.type(), u.count());
        }
        fStorageUniformAlignment = calculator.requiredAlignment();
        fStorageUniformStride = SkAlignTo<size_t>(calculator.size(), fStorageUniformAlignment);
    }

    UniformOffsetCalculator calculator = UniformOffsetCalculator::ForTopLevel(layout);
    for (const auto& u : fUniforms) {
        calculator.advanceOffset(u.type(), u.count());
    }
    fUniformAlignment = calculator.requiredAlignment();
}

std::optional<SkIRect> RenderStep::getScissor(const DrawParams& params,
                                              SkIRect currentScissor,
                                              SkIRect deviceBounds) const {
    if (currentScissor == params.scissor()) {
        return {}; // Trivially no change in scissor state is required
    }

    Rect drawBounds = params.drawBounds();
    if (params.geometry().isShape() && params.geometry().shape().inverted()) {
        // For inverse filled shapes, the scissor is able to be handled in unique ways.
        if (fFlags & Flags::kInverseFillsScissor) {
            // In this case, the RenderStep geometrically respects the scissor so as long as the
            // current scissor doesn't interfere, we don't need a state change.
            if (currentScissor.contains(params.scissor())) {
                return {};
            } else {
                // This draw doesn't need a scissor at all, so return the device bounds. It is
                // expected that this will generally lead to fewer scissor state changes (for
                // instance when applying the cover steps for a lot of inverse-filled intersect
                // clip depth-only draws). However, it could lead to a redundant scissor change if
                // the next draw would have used this draw's original scissor.
                return deviceBounds;
            }
        }

        if (fFlags & Flags::kIgnoreInverseFill) {
            // In this case params.drawBounds() fills the scissor from the inverse fill rule,
            // but we want to apply the scissor as if it were a regular fill.
            drawBounds = params.transformedShapeBounds(); // this ignores fill rule
            drawBounds.intersect(params.scissor());
        } // Else leave drawBounds filling the original scissor

        // Fall through to regular scissor state checking with the possibly-updated bounds
    }

    // Draws that are unaffected by a clip stack will have a scissor matching the device's bounds.
    // If their transformed shape bounds clipped to the current scissor are no different than their
    // draw bounds (clipped to the original scissor), then no state change is required.
    Rect currentClippedBounds = params.transformedShapeBounds();
    currentClippedBounds.intersect(currentScissor);
    if (currentClippedBounds == drawBounds) {
        return {};
    }

    if (drawBounds == params.transformedShapeBounds()) {
        // We need to change the scissor, but the registered scissor is a no-op so
        // use the device bounds as a canonical scissor.
        return deviceBounds;
    }

    return params.scissor();
}

Coverage RenderStep::GetCoverage(SkEnumBitMask<Flags> flags) {
    return !(flags & Flags::kEmitsCoverage) ? Coverage::kNone
           : (flags & Flags::kLCDCoverage)  ? Coverage::kLCD
                                            : Coverage::kSingleChannel;
}

const char* RenderStep::RenderStepName(RenderStepID id) {
#define CASE1(BaseName) case RenderStepID::k##BaseName: return #BaseName "RenderStep";
#define CASE2(BaseName, VariantName) \
    case RenderStepID::k##BaseName##_##VariantName: return #BaseName "RenderStep[" #VariantName "]";

    switch (id) {
        SKGPU_RENDERSTEP_TYPES(CASE1, CASE2)
    }
#undef CASE1
#undef CASE2

    SkUNREACHABLE;
}

bool RenderStep::IsValidRenderStepID(uint32_t renderStepID) {
    return renderStepID > (int) RenderStep::RenderStepID::kInvalid &&
           renderStepID < RenderStep::kNumRenderSteps;
}

} // namespace skgpu::graphite
