summaryrefslogtreecommitdiffstats
path: root/gfx/skia/skia/src/gpu/GrTextureMaker.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gfx/skia/skia/src/gpu/GrTextureMaker.cpp142
1 files changed, 142 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/gpu/GrTextureMaker.cpp b/gfx/skia/skia/src/gpu/GrTextureMaker.cpp
new file mode 100644
index 0000000000..fa428ed0fb
--- /dev/null
+++ b/gfx/skia/skia/src/gpu/GrTextureMaker.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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"
+
+sk_sp<GrTextureProxy> GrTextureMaker::onRefTextureProxyForParams(const GrSamplerState& params,
+ bool willBeMipped,
+ SkScalar scaleAdjust[2]) {
+ if (this->width() > this->context()->priv().caps()->maxTextureSize() ||
+ this->height() > this->context()->priv().caps()->maxTextureSize()) {
+ return nullptr;
+ }
+
+ CopyParams copyParams;
+
+ sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped,
+ AllowedTexGenType::kCheap));
+ bool needsCopyForMipsOnly = false;
+ if (original) {
+ if (!params.isRepeated() ||
+ !GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), original.get(),
+ original->width(), original->height(),
+ params.filter(), &copyParams, scaleAdjust)) {
+ needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips(this->context()->priv().caps(),
+ original.get(), params.filter(),
+ &copyParams);
+ if (!needsCopyForMipsOnly) {
+ return original;
+ }
+ }
+ } else {
+ if (!params.isRepeated() ||
+ !GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), nullptr,
+ this->width(), this->height(),
+ params.filter(), &copyParams, scaleAdjust)) {
+ return this->refOriginalTextureProxy(willBeMipped, AllowedTexGenType::kAny);
+ }
+ }
+
+ GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider();
+
+ GrSurfaceOrigin origOrigin = original ? original->origin() : kTopLeft_GrSurfaceOrigin;
+ GrUniqueKey copyKey;
+ this->makeCopyKey(copyParams, &copyKey);
+ sk_sp<GrTextureProxy> cachedProxy;
+ if (copyKey.isValid()) {
+ cachedProxy =
+ proxyProvider->findOrCreateProxyByUniqueKey(copyKey, this->colorType(), origOrigin);
+ if (cachedProxy && (!willBeMipped || GrMipMapped::kYes == cachedProxy->mipMapped())) {
+ return cachedProxy;
+ }
+ }
+
+ sk_sp<GrTextureProxy> source;
+ if (original) {
+ source = std::move(original);
+ } else if (cachedProxy) {
+ source = cachedProxy;
+ } else {
+ // Since we will be copying this texture there is no reason to make it mipped
+ source = this->refOriginalTextureProxy(false, AllowedTexGenType::kAny);
+ }
+
+ if (!source) {
+ return nullptr;
+ }
+
+ sk_sp<GrTextureProxy> result =
+ CopyOnGpu(this->context(), source, this->colorType(), copyParams, willBeMipped);
+
+ 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.
+ if (needsCopyForMipsOnly) {
+ return source;
+ }
+ return nullptr;
+ }
+
+ if (copyKey.isValid()) {
+ SkASSERT(result->origin() == origOrigin);
+ if (cachedProxy) {
+ SkASSERT(GrMipMapped::kYes == result->mipMapped() &&
+ GrMipMapped::kNo == cachedProxy->mipMapped());
+ // If we had a cachedProxy, that means there already is a proxy in the cache which
+ // matches the key, but it does not have mip levels and we require them. Thus we must
+ // remove the unique key from that proxy.
+ SkASSERT(cachedProxy->getUniqueKey() == copyKey);
+ proxyProvider->removeUniqueKeyFromProxy(cachedProxy.get());
+ }
+ proxyProvider->assignUniqueKeyToProxy(copyKey, result.get());
+ this->didCacheCopy(copyKey, 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;
+ }
+
+ SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
+ sk_sp<GrTextureProxy> proxy(this->refTextureProxyForParams(filterOrNullForBicubic,
+ scaleAdjust));
+ if (!proxy) {
+ return nullptr;
+ }
+ SkMatrix adjustedMatrix = textureMatrix;
+ adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
+
+ SkRect domain;
+ DomainMode domainMode =
+ DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
+ proxy.get(), fmForDetermineDomain, &domain);
+ SkASSERT(kTightCopy_DomainMode != domainMode);
+ return this->createFragmentProcessorForDomainAndFilter(
+ std::move(proxy), adjustedMatrix, domainMode, domain, filterOrNullForBicubic);
+}