/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/GrTextureProducer.h"

#include "include/private/GrRecordingContext.h"
#include "src/core/SkMipMap.h"
#include "src/core/SkRectPriv.h"
#include "src/gpu/GrClip.h"
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/GrProxyProvider.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrTextureProxy.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/effects/GrBicubicEffect.h"
#include "src/gpu/effects/GrTextureDomain.h"
#include "src/gpu/effects/GrTextureEffect.h"

GrSurfaceProxyView GrTextureProducer::MakeMipMappedCopy(GrRecordingContext* context,
                                                        GrSurfaceProxyView inputView,
                                                        GrColorType colorType) {
    SkASSERT(context);
    SkASSERT(inputView.asTextureProxy());

    GrSurfaceProxy* proxy = inputView.proxy();
    SkRect proxyRect = proxy->getBoundsRect();

    GrSurfaceProxyView view =
            GrCopyBaseMipMapToTextureProxy(context, proxy, inputView.origin(), colorType);
    if (view) {
        return view;
    }

    auto copyRTC = GrRenderTargetContext::MakeWithFallback(
            context, colorType, nullptr, SkBackingFit::kExact, inputView.dimensions(), 1,
            GrMipMapped::kYes, proxy->isProtected(), inputView.origin());
    if (!copyRTC) {
        return {};
    }

    GrPaint paint;
    auto fp = GrTextureEffect::Make(std::move(inputView), kUnknown_SkAlphaType, SkMatrix::I(),
                                    GrSamplerState::Filter::kNearest);
    paint.addColorFragmentProcessor(std::move(fp));
    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);

    copyRTC->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), proxyRect);
    return copyRTC->readSurfaceView();
}

/** Determines whether a texture domain is necessary and if so what domain to use. There are two
 *  rectangles to consider:
 *  - The first is the content area specified by the texture adjuster (i.e., textureContentArea).
 *    We can *never* allow filtering to cause bleed of pixels outside this rectangle.
 *  - The second rectangle is the constraint rectangle (i.e., constraintRect), which is known to
 *    be contained by the content area. The filterConstraint specifies whether we are allowed to
 *    bleed across this rect.
 *
 *  We want to avoid using a domain if possible. We consider the above rectangles, the filter type,
 *  and whether the coords generated by the draw would all fall within the constraint rect. If the
 *  latter is true we only need to consider whether the filter would extend beyond the rects.
 */
GrTextureProducer::DomainMode GrTextureProducer::DetermineDomainMode(
        const SkRect& constraintRect,
        FilterConstraint filterConstraint,
        bool coordsLimitedToConstraintRect,
        GrSurfaceProxy* proxy,
        const GrSamplerState::Filter* filterModeOrNullForBicubic,
        SkRect* domainRect) {
    const SkIRect proxyBounds = SkIRect::MakeSize(proxy->dimensions());

    SkASSERT(proxyBounds.contains(constraintRect));

    const bool proxyIsExact = proxy->isFunctionallyExact();

    // If the constraint rectangle contains the whole proxy then no need for a domain.
    if (constraintRect.contains(proxyBounds) && proxyIsExact) {
        return kNoDomain_DomainMode;
    }

    bool restrictFilterToRect = (filterConstraint == GrTextureProducer::kYes_FilterConstraint);

    // If we can filter outside the constraint rect, and there is no non-content area of the
    // proxy, and we aren't going to generate sample coords outside the constraint rect then we
    // don't need a domain.
    if (!restrictFilterToRect && proxyIsExact && coordsLimitedToConstraintRect) {
        return kNoDomain_DomainMode;
    }

    // Get the domain inset based on sampling mode (or bail if mipped). This is used
    // to evaluate whether we will read outside a non-exact proxy's dimensions.
    // TODO: Let GrTextureEffect handle this.
    SkScalar filterHalfWidth = 0.f;
    if (filterModeOrNullForBicubic) {
        switch (*filterModeOrNullForBicubic) {
            case GrSamplerState::Filter::kNearest:
                if (coordsLimitedToConstraintRect) {
                    return kNoDomain_DomainMode;
                } else {
                    filterHalfWidth = 0.f;
                }
                break;
            case GrSamplerState::Filter::kBilerp:
                filterHalfWidth = .5f;
                break;
            case GrSamplerState::Filter::kMipMap:
                if (restrictFilterToRect || !proxyIsExact) {
                    // No domain can save us here.
                    return kTightCopy_DomainMode;
                }
                return kNoDomain_DomainMode;
        }
    } else {
        // bicubic does nearest filtering internally.
        filterHalfWidth = 1.5f;
    }

    if (restrictFilterToRect) {
        *domainRect = constraintRect;
    } else if (!proxyIsExact) {
        // If we got here then: proxy is not exact, the coords are limited to the
        // constraint rect, and we're allowed to filter across the constraint rect boundary. So
        // we check whether the filter would reach across the edge of the proxy.
        // We will only set the sides that are required.

        *domainRect = SkRectPriv::MakeLargest();
        if (coordsLimitedToConstraintRect) {
            // We may be able to use the fact that the texture coords are limited to the constraint
            // rect in order to avoid having to add a domain.
            bool needContentAreaConstraint = false;
            if (proxyBounds.fRight - filterHalfWidth < constraintRect.fRight) {
                domainRect->fRight = proxyBounds.fRight;
                needContentAreaConstraint = true;
            }
            if (proxyBounds.fBottom - filterHalfWidth < constraintRect.fBottom) {
                domainRect->fBottom = proxyBounds.fBottom;
                needContentAreaConstraint = true;
            }
            if (!needContentAreaConstraint) {
                return kNoDomain_DomainMode;
            }
        }
    } else {
        return kNoDomain_DomainMode;
    }

    if (!filterModeOrNullForBicubic) {
        // Bicubic doesn't yet rely on GrTextureEffect to do this insetting.
        domainRect->inset(0.5f, 0.5f);
        if (domainRect->fLeft > domainRect->fRight) {
            domainRect->fLeft = domainRect->fRight =
                    SkScalarAve(domainRect->fLeft, domainRect->fRight);
        }
        if (domainRect->fTop > domainRect->fBottom) {
            domainRect->fTop = domainRect->fBottom =
                    SkScalarAve(domainRect->fTop, domainRect->fBottom);
        }
    }

    return kDomain_DomainMode;
}

std::unique_ptr<GrFragmentProcessor> GrTextureProducer::createFragmentProcessorForDomainAndFilter(
        GrSurfaceProxyView view,
        const SkMatrix& textureMatrix,
        DomainMode domainMode,
        const SkRect& domain,
        const GrSamplerState::Filter* filterOrNullForBicubic) {
    SkASSERT(kTightCopy_DomainMode != domainMode);
    SkASSERT(view.asTextureProxy());
    const auto& caps = *fContext->priv().caps();
    SkAlphaType srcAlphaType = this->alphaType();
    auto wm = fDomainNeedsDecal ? GrSamplerState::WrapMode::kClampToBorder
                                : GrSamplerState::WrapMode::kClamp;
    if (filterOrNullForBicubic) {
        GrSamplerState samplerState(wm, *filterOrNullForBicubic);
        if (kNoDomain_DomainMode == domainMode) {
            return GrTextureEffect::Make(std::move(view), srcAlphaType, textureMatrix, samplerState,
                                         caps);
        }
        return GrTextureEffect::MakeSubset(std::move(view), srcAlphaType, textureMatrix,
                                           samplerState, domain, caps);
    } else {

        static constexpr auto kDir = GrBicubicEffect::Direction::kXY;
        const auto& caps = *fContext->priv().caps();
        if (kDomain_DomainMode == domainMode) {
            return GrBicubicEffect::MakeSubset(std::move(view), srcAlphaType, textureMatrix, wm, wm,
                                               domain, kDir, caps);
        } else {
            return GrBicubicEffect::Make(std::move(view), srcAlphaType, textureMatrix, wm, wm, kDir,
                                         caps);
        }
    }
}

GrSurfaceProxyView GrTextureProducer::viewForParams(
        const GrSamplerState::Filter* filterOrNullForBicubic) {
    GrSamplerState sampler; // Default is nearest + clamp
    if (filterOrNullForBicubic) {
        sampler.setFilterMode(*filterOrNullForBicubic);
    }
    if (fDomainNeedsDecal) {
        // Assuming hardware support, switch to clamp-to-border instead of clamp
        if (fContext->priv().caps()->clampToBorderSupport()) {
            sampler.setWrapModeX(GrSamplerState::WrapMode::kClampToBorder);
            sampler.setWrapModeY(GrSamplerState::WrapMode::kClampToBorder);
        }
    }
    return this->viewForParams(sampler);
}

GrSurfaceProxyView GrTextureProducer::viewForParams(GrSamplerState sampler) {
    const GrCaps* caps = this->context()->priv().caps();

    int mipCount = SkMipMap::ComputeLevelCount(this->width(), this->height());
    bool willBeMipped = GrSamplerState::Filter::kMipMap == sampler.filter() && mipCount &&
                        caps->mipMapSupport();

    auto result = this->onRefTextureProxyViewForParams(sampler, willBeMipped);
    if (!result) {
        return {};
    }

    SkASSERT(result.asTextureProxy());

    // Check to make sure that if we say the texture willBeMipped that the returned texture has mip
    // maps, unless the config is not copyable.
    SkASSERT(!willBeMipped || result.asTextureProxy()->mipMapped() == GrMipMapped::kYes ||
             !caps->isFormatCopyable(result.proxy()->backendFormat()));

    SkASSERT(result.proxy()->dimensions() == this->dimensions());

    return result;
}

std::pair<GrSurfaceProxyView, GrColorType> GrTextureProducer::view(GrMipMapped willNeedMips) {
    GrSamplerState::Filter filter =
            GrMipMapped::kNo == willNeedMips ? GrSamplerState::Filter::kNearest
                                             : GrSamplerState::Filter::kMipMap;
    GrSamplerState sampler(GrSamplerState::WrapMode::kClamp, filter);

    auto result = this->viewForParams(sampler);

#ifdef SK_DEBUG
    const GrCaps* caps = this->context()->priv().caps();
    // Check that the resulting proxy format is compatible with the GrColorType of this producer
    SkASSERT(!result.proxy() ||
             result.proxy()->isFormatCompressed(caps) ||
             caps->areColorTypeAndFormatCompatible(this->colorType(),
                                                   result.proxy()->backendFormat()));
#endif

    return {result, this->colorType()};
}
