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

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

Issue 28273005: Magnifier gpu path fix (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Merge fix Created 7 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « gm/imagemagnifier.cpp ('k') | no next file » | 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 "SkFlattenableBuffers.h" 11 #include "SkFlattenableBuffers.h"
12 12
13 //////////////////////////////////////////////////////////////////////////////// 13 ////////////////////////////////////////////////////////////////////////////////
14 #if SK_SUPPORT_GPU 14 #if SK_SUPPORT_GPU
15 #include "effects/GrSingleTextureEffect.h" 15 #include "effects/GrSingleTextureEffect.h"
16 #include "gl/GrGLEffect.h" 16 #include "gl/GrGLEffect.h"
17 #include "gl/GrGLSL.h" 17 #include "gl/GrGLSL.h"
18 #include "gl/GrGLTexture.h" 18 #include "gl/GrGLTexture.h"
19 #include "GrTBackendEffectFactory.h" 19 #include "GrTBackendEffectFactory.h"
20 20
21 class GrGLMagnifierEffect; 21 class GrGLMagnifierEffect;
22 22
23 class GrMagnifierEffect : public GrSingleTextureEffect { 23 class GrMagnifierEffect : public GrSingleTextureEffect {
24 24
25 public: 25 public:
26 static GrEffectRef* Create(GrTexture* texture, 26 static GrEffectRef* Create(GrTexture* texture,
27 float xOffset, 27 float xOffset,
28 float yOffset, 28 float yOffset,
29 float xZoom, 29 float xInvZoom,
30 float yZoom, 30 float yInvZoom,
31 float xInset, 31 float xInvInset,
32 float yInset) { 32 float yInvInset) {
33 AutoEffectUnref effect(SkNEW_ARGS(GrMagnifierEffect, (texture, 33 AutoEffectUnref effect(SkNEW_ARGS(GrMagnifierEffect, (texture,
34 xOffset, 34 xOffset,
35 yOffset, 35 yOffset,
36 xZoom, 36 xInvZoom,
37 yZoom, 37 yInvZoom,
38 xInset, 38 xInvInset,
39 yInset))); 39 yInvInset)));
40 return CreateEffectRef(effect); 40 return CreateEffectRef(effect);
41 } 41 }
42 42
43 virtual ~GrMagnifierEffect() {}; 43 virtual ~GrMagnifierEffect() {};
44 44
45 static const char* Name() { return "Magnifier"; } 45 static const char* Name() { return "Magnifier"; }
46 46
47 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; 47 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
48 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE; 48 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE;
49 49
50 float x_offset() const { return fXOffset; } 50 float x_offset() const { return fXOffset; }
51 float y_offset() const { return fYOffset; } 51 float y_offset() const { return fYOffset; }
52 float x_zoom() const { return fXZoom; } 52 float x_inv_zoom() const { return fXInvZoom; }
53 float y_zoom() const { return fYZoom; } 53 float y_inv_zoom() const { return fYInvZoom; }
54 float x_inset() const { return fXInset; } 54 float x_inv_inset() const { return fXInvInset; }
55 float y_inset() const { return fYInset; } 55 float y_inv_inset() const { return fYInvInset; }
56 56
57 typedef GrGLMagnifierEffect GLEffect; 57 typedef GrGLMagnifierEffect GLEffect;
58 58
59 private: 59 private:
60 GrMagnifierEffect(GrTexture* texture, 60 GrMagnifierEffect(GrTexture* texture,
61 float xOffset, 61 float xOffset,
62 float yOffset, 62 float yOffset,
63 float xZoom, 63 float xInvZoom,
64 float yZoom, 64 float yInvZoom,
65 float xInset, 65 float xInvInset,
66 float yInset) 66 float yInvInset)
67 : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture)) 67 : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture))
68 , fXOffset(xOffset) 68 , fXOffset(xOffset)
69 , fYOffset(yOffset) 69 , fYOffset(yOffset)
70 , fXZoom(xZoom) 70 , fXInvZoom(xInvZoom)
71 , fYZoom(yZoom) 71 , fYInvZoom(yInvZoom)
72 , fXInset(xInset) 72 , fXInvInset(xInvInset)
73 , fYInset(yInset) {} 73 , fYInvInset(yInvInset) {}
74 74
75 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; 75 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
76 76
77 GR_DECLARE_EFFECT_TEST; 77 GR_DECLARE_EFFECT_TEST;
78 78
79 float fXOffset; 79 float fXOffset;
80 float fYOffset; 80 float fYOffset;
81 float fXZoom; 81 float fXInvZoom;
82 float fYZoom; 82 float fYInvZoom;
83 float fXInset; 83 float fXInvInset;
84 float fYInset; 84 float fYInvInset;
85 85
86 typedef GrSingleTextureEffect INHERITED; 86 typedef GrSingleTextureEffect INHERITED;
87 }; 87 };
88 88
89 // For brevity 89 // For brevity
90 typedef GrGLUniformManager::UniformHandle UniformHandle; 90 typedef GrGLUniformManager::UniformHandle UniformHandle;
91 91
92 class GrGLMagnifierEffect : public GrGLEffect { 92 class GrGLMagnifierEffect : public GrGLEffect {
93 public: 93 public:
94 GrGLMagnifierEffect(const GrBackendEffectFactory&, const GrDrawEffect&); 94 GrGLMagnifierEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
95 95
96 virtual void emitCode(GrGLShaderBuilder*, 96 virtual void emitCode(GrGLShaderBuilder*,
97 const GrDrawEffect&, 97 const GrDrawEffect&,
98 EffectKey, 98 EffectKey,
99 const char* outputColor, 99 const char* outputColor,
100 const char* inputColor, 100 const char* inputColor,
101 const TransformedCoordsArray&, 101 const TransformedCoordsArray&,
102 const TextureSamplerArray&) SK_OVERRIDE; 102 const TextureSamplerArray&) SK_OVERRIDE;
103 103
104 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE; 104 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE;
105 105
106 private: 106 private:
107 UniformHandle fOffsetVar; 107 UniformHandle fOffsetVar;
108 UniformHandle fZoomVar; 108 UniformHandle fInvZoomVar;
109 UniformHandle fInsetVar; 109 UniformHandle fInvInsetVar;
110 110
111 typedef GrGLEffect INHERITED; 111 typedef GrGLEffect INHERITED;
112 }; 112 };
113 113
114 GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) 114 GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
115 : INHERITED(factory) { 115 : INHERITED(factory) {
116 } 116 }
117 117
118 void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder, 118 void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder,
119 const GrDrawEffect&, 119 const GrDrawEffect&,
120 EffectKey key, 120 EffectKey key,
121 const char* outputColor, 121 const char* outputColor,
122 const char* inputColor, 122 const char* inputColor,
123 const TransformedCoordsArray& coords, 123 const TransformedCoordsArray& coords,
124 const TextureSamplerArray& samplers) { 124 const TextureSamplerArray& samplers) {
125 SkString coords2D = builder->ensureFSCoords2D(coords, 0); 125 SkString coords2D = builder->ensureFSCoords2D(coords, 0);
126 fOffsetVar = builder->addUniform( 126 fOffsetVar = builder->addUniform(
127 GrGLShaderBuilder::kFragment_Visibility | 127 GrGLShaderBuilder::kFragment_Visibility |
128 GrGLShaderBuilder::kVertex_Visibility, 128 GrGLShaderBuilder::kVertex_Visibility,
129 kVec2f_GrSLType, "uOffset"); 129 kVec2f_GrSLType, "Offset");
130 fZoomVar = builder->addUniform( 130 fInvZoomVar = builder->addUniform(
131 GrGLShaderBuilder::kFragment_Visibility | 131 GrGLShaderBuilder::kFragment_Visibility |
132 GrGLShaderBuilder::kVertex_Visibility, 132 GrGLShaderBuilder::kVertex_Visibility,
133 kVec2f_GrSLType, "uZoom"); 133 kVec2f_GrSLType, "InvZoom");
134 fInsetVar = builder->addUniform( 134 fInvInsetVar = builder->addUniform(
135 GrGLShaderBuilder::kFragment_Visibility | 135 GrGLShaderBuilder::kFragment_Visibility |
136 GrGLShaderBuilder::kVertex_Visibility, 136 GrGLShaderBuilder::kVertex_Visibility,
137 kVec2f_GrSLType, "uInset"); 137 kVec2f_GrSLType, "InvInset");
138 138
139 builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str()); 139 builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
140 builder->fsCodeAppendf("\t\tvec2 zoom_coord = %s + %s / %s;\n", 140 builder->fsCodeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n",
141 builder->getUniformCStr(fOffsetVar), 141 builder->getUniformCStr(fOffsetVar),
142 coords2D.c_str(), 142 coords2D.c_str(),
143 builder->getUniformCStr(fZoomVar)); 143 builder->getUniformCStr(fInvZoomVar));
144 144
145 builder->fsCodeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\ n"); 145 builder->fsCodeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\ n");
146 146
147 builder->fsCodeAppendf("\t\tdelta = delta / %s;\n", builder->getUniformCStr( fInsetVar)); 147 builder->fsCodeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr( fInvInsetVar));
148 148
149 builder->fsCodeAppend("\t\tfloat weight = 0.0;\n"); 149 builder->fsCodeAppend("\t\tfloat weight = 0.0;\n");
150 builder->fsCodeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n"); 150 builder->fsCodeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n");
151 builder->fsCodeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n"); 151 builder->fsCodeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n");
152 builder->fsCodeAppend("\t\t\tfloat dist = length(delta);\n"); 152 builder->fsCodeAppend("\t\t\tfloat dist = length(delta);\n");
153 builder->fsCodeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n"); 153 builder->fsCodeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n");
154 builder->fsCodeAppend("\t\t\tweight = min(dist * dist, 1.0);\n"); 154 builder->fsCodeAppend("\t\t\tweight = min(dist * dist, 1.0);\n");
155 builder->fsCodeAppend("\t\t} else {\n"); 155 builder->fsCodeAppend("\t\t} else {\n");
156 builder->fsCodeAppend("\t\t\tvec2 delta_squared = delta * delta;\n"); 156 builder->fsCodeAppend("\t\t\tvec2 delta_squared = delta * delta;\n");
157 builder->fsCodeAppend("\t\t\tweight = min(min(delta_squared.s, delta_squared .y), 1.0);\n"); 157 builder->fsCodeAppend("\t\t\tweight = min(min(delta_squared.x, delta_squared .y), 1.0);\n");
158 builder->fsCodeAppend("\t\t}\n"); 158 builder->fsCodeAppend("\t\t}\n");
159 159
160 builder->fsCodeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\ n"); 160 builder->fsCodeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\ n");
161 builder->fsCodeAppend("\t\tvec4 output_color = "); 161 builder->fsCodeAppend("\t\tvec4 output_color = ");
162 builder->fsAppendTextureLookup(samplers[0], "mix_coord"); 162 builder->fsAppendTextureLookup(samplers[0], "mix_coord");
163 builder->fsCodeAppend(";\n"); 163 builder->fsCodeAppend(";\n");
164 164
165 builder->fsCodeAppendf("\t\t%s = output_color;", outputColor); 165 builder->fsCodeAppendf("\t\t%s = output_color;", outputColor);
166 SkString modulate; 166 SkString modulate;
167 GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor); 167 GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
168 builder->fsCodeAppend(modulate.c_str()); 168 builder->fsCodeAppend(modulate.c_str());
169 } 169 }
170 170
171 void GrGLMagnifierEffect::setData(const GrGLUniformManager& uman, 171 void GrGLMagnifierEffect::setData(const GrGLUniformManager& uman,
172 const GrDrawEffect& drawEffect) { 172 const GrDrawEffect& drawEffect) {
173 const GrMagnifierEffect& zoom = drawEffect.castEffect<GrMagnifierEffect>(); 173 const GrMagnifierEffect& zoom = drawEffect.castEffect<GrMagnifierEffect>();
174 uman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset()); 174 uman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset());
175 uman.set2f(fZoomVar, zoom.x_zoom(), zoom.y_zoom()); 175 uman.set2f(fInvZoomVar, zoom.x_inv_zoom(), zoom.y_inv_zoom());
176 uman.set2f(fInsetVar, zoom.x_inset(), zoom.y_inset()); 176 uman.set2f(fInvInsetVar, zoom.x_inv_inset(), zoom.y_inv_inset());
177 } 177 }
178 178
179 ///////////////////////////////////////////////////////////////////// 179 /////////////////////////////////////////////////////////////////////
180 180
181 GR_DEFINE_EFFECT_TEST(GrMagnifierEffect); 181 GR_DEFINE_EFFECT_TEST(GrMagnifierEffect);
182 182
183 GrEffectRef* GrMagnifierEffect::TestCreate(SkRandom* random, 183 GrEffectRef* GrMagnifierEffect::TestCreate(SkRandom* random,
184 GrContext* context, 184 GrContext* context,
185 const GrDrawTargetCaps&, 185 const GrDrawTargetCaps&,
186 GrTexture** textures) { 186 GrTexture** textures) {
(...skipping 23 matching lines...) Expand all
210 210
211 const GrBackendEffectFactory& GrMagnifierEffect::getFactory() const { 211 const GrBackendEffectFactory& GrMagnifierEffect::getFactory() const {
212 return GrTBackendEffectFactory<GrMagnifierEffect>::getInstance(); 212 return GrTBackendEffectFactory<GrMagnifierEffect>::getInstance();
213 } 213 }
214 214
215 bool GrMagnifierEffect::onIsEqual(const GrEffect& sBase) const { 215 bool GrMagnifierEffect::onIsEqual(const GrEffect& sBase) const {
216 const GrMagnifierEffect& s = CastEffect<GrMagnifierEffect>(sBase); 216 const GrMagnifierEffect& s = CastEffect<GrMagnifierEffect>(sBase);
217 return (this->texture(0) == s.texture(0) && 217 return (this->texture(0) == s.texture(0) &&
218 this->fXOffset == s.fXOffset && 218 this->fXOffset == s.fXOffset &&
219 this->fYOffset == s.fYOffset && 219 this->fYOffset == s.fYOffset &&
220 this->fXZoom == s.fXZoom && 220 this->fXInvZoom == s.fXInvZoom &&
221 this->fYZoom == s.fYZoom && 221 this->fYInvZoom == s.fYInvZoom &&
222 this->fXInset == s.fXInset && 222 this->fXInvInset == s.fXInvInset &&
223 this->fYInset == s.fYInset); 223 this->fYInvInset == s.fYInvInset);
224 } 224 }
225 225
226 void GrMagnifierEffect::getConstantColorComponents(GrColor* color, uint32_t* val idFlags) const { 226 void GrMagnifierEffect::getConstantColorComponents(GrColor* color, uint32_t* val idFlags) const {
227 this->updateConstantColorComponentsForModulation(color, validFlags); 227 this->updateConstantColorComponentsForModulation(color, validFlags);
228 } 228 }
229 229
230 #endif 230 #endif
231 231
232 //////////////////////////////////////////////////////////////////////////////// 232 ////////////////////////////////////////////////////////////////////////////////
233 SkMagnifierImageFilter::SkMagnifierImageFilter(SkFlattenableReadBuffer& buffer) 233 SkMagnifierImageFilter::SkMagnifierImageFilter(SkFlattenableReadBuffer& buffer)
234 : INHERITED(buffer) { 234 : INHERITED(buffer) {
235 float x = buffer.readScalar(); 235 float x = buffer.readScalar();
236 float y = buffer.readScalar(); 236 float y = buffer.readScalar();
237 float width = buffer.readScalar(); 237 float width = buffer.readScalar();
238 float height = buffer.readScalar(); 238 float height = buffer.readScalar();
239 fSrcRect = SkRect::MakeXYWH(x, y, width, height); 239 fSrcRect = SkRect::MakeXYWH(x, y, width, height);
240 fInset = buffer.readScalar(); 240 fInset = buffer.readScalar();
241 } 241 }
242 242
243 // FIXME: implement single-input semantics 243 // FIXME: implement single-input semantics
244 SkMagnifierImageFilter::SkMagnifierImageFilter(SkRect srcRect, SkScalar inset) 244 SkMagnifierImageFilter::SkMagnifierImageFilter(SkRect srcRect, SkScalar inset)
245 : INHERITED(0), fSrcRect(srcRect), fInset(inset) { 245 : INHERITED(0), fSrcRect(srcRect), fInset(inset) {
246 SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0); 246 SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0);
247 } 247 }
248 248
249 #if SK_SUPPORT_GPU 249 #if SK_SUPPORT_GPU
250 bool SkMagnifierImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* textur e, const SkMatrix&, const SkIRect&) const { 250 bool SkMagnifierImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* textur e, const SkMatrix&, const SkIRect&) const {
251 if (effect) { 251 if (effect) {
252 SkScalar yOffset = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? fSr cRect.y() :
253 (texture->height() - (fSrcRect.y() + fSrcRect.height( )));
254 SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1;
252 *effect = GrMagnifierEffect::Create(texture, 255 *effect = GrMagnifierEffect::Create(texture,
253 fSrcRect.x() / texture->width(), 256 fSrcRect.x() / texture->width(),
254 fSrcRect.y() / texture->height(), 257 yOffset / texture->height(),
255 texture->width() / fSrcRect.width(), 258 fSrcRect.width() / texture->width(),
256 texture->height() / fSrcRect.height( ), 259 fSrcRect.height() / texture->height( ),
257 fInset / texture->width(), 260 texture->width() * invInset,
258 fInset / texture->height()); 261 texture->height() * invInset);
259 } 262 }
260 return true; 263 return true;
261 } 264 }
262 #endif 265 #endif
263 266
264 void SkMagnifierImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { 267 void SkMagnifierImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
265 this->INHERITED::flatten(buffer); 268 this->INHERITED::flatten(buffer);
266 buffer.writeScalar(fSrcRect.x()); 269 buffer.writeScalar(fSrcRect.x());
267 buffer.writeScalar(fSrcRect.y()); 270 buffer.writeScalar(fSrcRect.y());
268 buffer.writeScalar(fSrcRect.width()); 271 buffer.writeScalar(fSrcRect.width());
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 331
329 int x_val = SkMin32(SkScalarFloorToInt(x_interp), width - 1); 332 int x_val = SkMin32(SkScalarFloorToInt(x_interp), width - 1);
330 int y_val = SkMin32(SkScalarFloorToInt(y_interp), height - 1); 333 int y_val = SkMin32(SkScalarFloorToInt(y_interp), height - 1);
331 334
332 *dptr = sptr[y_val * width + x_val]; 335 *dptr = sptr[y_val * width + x_val];
333 dptr++; 336 dptr++;
334 } 337 }
335 } 338 }
336 return true; 339 return true;
337 } 340 }
OLDNEW
« no previous file with comments | « gm/imagemagnifier.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698