1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "include/gpu/GrRecordingContext.h"
9#include "src/gpu/GrColorSpaceXform.h"
10#include "src/gpu/GrGpu.h"
11#include "src/gpu/GrProxyProvider.h"
12#include "src/gpu/GrRecordingContextPriv.h"
13#include "src/gpu/GrTextureAdjuster.h"
14#include "src/gpu/SkGr.h"
15
16GrTextureAdjuster::GrTextureAdjuster(GrRecordingContext* context,
17 GrSurfaceProxyView original,
18 const GrColorInfo& colorInfo,
19 uint32_t uniqueID)
20 : INHERITED(context, {colorInfo, original.proxy()->dimensions()})
21 , fOriginal(std::move(original))
22 , fUniqueID(uniqueID) {}
23
24GrSurfaceProxyView GrTextureAdjuster::makeMippedCopy() {
25 GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider();
26
27 GrUniqueKey baseKey, mipMappedKey;
28 GrMakeKeyFromImageID(&baseKey, fUniqueID, SkIRect::MakeSize(this->dimensions()));
29 if (baseKey.isValid()) {
30 static const GrUniqueKey::Domain kMipMappedDomain = GrUniqueKey::GenerateDomain();
31 GrUniqueKey::Builder builder(&mipMappedKey, baseKey, kMipMappedDomain, 0);
32 }
33 sk_sp<GrTextureProxy> cachedCopy;
34 if (mipMappedKey.isValid()) {
35 cachedCopy = proxyProvider->findOrCreateProxyByUniqueKey(mipMappedKey);
36 if (cachedCopy) {
37 return {std::move(cachedCopy), fOriginal.origin(), fOriginal.swizzle()};
38 }
39 }
40
41 auto copy = GrCopyBaseMipMapToView(this->context(), fOriginal);
42 if (!copy) {
43 return {};
44 }
45 if (mipMappedKey.isValid()) {
46 // TODO: If we move listeners up from SkImage_Lazy to SkImage_Base then add one here.
47 proxyProvider->assignUniqueKeyToProxy(mipMappedKey, copy.asTextureProxy());
48 }
49 return copy;
50}
51
52GrSurfaceProxyView GrTextureAdjuster::onView(GrMipmapped mipMapped) {
53 if (this->context()->abandoned()) {
54 // The texture was abandoned.
55 return {};
56 }
57
58 SkASSERT(this->width() <= this->context()->priv().caps()->maxTextureSize() &&
59 this->height() <= this->context()->priv().caps()->maxTextureSize());
60
61 GrTextureProxy* texProxy = fOriginal.asTextureProxy();
62 SkASSERT(texProxy);
63 if (mipMapped == GrMipmapped::kNo || texProxy->mipmapped() == GrMipmapped::kYes) {
64 return fOriginal;
65 }
66
67 GrSurfaceProxyView copy = this->makeMippedCopy();
68 if (!copy) {
69 // If we were unable to make a copy and we only needed a copy for mips, then we will return
70 // the source texture here and require that the GPU backend is able to fall back to using
71 // linear filtering if mips are required.
72 return fOriginal;
73 }
74 SkASSERT(copy.asTextureProxy());
75 return copy;
76}
77
78std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
79 const SkMatrix& textureMatrix,
80 const SkRect* subset,
81 const SkRect* domain,
82 GrSamplerState samplerState) {
83 return this->createFragmentProcessorForView(
84 this->view(samplerState.mipmapped()), textureMatrix, subset, domain, samplerState);
85}
86
87std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createBicubicFragmentProcessor(
88 const SkMatrix& textureMatrix,
89 const SkRect* subset,
90 const SkRect* domain,
91 GrSamplerState::WrapMode wrapX,
92 GrSamplerState::WrapMode wrapY) {
93 return this->createBicubicFragmentProcessorForView(
94 this->view(GrMipmapped::kNo), textureMatrix, subset, domain, wrapX, wrapY);
95}
96