/*
 * 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 "GrTextureProducer.h"
#include "GrClip.h"
#include "GrRenderTargetContext.h"
#include "GrResourceProvider.h"
#include "GrSurfaceProxy.h"
#include "GrSurfaceProxyPriv.h"
#include "GrTexture.h"
#include "effects/GrBicubicEffect.h"
#include "effects/GrSimpleTextureEffect.h"
#include "effects/GrTextureDomain.h"

sk_sp<GrTextureProxy> GrTextureProducer::CopyOnGpu(GrContext* context,
                                                   sk_sp<GrTextureProxy> inputProxy,
                                                   const SkIRect* subset,
                                                   const CopyParams& copyParams) {
    SkASSERT(!subset || !subset->isEmpty());
    SkASSERT(context);

    const SkRect dstRect = SkRect::MakeIWH(copyParams.fWidth, copyParams.fHeight);

    sk_sp<GrRenderTargetContext> copyRTC = context->makeDeferredRenderTargetContextWithFallback(
        SkBackingFit::kExact, dstRect.width(), dstRect.height(), inputProxy->config(), nullptr);
    if (!copyRTC) {
        return nullptr;
    }

    GrPaint paint;
    paint.setGammaCorrect(true);

    SkRect localRect;
    if (subset) {
        localRect = SkRect::Make(*subset);
    } else {
        localRect = SkRect::MakeWH(inputProxy->width(), inputProxy->height());
    }

    bool needsDomain = false;
    if (copyParams.fFilter != GrSamplerParams::kNone_FilterMode) {
        bool resizing = localRect.width()  != dstRect.width() ||
                        localRect.height() != dstRect.height();

        if (GrResourceProvider::IsFunctionallyExact(inputProxy.get())) {
            needsDomain = subset && resizing;
        } else {
            needsDomain = resizing;
        }
    }

    if (needsDomain) {
        const SkRect domain = localRect.makeInset(0.5f, 0.5f);
        // This would cause us to read values from outside the subset. Surely, the caller knows
        // better!
        SkASSERT(copyParams.fFilter != GrSamplerParams::kMipMap_FilterMode);
        paint.addColorFragmentProcessor(
            GrTextureDomainEffect::Make(context->resourceProvider(), std::move(inputProxy),
                                        nullptr, SkMatrix::I(),
                                        domain, GrTextureDomain::kClamp_Mode, copyParams.fFilter));
    } else {
        GrSamplerParams params(SkShader::kClamp_TileMode, copyParams.fFilter);
        paint.addColorTextureProcessor(context->resourceProvider(), std::move(inputProxy),
                                       nullptr, SkMatrix::I(), params);
    }
    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);

    copyRTC->fillRectToRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), dstRect,
                            localRect);
    return copyRTC->asTextureProxyRef();
}

/** 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,
                                GrTextureProxy* proxy,
                                const SkIRect* contentRect,
                                const GrSamplerParams::FilterMode* filterModeOrNullForBicubic,
                                SkRect* domainRect) {
    const SkIRect proxyBounds = SkIRect::MakeWH(proxy->width(), proxy->height());

    SkASSERT(proxyBounds.contains(constraintRect));
    // We only expect a content area rect if there is some non-content area.
    SkASSERT(!contentRect ||
             (!contentRect->contains(proxyBounds) &&
              proxyBounds.contains(*contentRect) &&
              contentRect->contains(constraintRect)));

    const bool proxyIsExact = GrResourceProvider::IsFunctionallyExact(proxy);

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

    if (!contentRect && !proxyIsExact) {
        contentRect = &proxyBounds;
    }

    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 && !contentRect && coordsLimitedToConstraintRect) {
        return kNoDomain_DomainMode;
    }

    // Get the domain inset based on sampling mode (or bail if mipped)
    SkScalar filterHalfWidth = 0.f;
    if (filterModeOrNullForBicubic) {
        switch (*filterModeOrNullForBicubic) {
            case GrSamplerParams::kNone_FilterMode:
                if (coordsLimitedToConstraintRect) {
                    return kNoDomain_DomainMode;
                } else {
                    filterHalfWidth = 0.f;
                }
                break;
            case GrSamplerParams::kBilerp_FilterMode:
                filterHalfWidth = .5f;
                break;
            case GrSamplerParams::kMipMap_FilterMode:
                if (restrictFilterToRect || contentRect) {
                    // No domain can save us here.
                    return kTightCopy_DomainMode;
                }
                return kNoDomain_DomainMode;
        }
    } else {
        // bicubic does nearest filtering internally.
        filterHalfWidth = 1.5f;
    }

    // Both bilerp and bicubic use bilinear filtering and so need to be clamped to the center
    // of the edge texel. Pinning to the texel center has no impact on nearest mode and MIP-maps

    static const SkScalar kDomainInset = 0.5f;
    // Figure out the limits of pixels we're allowed to sample from.
    // Unless we know the amount of outset and the texture matrix we have to conservatively enforce
    // the domain.
    if (restrictFilterToRect) {
        *domainRect = constraintRect.makeInset(kDomainInset, kDomainInset);
    } else if (contentRect) {
        // If we got here then: there is a contentRect, 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 content area.
        // We will only set the sides that are required.

        domainRect->setLargest();
        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 (contentRect->fLeft > 0 &&
                contentRect->fLeft + filterHalfWidth > constraintRect.fLeft) {
                domainRect->fLeft = contentRect->fLeft + kDomainInset;
                needContentAreaConstraint = true;
            }
            if (contentRect->fTop > 0 &&
                contentRect->fTop + filterHalfWidth > constraintRect.fTop) {
                domainRect->fTop = contentRect->fTop + kDomainInset;
                needContentAreaConstraint = true;
            }
            if ((!proxyIsExact || contentRect->fRight < proxy->width()) &&
                contentRect->fRight - filterHalfWidth < constraintRect.fRight) {
                domainRect->fRight = contentRect->fRight - kDomainInset;
                needContentAreaConstraint = true;
            }
            if ((!proxyIsExact || contentRect->fBottom < proxy->height()) &&
                contentRect->fBottom - filterHalfWidth < constraintRect.fBottom) {
                domainRect->fBottom = contentRect->fBottom - kDomainInset;
                needContentAreaConstraint = true;
            }
            if (!needContentAreaConstraint) {
                return kNoDomain_DomainMode;
            }
        } else {
            // Our sample coords for the texture are allowed to be outside the constraintRect so we
            // don't consider it when computing the domain.
            if (contentRect->fLeft > 0) {
                domainRect->fLeft = contentRect->fLeft + kDomainInset;
            }
            if (contentRect->fTop > 0) {
                domainRect->fTop = contentRect->fTop + kDomainInset;
            }
            if (!proxyIsExact || contentRect->fRight < proxy->width()) {
                domainRect->fRight = contentRect->fRight - kDomainInset;
            }
            if (!proxyIsExact || contentRect->fBottom < proxy->height()) {
                domainRect->fBottom = contentRect->fBottom - kDomainInset;
            }
        }
    } else {
        return kNoDomain_DomainMode;
    }

    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;
}

sk_sp<GrFragmentProcessor> GrTextureProducer::CreateFragmentProcessorForDomainAndFilter(
                                        GrResourceProvider* resourceProvider,
                                        sk_sp<GrTextureProxy> proxy,
                                        sk_sp<GrColorSpaceXform> colorSpaceXform,
                                        const SkMatrix& textureMatrix,
                                        DomainMode domainMode,
                                        const SkRect& domain,
                                        const GrSamplerParams::FilterMode* filterOrNullForBicubic) {
    SkASSERT(kTightCopy_DomainMode != domainMode);
    if (filterOrNullForBicubic) {
        if (kDomain_DomainMode == domainMode) {
            return GrTextureDomainEffect::Make(resourceProvider, std::move(proxy),
                                               std::move(colorSpaceXform), textureMatrix,
                                               domain, GrTextureDomain::kClamp_Mode,
                                               *filterOrNullForBicubic);
        } else {
            GrSamplerParams params(SkShader::kClamp_TileMode, *filterOrNullForBicubic);
            return GrSimpleTextureEffect::Make(resourceProvider, std::move(proxy),
                                               std::move(colorSpaceXform), textureMatrix,
                                               params);
        }
    } else {
        if (kDomain_DomainMode == domainMode) {
            return GrBicubicEffect::Make(resourceProvider, std::move(proxy),
                                         std::move(colorSpaceXform),
                                         textureMatrix, domain);
        } else {
            static const SkShader::TileMode kClampClamp[] =
                { SkShader::kClamp_TileMode, SkShader::kClamp_TileMode };
            return GrBicubicEffect::Make(resourceProvider, std::move(proxy),
                                         std::move(colorSpaceXform),
                                         textureMatrix, kClampClamp);
        }
    }
}
