Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: src/effects/SkMagnifierImageFilter.cpp

Issue 1034733002: Implement approx-match support in image filter saveLayer() offscreen. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix comment Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkCanvas.cpp ('k') | src/gpu/SkGpuDevice.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 The Android Open Source Project 2 * Copyright 2012 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmap.h" 8 #include "SkBitmap.h"
9 #include "SkMagnifierImageFilter.h" 9 #include "SkMagnifierImageFilter.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
11 #include "SkReadBuffer.h" 11 #include "SkReadBuffer.h"
12 #include "SkWriteBuffer.h" 12 #include "SkWriteBuffer.h"
13 #include "SkValidationUtils.h" 13 #include "SkValidationUtils.h"
14 14
15 //////////////////////////////////////////////////////////////////////////////// 15 ////////////////////////////////////////////////////////////////////////////////
16 #if SK_SUPPORT_GPU 16 #if SK_SUPPORT_GPU
17 #include "GrInvariantOutput.h" 17 #include "GrInvariantOutput.h"
18 #include "effects/GrSingleTextureEffect.h" 18 #include "effects/GrSingleTextureEffect.h"
19 #include "gl/GrGLProcessor.h" 19 #include "gl/GrGLProcessor.h"
20 #include "gl/GrGLSL.h" 20 #include "gl/GrGLSL.h"
21 #include "gl/GrGLTexture.h" 21 #include "gl/GrGLTexture.h"
22 #include "gl/builders/GrGLProgramBuilder.h" 22 #include "gl/builders/GrGLProgramBuilder.h"
23 23
24 class GrMagnifierEffect : public GrSingleTextureEffect { 24 class GrMagnifierEffect : public GrSingleTextureEffect {
25 25
26 public: 26 public:
27 static GrFragmentProcessor* Create(GrTexture* texture, 27 static GrFragmentProcessor* Create(GrTexture* texture,
28 const SkRect& bounds,
reed2 2015/03/28 21:55:27 If we try to re-land this, lets add some dox for t
28 float xOffset, 29 float xOffset,
29 float yOffset, 30 float yOffset,
30 float xInvZoom, 31 float xInvZoom,
31 float yInvZoom, 32 float yInvZoom,
32 float xInvInset, 33 float xInvInset,
33 float yInvInset) { 34 float yInvInset) {
34 return SkNEW_ARGS(GrMagnifierEffect, (texture, 35 return SkNEW_ARGS(GrMagnifierEffect, (texture,
36 bounds,
35 xOffset, 37 xOffset,
36 yOffset, 38 yOffset,
37 xInvZoom, 39 xInvZoom,
38 yInvZoom, 40 yInvZoom,
39 xInvInset, 41 xInvInset,
40 yInvInset)); 42 yInvInset));
41 } 43 }
42 44
43 virtual ~GrMagnifierEffect() {}; 45 virtual ~GrMagnifierEffect() {};
44 46
45 const char* name() const override { return "Magnifier"; } 47 const char* name() const override { return "Magnifier"; }
46 48
47 void getGLProcessorKey(const GrGLCaps&, GrProcessorKeyBuilder*) const overri de; 49 void getGLProcessorKey(const GrGLCaps&, GrProcessorKeyBuilder*) const overri de;
48 50
49 GrGLFragmentProcessor* createGLInstance() const override; 51 GrGLFragmentProcessor* createGLInstance() const override;
50 52
53 const SkRect& bounds() const { return fBounds; }
51 float x_offset() const { return fXOffset; } 54 float x_offset() const { return fXOffset; }
52 float y_offset() const { return fYOffset; } 55 float y_offset() const { return fYOffset; }
53 float x_inv_zoom() const { return fXInvZoom; } 56 float x_inv_zoom() const { return fXInvZoom; }
54 float y_inv_zoom() const { return fYInvZoom; } 57 float y_inv_zoom() const { return fYInvZoom; }
55 float x_inv_inset() const { return fXInvInset; } 58 float x_inv_inset() const { return fXInvInset; }
56 float y_inv_inset() const { return fYInvInset; } 59 float y_inv_inset() const { return fYInvInset; }
57 60
58 private: 61 private:
59 GrMagnifierEffect(GrTexture* texture, 62 GrMagnifierEffect(GrTexture* texture,
63 const SkRect& bounds,
60 float xOffset, 64 float xOffset,
61 float yOffset, 65 float yOffset,
62 float xInvZoom, 66 float xInvZoom,
63 float yInvZoom, 67 float yInvZoom,
64 float xInvInset, 68 float xInvInset,
65 float yInvInset) 69 float yInvInset)
66 : GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMat rix(texture)) 70 : GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMat rix(texture))
71 , fBounds(bounds)
67 , fXOffset(xOffset) 72 , fXOffset(xOffset)
68 , fYOffset(yOffset) 73 , fYOffset(yOffset)
69 , fXInvZoom(xInvZoom) 74 , fXInvZoom(xInvZoom)
70 , fYInvZoom(yInvZoom) 75 , fYInvZoom(yInvZoom)
71 , fXInvInset(xInvInset) 76 , fXInvInset(xInvInset)
72 , fYInvInset(yInvInset) { 77 , fYInvInset(yInvInset) {
73 this->initClassID<GrMagnifierEffect>(); 78 this->initClassID<GrMagnifierEffect>();
74 } 79 }
75 80
76 bool onIsEqual(const GrFragmentProcessor&) const override; 81 bool onIsEqual(const GrFragmentProcessor&) const override;
77 82
78 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; 83 void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
79 84
80 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 85 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
81 86
87 SkRect fBounds;
82 float fXOffset; 88 float fXOffset;
83 float fYOffset; 89 float fYOffset;
84 float fXInvZoom; 90 float fXInvZoom;
85 float fYInvZoom; 91 float fYInvZoom;
86 float fXInvInset; 92 float fXInvInset;
87 float fYInvInset; 93 float fYInvInset;
88 94
89 typedef GrSingleTextureEffect INHERITED; 95 typedef GrSingleTextureEffect INHERITED;
90 }; 96 };
91 97
(...skipping 10 matching lines...) Expand all
102 const char* inputColor, 108 const char* inputColor,
103 const TransformedCoordsArray&, 109 const TransformedCoordsArray&,
104 const TextureSamplerArray&) override; 110 const TextureSamplerArray&) override;
105 111
106 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; 112 void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
107 113
108 private: 114 private:
109 UniformHandle fOffsetVar; 115 UniformHandle fOffsetVar;
110 UniformHandle fInvZoomVar; 116 UniformHandle fInvZoomVar;
111 UniformHandle fInvInsetVar; 117 UniformHandle fInvInsetVar;
118 UniformHandle fBoundsVar;
112 119
113 typedef GrGLFragmentProcessor INHERITED; 120 typedef GrGLFragmentProcessor INHERITED;
114 }; 121 };
115 122
116 GrGLMagnifierEffect::GrGLMagnifierEffect(const GrProcessor&) { 123 GrGLMagnifierEffect::GrGLMagnifierEffect(const GrProcessor&) {
117 } 124 }
118 125
119 void GrGLMagnifierEffect::emitCode(GrGLFPBuilder* builder, 126 void GrGLMagnifierEffect::emitCode(GrGLFPBuilder* builder,
120 const GrFragmentProcessor&, 127 const GrFragmentProcessor&,
121 const char* outputColor, 128 const char* outputColor,
122 const char* inputColor, 129 const char* inputColor,
123 const TransformedCoordsArray& coords, 130 const TransformedCoordsArray& coords,
124 const TextureSamplerArray& samplers) { 131 const TextureSamplerArray& samplers) {
125 fOffsetVar = builder->addUniform( 132 fOffsetVar = builder->addUniform(
126 GrGLProgramBuilder::kFragment_Visibility | 133 GrGLProgramBuilder::kFragment_Visibility |
127 GrGLProgramBuilder::kVertex_Visibility, 134 GrGLProgramBuilder::kVertex_Visibility,
128 kVec2f_GrSLType, kDefault_GrSLPrecision, "Offset"); 135 kVec2f_GrSLType, kDefault_GrSLPrecision, "Offset");
129 fInvZoomVar = builder->addUniform( 136 fInvZoomVar = builder->addUniform(
130 GrGLProgramBuilder::kFragment_Visibility | 137 GrGLProgramBuilder::kFragment_Visibility |
131 GrGLProgramBuilder::kVertex_Visibility, 138 GrGLProgramBuilder::kVertex_Visibility,
132 kVec2f_GrSLType, kDefault_GrSLPrecision, "InvZoom"); 139 kVec2f_GrSLType, kDefault_GrSLPrecision, "InvZoom");
133 fInvInsetVar = builder->addUniform( 140 fInvInsetVar = builder->addUniform(
134 GrGLProgramBuilder::kFragment_Visibility | 141 GrGLProgramBuilder::kFragment_Visibility |
135 GrGLProgramBuilder::kVertex_Visibility, 142 GrGLProgramBuilder::kVertex_Visibility,
136 kVec2f_GrSLType, kDefault_GrSLPrecision, "InvInset"); 143 kVec2f_GrSLType, kDefault_GrSLPrecision, "InvInset");
144 fBoundsVar = builder->addUniform(
145 GrGLProgramBuilder::kFragment_Visibility |
146 GrGLProgramBuilder::kVertex_Visibility,
147 kVec4f_GrSLType, kDefault_GrSLPrecision, "Bounds");
137 148
138 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 149 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
139 SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); 150 SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
140 fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str()); 151 fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
141 fsBuilder->codeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n", 152 fsBuilder->codeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n",
142 builder->getUniformCStr(fOffsetVar), 153 builder->getUniformCStr(fOffsetVar),
143 coords2D.c_str(), 154 coords2D.c_str(),
144 builder->getUniformCStr(fInvZoomVar)); 155 builder->getUniformCStr(fInvZoomVar));
145 156 const char* bounds = builder->getUniformCStr(fBoundsVar);
146 fsBuilder->codeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\ n"); 157 fsBuilder->codeAppendf("\t\tvec2 delta = (coord - %s.xy) * %s.zw;\n", bounds , bounds);
147 158 fsBuilder->codeAppendf("\t\tdelta = min(delta, vec2(1.0, 1.0) - delta);\n");
148 fsBuilder->codeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr( fInvInsetVar)); 159 fsBuilder->codeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr( fInvInsetVar));
149 160
150 fsBuilder->codeAppend("\t\tfloat weight = 0.0;\n"); 161 fsBuilder->codeAppend("\t\tfloat weight = 0.0;\n");
151 fsBuilder->codeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n"); 162 fsBuilder->codeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n");
152 fsBuilder->codeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n"); 163 fsBuilder->codeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n");
153 fsBuilder->codeAppend("\t\t\tfloat dist = length(delta);\n"); 164 fsBuilder->codeAppend("\t\t\tfloat dist = length(delta);\n");
154 fsBuilder->codeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n"); 165 fsBuilder->codeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n");
155 fsBuilder->codeAppend("\t\t\tweight = min(dist * dist, 1.0);\n"); 166 fsBuilder->codeAppend("\t\t\tweight = min(dist * dist, 1.0);\n");
156 fsBuilder->codeAppend("\t\t} else {\n"); 167 fsBuilder->codeAppend("\t\t} else {\n");
157 fsBuilder->codeAppend("\t\t\tvec2 delta_squared = delta * delta;\n"); 168 fsBuilder->codeAppend("\t\t\tvec2 delta_squared = delta * delta;\n");
(...skipping 10 matching lines...) Expand all
168 GrGLSLMulVarBy4f(&modulate, outputColor, inputColor); 179 GrGLSLMulVarBy4f(&modulate, outputColor, inputColor);
169 fsBuilder->codeAppend(modulate.c_str()); 180 fsBuilder->codeAppend(modulate.c_str());
170 } 181 }
171 182
172 void GrGLMagnifierEffect::setData(const GrGLProgramDataManager& pdman, 183 void GrGLMagnifierEffect::setData(const GrGLProgramDataManager& pdman,
173 const GrProcessor& effect) { 184 const GrProcessor& effect) {
174 const GrMagnifierEffect& zoom = effect.cast<GrMagnifierEffect>(); 185 const GrMagnifierEffect& zoom = effect.cast<GrMagnifierEffect>();
175 pdman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset()); 186 pdman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset());
176 pdman.set2f(fInvZoomVar, zoom.x_inv_zoom(), zoom.y_inv_zoom()); 187 pdman.set2f(fInvZoomVar, zoom.x_inv_zoom(), zoom.y_inv_zoom());
177 pdman.set2f(fInvInsetVar, zoom.x_inv_inset(), zoom.y_inv_inset()); 188 pdman.set2f(fInvInsetVar, zoom.x_inv_inset(), zoom.y_inv_inset());
189 pdman.set4f(fBoundsVar, zoom.bounds().x(), zoom.bounds().y(),
190 zoom.bounds().width(), zoom.bounds().height());
178 } 191 }
179 192
180 ///////////////////////////////////////////////////////////////////// 193 /////////////////////////////////////////////////////////////////////
181 194
182 void GrMagnifierEffect::getGLProcessorKey(const GrGLCaps& caps, 195 void GrMagnifierEffect::getGLProcessorKey(const GrGLCaps& caps,
183 GrProcessorKeyBuilder* b) const { 196 GrProcessorKeyBuilder* b) const {
184 GrGLMagnifierEffect::GenKey(*this, caps, b); 197 GrGLMagnifierEffect::GenKey(*this, caps, b);
185 } 198 }
186 199
187 GrGLFragmentProcessor* GrMagnifierEffect::createGLInstance() const { 200 GrGLFragmentProcessor* GrMagnifierEffect::createGLInstance() const {
(...skipping 11 matching lines...) Expand all
199 const int kMaxHeight = 200; 212 const int kMaxHeight = 200;
200 const int kMaxInset = 20; 213 const int kMaxInset = 20;
201 uint32_t width = random->nextULessThan(kMaxWidth); 214 uint32_t width = random->nextULessThan(kMaxWidth);
202 uint32_t height = random->nextULessThan(kMaxHeight); 215 uint32_t height = random->nextULessThan(kMaxHeight);
203 uint32_t x = random->nextULessThan(kMaxWidth - width); 216 uint32_t x = random->nextULessThan(kMaxWidth - width);
204 uint32_t y = random->nextULessThan(kMaxHeight - height); 217 uint32_t y = random->nextULessThan(kMaxHeight - height);
205 uint32_t inset = random->nextULessThan(kMaxInset); 218 uint32_t inset = random->nextULessThan(kMaxInset);
206 219
207 GrFragmentProcessor* effect = GrMagnifierEffect::Create( 220 GrFragmentProcessor* effect = GrMagnifierEffect::Create(
208 texture, 221 texture,
222 SkRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)),
209 (float) width / texture->width(), 223 (float) width / texture->width(),
210 (float) height / texture->height(), 224 (float) height / texture->height(),
211 texture->width() / (float) x, 225 texture->width() / (float) x,
212 texture->height() / (float) y, 226 texture->height() / (float) y,
213 (float) inset / texture->width(), 227 (float) inset / texture->width(),
214 (float) inset / texture->height()); 228 (float) inset / texture->height());
215 SkASSERT(effect); 229 SkASSERT(effect);
216 return effect; 230 return effect;
217 } 231 }
218 232
219 /////////////////////////////////////////////////////////////////////////////// 233 ///////////////////////////////////////////////////////////////////////////////
220 234
221 bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& sBase) const { 235 bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
222 const GrMagnifierEffect& s = sBase.cast<GrMagnifierEffect>(); 236 const GrMagnifierEffect& s = sBase.cast<GrMagnifierEffect>();
223 return (this->fXOffset == s.fXOffset && 237 return (this->fBounds == s.fBounds &&
238 this->fXOffset == s.fXOffset &&
224 this->fYOffset == s.fYOffset && 239 this->fYOffset == s.fYOffset &&
225 this->fXInvZoom == s.fXInvZoom && 240 this->fXInvZoom == s.fXInvZoom &&
226 this->fYInvZoom == s.fYInvZoom && 241 this->fYInvZoom == s.fYInvZoom &&
227 this->fXInvInset == s.fXInvInset && 242 this->fXInvInset == s.fXInvInset &&
228 this->fYInvInset == s.fYInvInset); 243 this->fYInvInset == s.fYInvInset);
229 } 244 }
230 245
231 void GrMagnifierEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { 246 void GrMagnifierEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
232 this->updateInvariantOutputForModulation(inout); 247 this->updateInvariantOutputForModulation(inout);
233 } 248 }
(...skipping 17 matching lines...) Expand all
251 266
252 267
253 SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, SkScalar i nset, 268 SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, SkScalar i nset,
254 SkImageFilter* input) 269 SkImageFilter* input)
255 : INHERITED(1, &input), fSrcRect(srcRect), fInset(inset) { 270 : INHERITED(1, &input), fSrcRect(srcRect), fInset(inset) {
256 SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0); 271 SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0);
257 } 272 }
258 273
259 #if SK_SUPPORT_GPU 274 #if SK_SUPPORT_GPU
260 bool SkMagnifierImageFilter::asFragmentProcessor(GrFragmentProcessor** fp, GrTex ture* texture, 275 bool SkMagnifierImageFilter::asFragmentProcessor(GrFragmentProcessor** fp, GrTex ture* texture,
261 const SkMatrix&, const SkIRect& ) const { 276 const SkMatrix&, const SkIRect& bounds) const {
262 if (fp) { 277 if (fp) {
263 SkScalar yOffset = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? fSr cRect.y() : 278 SkScalar yOffset = texture->origin() == kTopLeft_GrSurfaceOrigin ? fSrcR ect.y() :
264 (texture->height() - (fSrcRect.y() + fSrcRect.height( ))); 279 texture->height() - fSrcRect.height() * texture->height() / bounds.he ight()
280 - fSrcRect.y();
281 int boundsY = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? bounds.y () :
282 (texture->height() - bounds.height());
283 SkRect effectBounds = SkRect::MakeXYWH(
284 SkIntToScalar(bounds.x()) / texture->width(),
285 SkIntToScalar(boundsY) / texture->height(),
286 SkIntToScalar(texture->width()) / bounds.width(),
287 SkIntToScalar(texture->height()) / bounds.height());
265 SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1; 288 SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1;
266 *fp = GrMagnifierEffect::Create(texture, 289 *fp = GrMagnifierEffect::Create(texture,
290 effectBounds,
267 fSrcRect.x() / texture->width(), 291 fSrcRect.x() / texture->width(),
268 yOffset / texture->height(), 292 yOffset / texture->height(),
269 fSrcRect.width() / texture->width(), 293 fSrcRect.width() / bounds.width(),
270 fSrcRect.height() / texture->height(), 294 fSrcRect.height() / bounds.height(),
271 texture->width() * invInset, 295 bounds.width() * invInset,
272 texture->height() * invInset); 296 bounds.height() * invInset);
273 } 297 }
274 return true; 298 return true;
275 } 299 }
276 #endif 300 #endif
277 301
278 SkFlattenable* SkMagnifierImageFilter::CreateProc(SkReadBuffer& buffer) { 302 SkFlattenable* SkMagnifierImageFilter::CreateProc(SkReadBuffer& buffer) {
279 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 303 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
280 SkRect src; 304 SkRect src;
281 buffer.readRect(&src); 305 buffer.readRect(&src);
282 return Create(src, buffer.readScalar(), common.getInput(0)); 306 return Create(src, buffer.readScalar(), common.getInput(0));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 380
357 #ifndef SK_IGNORE_TO_STRING 381 #ifndef SK_IGNORE_TO_STRING
358 void SkMagnifierImageFilter::toString(SkString* str) const { 382 void SkMagnifierImageFilter::toString(SkString* str) const {
359 str->appendf("SkMagnifierImageFilter: ("); 383 str->appendf("SkMagnifierImageFilter: (");
360 str->appendf("src: (%f,%f,%f,%f) ", 384 str->appendf("src: (%f,%f,%f,%f) ",
361 fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, fSrcRect.fBotto m); 385 fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, fSrcRect.fBotto m);
362 str->appendf("inset: %f", fInset); 386 str->appendf("inset: %f", fInset);
363 str->append(")"); 387 str->append(")");
364 } 388 }
365 #endif 389 #endif
OLDNEW
« no previous file with comments | « src/core/SkCanvas.cpp ('k') | src/gpu/SkGpuDevice.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698