/*
 * Copyright 2019 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/GrProgramInfo.h"

#include "include/gpu/GpuTypes.h"
#include "include/private/SkAssert.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrRenderTargetProxy.h"
#include "src/gpu/ganesh/GrSamplerState.h"
#include "src/gpu/ganesh/GrStencilSettings.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "src/gpu/ganesh/effects/GrTextureEffect.h"

#include <functional>

class GrGeometryProcessor;
enum class GrXferBarrierFlags;

GrProgramInfo::GrProgramInfo(const GrCaps& caps,
                             const GrSurfaceProxyView& targetView,
                             bool usesMSAASurface,
                             const GrPipeline* pipeline,
                             const GrUserStencilSettings* userStencilSettings,
                             const GrGeometryProcessor* geomProc,
                             GrPrimitiveType primitiveType,
                             GrXferBarrierFlags renderPassXferBarriers,
                             GrLoadOp colorLoadOp)
        : fNeedsStencil(targetView.asRenderTargetProxy()->needsStencil())
        , fBackendFormat(targetView.proxy()->backendFormat())
        , fOrigin(targetView.origin())
        , fTargetHasVkResolveAttachmentWithInput(
                  targetView.asRenderTargetProxy()->supportsVkInputAttachment() &&
                  ((targetView.asRenderTargetProxy()->numSamples() > 1 &&
                    targetView.asTextureProxy()) ||
                   targetView.asRenderTargetProxy()->numSamples() == 1))
        , fTargetsNumSamples(targetView.asRenderTargetProxy()->numSamples())
        , fPipeline(pipeline)
        , fUserStencilSettings(userStencilSettings)
        , fGeomProc(geomProc)
        , fPrimitiveType(primitiveType)
        , fRenderPassXferBarriers(renderPassXferBarriers)
        , fColorLoadOp(colorLoadOp) {
    SkASSERT(fTargetsNumSamples > 0);
    fNumSamples = fTargetsNumSamples;
    if (fNumSamples == 1 && usesMSAASurface) {
        fNumSamples = caps.internalMultisampleCount(this->backendFormat());
    }
    SkDEBUGCODE(this->validate(false);)
}

GrStencilSettings GrProgramInfo::nonGLStencilSettings() const {
    GrStencilSettings stencil;

    if (this->isStencilEnabled()) {
        stencil.reset(*fUserStencilSettings, this->pipeline().hasStencilClip(), 8);
    }

    return stencil;
}

#ifdef SK_DEBUG

void GrProgramInfo::validate(bool flushTime) const {
    if (flushTime) {
        SkASSERT(fPipeline->allProxiesInstantiated());
    }
}

void GrProgramInfo::checkAllInstantiated() const {
    this->pipeline().visitProxies([](GrSurfaceProxy* proxy, skgpu::Mipmapped) {
        SkASSERT(proxy->isInstantiated());
        return true;
    });
}

void GrProgramInfo::checkMSAAAndMIPSAreResolved() const {
    this->pipeline().visitTextureEffects([](const GrTextureEffect& te) {
        GrTexture* tex = te.texture();
        SkASSERT(tex);

        // Ensure mipmaps were all resolved ahead of time by the DAG.
        if (te.samplerState().mipmapped() == skgpu::Mipmapped::kYes &&
            (tex->width() != 1 || tex->height() != 1)) {
            // There are some cases where we might be given a non-mipmapped texture with a
            // mipmap filter. See skbug.com/40038328.
            SkASSERT(tex->mipmapped() != skgpu::Mipmapped::kYes || !tex->mipmapsAreDirty());
        }
    });
}

#endif
