blob: d9e89c2113590a56596e89286b3d268d0eab28d5 [file] [log] [blame]
/*
* 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/GrTextureMaker.h"
#include "include/private/GrRecordingContext.h"
#include "src/gpu/GrColorSpaceXform.h"
#include "src/gpu/GrGpu.h"
#include "src/gpu/GrProxyProvider.h"
#include "src/gpu/GrRecordingContextPriv.h"
GrSurfaceProxyView GrTextureMaker::onRefTextureProxyViewForParams(GrSamplerState params,
bool willBeMipped) {
if (this->width() > this->context()->priv().caps()->maxTextureSize() ||
this->height() > this->context()->priv().caps()->maxTextureSize()) {
return {};
}
GrSurfaceProxyView original = this->refOriginalTextureProxyView(willBeMipped,
AllowedTexGenType::kCheap);
if (!original) {
return this->refOriginalTextureProxyView(willBeMipped, AllowedTexGenType::kAny);
}
GrTextureProxy* texProxy = original.asTextureProxy();
if (!GrGpu::IsACopyNeededForMips(this->context()->priv().caps(), texProxy, params.filter())) {
return original;
}
GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider();
GrSurfaceOrigin origOrigin = original.proxy() ? original.origin() : kTopLeft_GrSurfaceOrigin;
GrUniqueKey mipMappedKey;
this->makeMipMappedKey(&mipMappedKey);
if (mipMappedKey.isValid()) {
auto cachedProxy =
proxyProvider->findOrCreateProxyByUniqueKey(mipMappedKey, this->colorType());
if (cachedProxy) {
SkASSERT(cachedProxy->mipMapped() == GrMipMapped::kYes);
// TODO: Once we no longer use MakeMipMappedCopy which can fallback to arbitrary formats
// and colorTypes, we can use the swizzle of the originalView.
GrSwizzle swizzle = cachedProxy->textureSwizzleDoNotUse();
return GrSurfaceProxyView(std::move(cachedProxy), origOrigin, swizzle);
}
}
GrSurfaceProxyView source;
if (original) {
source = std::move(original);
} else {
// Since we will be copying this texture there is no reason to make it mipped
source = this->refOriginalTextureProxyView(false, AllowedTexGenType::kAny);
if (!source) {
return {};
}
}
SkASSERT(source.asTextureProxy());
GrSurfaceProxyView result = MakeMipMappedCopy(this->context(), source, this->colorType());
if (!result) {
// If we were unable to make a copy and we only needed a copy for mips, then we will return
// the source texture here and require that the GPU backend is able to fall back to using
// bilerp if mips are required.
return source;
}
if (mipMappedKey.isValid()) {
SkASSERT(result.origin() == origOrigin);
proxyProvider->assignUniqueKeyToProxy(mipMappedKey, result.asTextureProxy());
this->didCacheMipMappedCopy(mipMappedKey, proxyProvider->contextID());
}
return result;
}
std::unique_ptr<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
const SkMatrix& textureMatrix,
const SkRect& constraintRect,
FilterConstraint filterConstraint,
bool coordsLimitedToConstraintRect,
const GrSamplerState::Filter* filterOrNullForBicubic) {
const GrSamplerState::Filter* fmForDetermineDomain = filterOrNullForBicubic;
if (filterOrNullForBicubic && GrSamplerState::Filter::kMipMap == *filterOrNullForBicubic &&
kYes_FilterConstraint == filterConstraint) {
// TODO: Here we should force a copy restricted to the constraintRect since MIP maps will
// read outside the constraint rect. However, as in the adjuster case, we aren't currently
// doing that.
// We instead we compute the domain as though were bilerping which is only correct if we
// only sample level 0.
static const GrSamplerState::Filter kBilerp = GrSamplerState::Filter::kBilerp;
fmForDetermineDomain = &kBilerp;
}
GrSurfaceProxyView view = this->viewForParams(filterOrNullForBicubic);
if (!view) {
return nullptr;
}
SkRect domain;
DomainMode domainMode =
DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
view.proxy(), fmForDetermineDomain, &domain);
SkASSERT(kTightCopy_DomainMode != domainMode);
return this->createFragmentProcessorForDomainAndFilter(
std::move(view), textureMatrix, domainMode, domain, filterOrNullForBicubic);
}