@@ -22,47 +22,65 @@ GrTextureAdjuster::GrTextureAdjuster(GrRecordingContext* context,
22
22
, fOriginal(std::move(original))
23
23
, fUniqueID(uniqueID) {}
24
24
25
- void GrTextureAdjuster::makeMipMappedKey ( GrUniqueKey* mipMappedKey ) {
25
+ void GrTextureAdjuster::makeCopyKey ( const CopyParams& params, GrUniqueKey* copyKey ) {
26
26
// Destination color space is irrelevant - we already have a texture so we're just sub-setting
27
27
GrUniqueKey baseKey;
28
28
GrMakeKeyFromImageID (&baseKey, fUniqueID , SkIRect::MakeSize (this ->dimensions ()));
29
- MakeMipMappedKeyFromOriginalKey (baseKey, mipMappedKey );
29
+ MakeCopyKeyFromOrigKey (baseKey, params, copyKey );
30
30
}
31
31
32
- void GrTextureAdjuster::didCacheMipMappedCopy (const GrUniqueKey& mipMappedKey,
33
- uint32_t contextUniqueID) {
32
+ void GrTextureAdjuster::didCacheCopy (const GrUniqueKey& copyKey, uint32_t contextUniqueID) {
34
33
// We don't currently have a mechanism for notifications on Images!
35
34
}
36
35
37
- GrSurfaceProxyView GrTextureAdjuster::makeMippedCopy () {
36
+ GrSurfaceProxyView GrTextureAdjuster::copy (const CopyParams& copyParams, bool willBeMipped,
37
+ bool copyForMipsOnly) {
38
38
GrProxyProvider* proxyProvider = this ->context ()->priv ().proxyProvider ();
39
39
40
40
GrUniqueKey key;
41
- this ->makeMipMappedKey ( &key);
41
+ this ->makeCopyKey (copyParams, &key);
42
42
sk_sp<GrTextureProxy> cachedCopy;
43
43
const GrSurfaceProxyView& originalView = this ->originalProxyView ();
44
44
if (key.isValid ()) {
45
45
cachedCopy = proxyProvider->findOrCreateProxyByUniqueKey (key, this ->colorType ());
46
- if (cachedCopy) {
47
- return {std::move (cachedCopy), originalView.origin (), originalView.swizzle ()};
46
+ if (cachedCopy && (!willBeMipped || GrMipMapped::kYes == cachedCopy->mipMapped ())) {
47
+ // TODO: Once we no longer use CopyOnGpu which can fallback to arbitrary formats and
48
+ // colorTypes, we can use the swizzle of the originalView.
49
+ GrSwizzle swizzle = cachedCopy->textureSwizzleDoNotUse ();
50
+ return GrSurfaceProxyView (std::move (cachedCopy), originalView.origin (), swizzle);
48
51
}
49
52
}
50
53
51
- GrSurfaceProxyView copyView = GrCopyBaseMipMapToTextureProxy (
52
- this ->context (), originalView.proxy (), originalView.origin (), this ->colorType ());
53
- if (!copyView) {
54
- return {};
54
+ GrSurfaceProxyView copyView;
55
+ if (copyForMipsOnly) {
56
+ copyView = GrCopyBaseMipMapToTextureProxy (this ->context (), originalView.proxy (),
57
+ originalView.origin (), this ->colorType ());
58
+ } else {
59
+ copyView = CopyOnGpu (this ->context (), this ->originalProxyViewRef (), this ->colorType (),
60
+ copyParams, willBeMipped);
55
61
}
56
- if (key.isValid ()) {
57
- SkASSERT (copyView.origin () == originalView.origin ());
58
- proxyProvider->assignUniqueKeyToProxy (key, copyView.asTextureProxy ());
59
- this ->didCacheMipMappedCopy (key, proxyProvider->contextID ());
62
+ if (copyView.proxy ()) {
63
+ if (key.isValid ()) {
64
+ SkASSERT (copyView.origin () == originalView.origin ());
65
+ if (cachedCopy) {
66
+ SkASSERT (GrMipMapped::kYes == copyView.asTextureProxy ()->mipMapped () &&
67
+ GrMipMapped::kNo == cachedCopy->mipMapped ());
68
+ // If we had a cachedProxy, that means there already is a proxy in the cache which
69
+ // matches the key, but it does not have mip levels and we require them. Thus we
70
+ // must remove the unique key from that proxy.
71
+ SkASSERT (cachedCopy->getUniqueKey () == key);
72
+ proxyProvider->removeUniqueKeyFromProxy (cachedCopy.get ());
73
+ }
74
+ proxyProvider->assignUniqueKeyToProxy (key, copyView.asTextureProxy ());
75
+ this ->didCacheCopy (key, proxyProvider->contextID ());
76
+ }
60
77
}
61
78
return copyView;
62
79
}
63
80
64
81
GrSurfaceProxyView GrTextureAdjuster::onRefTextureProxyViewForParams (GrSamplerState params,
65
- bool willBeMipped) {
82
+ bool willBeMipped,
83
+ SkScalar scaleAdjust[2 ]) {
66
84
if (this ->context ()->priv ().abandoned ()) {
67
85
// The texture was abandoned.
68
86
return {};
@@ -74,32 +92,51 @@ GrSurfaceProxyView GrTextureAdjuster::onRefTextureProxyViewForParams(GrSamplerSt
74
92
GrSurfaceProxyView view = this ->originalProxyViewRef ();
75
93
GrTextureProxy* texProxy = view.asTextureProxy ();
76
94
SkASSERT (texProxy);
77
- if (!GrGpu::IsACopyNeededForMips (this ->context ()->priv ().caps (), texProxy, params.filter ())) {
78
- return view;
95
+ CopyParams copyParams;
96
+
97
+ bool needsCopyForMipsOnly = false ;
98
+ if (!params.isRepeated () ||
99
+ !GrGpu::IsACopyNeededForRepeatWrapMode (this ->context ()->priv ().caps (), texProxy,
100
+ texProxy->dimensions (), params.filter (), ©Params,
101
+ scaleAdjust)) {
102
+ needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips (this ->context ()->priv ().caps (),
103
+ texProxy, params.filter (),
104
+ ©Params);
105
+ if (!needsCopyForMipsOnly) {
106
+ return view;
107
+ }
79
108
}
80
109
81
- GrSurfaceProxyView copy = this ->makeMippedCopy ( );
82
- if (!copy ) {
110
+ GrSurfaceProxyView result = this ->copy (copyParams, willBeMipped, needsCopyForMipsOnly );
111
+ if (!result. proxy () && needsCopyForMipsOnly ) {
83
112
// If we were unable to make a copy and we only needed a copy for mips, then we will return
84
113
// the source texture here and require that the GPU backend is able to fall back to using
85
114
// bilerp if mips are required.
86
115
return view;
87
116
}
88
- SkASSERT (copy .asTextureProxy ());
89
- return copy ;
117
+ SkASSERT (result .asTextureProxy ());
118
+ return result ;
90
119
}
91
120
92
121
std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor (
93
- const SkMatrix& textureMatrix ,
122
+ const SkMatrix& origTextureMatrix ,
94
123
const SkRect& constraintRect,
95
124
FilterConstraint filterConstraint,
96
125
bool coordsLimitedToConstraintRect,
97
126
const GrSamplerState::Filter* filterOrNullForBicubic) {
98
- GrSurfaceProxyView view = this ->viewForParams (filterOrNullForBicubic);
99
- if (!view) {
127
+ SkMatrix textureMatrix = origTextureMatrix;
128
+
129
+ SkScalar scaleAdjust[2 ] = { 1 .0f , 1 .0f };
130
+ GrSurfaceProxyView view = this ->viewForParams (filterOrNullForBicubic, scaleAdjust);
131
+ if (!view.proxy ()) {
100
132
return nullptr ;
101
133
}
102
134
SkASSERT (view.asTextureProxy ());
135
+ // If we made a copy then we only copied the contentArea, in which case the new texture is all
136
+ // content.
137
+ if (view.proxy () != this ->originalProxyView ().proxy ()) {
138
+ textureMatrix.postScale (scaleAdjust[0 ], scaleAdjust[1 ]);
139
+ }
103
140
104
141
SkRect domain;
105
142
DomainMode domainMode =
0 commit comments