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

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

Issue 920513003: Make filters use SkImage instead of SkBitmap Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 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/effects/SkBitmapSource.cpp ('k') | src/effects/SkColorFilterImageFilter.cpp » ('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 2011 The Android Open Source Project 2 * Copyright 2011 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 "SkBlurImageFilter.h" 9 #include "SkBlurImageFilter.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
11 #include "SkImage_Base.h"
12 #include "SkImagePriv.h"
11 #include "SkReadBuffer.h" 13 #include "SkReadBuffer.h"
12 #include "SkWriteBuffer.h" 14 #include "SkWriteBuffer.h"
13 #include "SkGpuBlurUtils.h" 15 #include "SkGpuBlurUtils.h"
14 #include "SkBlurImage_opts.h" 16 #include "SkBlurImage_opts.h"
15 #if SK_SUPPORT_GPU 17 #if SK_SUPPORT_GPU
16 #include "GrContext.h" 18 #include "GrContext.h"
17 #endif 19 #endif
18 20
19 // This rather arbitrary-looking value results in a maximum box blur kernel size 21 // This rather arbitrary-looking value results in a maximum box blur kernel size
20 // of 1000 pixels on the raster path, which matches the WebKit and Firefox 22 // of 1000 pixels on the raster path, which matches the WebKit and Firefox
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 *lowOffset = *highOffset = (d - 1) / 2; 140 *lowOffset = *highOffset = (d - 1) / 2;
139 *kernelSize3 = d; 141 *kernelSize3 = d;
140 } else { 142 } else {
141 *highOffset = d / 2; 143 *highOffset = d / 2;
142 *lowOffset = *highOffset - 1; 144 *lowOffset = *highOffset - 1;
143 *kernelSize3 = d + 1; 145 *kernelSize3 = d + 1;
144 } 146 }
145 } 147 }
146 148
147 bool SkBlurImageFilter::onFilterImage(Proxy* proxy, 149 bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
148 const SkBitmap& source, const Context& ctx , 150 const SkImage* source, const Context& ctx,
149 SkBitmap* dst, SkIPoint* offset) const { 151 SkAutoTUnref<const SkImage>& dst, SkIPoint * offset) const {
150 SkBitmap src = source; 152 SkAutoTUnref<const SkImage> src(SkRef(source));
151 SkIPoint srcOffset = SkIPoint::Make(0, 0); 153 SkIPoint srcOffset = SkIPoint::Make(0, 0);
152 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcO ffset)) { 154 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, src, &srcOf fset)) {
153 return false;
154 }
155
156 if (src.colorType() != kN32_SkColorType) {
157 return false; 155 return false;
158 } 156 }
159 157
160 SkIRect srcBounds, dstBounds; 158 SkIRect srcBounds, dstBounds;
161 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &srcBounds, &src)) { 159 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &srcBounds, src)) {
162 return false; 160 return false;
163 } 161 }
164 162
165 SkAutoLockPixels alp(src); 163 SkBitmap srcBitmap;
166 if (!src.getPixels()) { 164 SkAutoAdoptImageAsN32Bitmap aai(src, &srcBitmap);
165 if (NULL == srcBitmap.getPixels()) {
167 return false; 166 return false;
168 } 167 }
169 168
170 if (!dst->tryAllocPixels(src.info().makeWH(srcBounds.width(), srcBounds.heig ht()))) { 169 SkBitmap dstBitmap;
170 if (!dstBitmap.tryAllocPixels(
171 srcBitmap.info().makeWH(srcBounds.width(), srcBounds.height()))) {
171 return false; 172 return false;
172 } 173 }
173 dst->getBounds(&dstBounds); 174 dstBitmap.getBounds(&dstBounds);
174 175
175 SkVector sigma = mapSigma(fSigma, ctx.ctm()); 176 SkVector sigma = mapSigma(fSigma, ctx.ctm());
176 177
177 int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX; 178 int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
178 int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY; 179 int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
179 getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffs etX); 180 getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffs etX);
180 getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffs etY); 181 getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffs etY);
181 182
182 if (kernelSizeX < 0 || kernelSizeY < 0) { 183 if (kernelSizeX < 0 || kernelSizeY < 0) {
183 return false; 184 return false;
184 } 185 }
185 186
186 if (kernelSizeX == 0 && kernelSizeY == 0) { 187 if (kernelSizeX == 0 && kernelSizeY == 0) {
187 src.copyTo(dst, dst->colorType()); 188 srcBitmap.copyTo(&dstBitmap, dstBitmap.colorType());
189 srcBitmap = SkBitmap();
190 SkImage* image = SkNewImageFromBitmap(dstBitmap, NULL);
191 if (NULL == image) {
192 return false;
193 }
194 dst.reset(image);
188 offset->fX = srcBounds.fLeft; 195 offset->fX = srcBounds.fLeft;
189 offset->fY = srcBounds.fTop; 196 offset->fY = srcBounds.fTop;
190 return true; 197 return true;
191 } 198 }
192 199
193 SkBitmap temp; 200 SkBitmap temp;
194 if (!temp.tryAllocPixels(dst->info())) { 201 if (!temp.tryAllocPixels(dstBitmap.info())) {
195 return false; 202 return false;
196 } 203 }
197 204
198 offset->fX = srcBounds.fLeft; 205 int32_t resultX = srcBounds.fLeft;
199 offset->fY = srcBounds.fTop; 206 int32_t resultY = srcBounds.fTop;
200 srcBounds.offset(-srcOffset); 207 srcBounds.offset(-srcOffset);
201 const SkPMColor* s = src.getAddr32(srcBounds.left(), srcBounds.top()); 208 const SkPMColor* s = srcBitmap.getAddr32(srcBounds.left(), srcBounds.top());
202 SkPMColor* t = temp.getAddr32(0, 0); 209 SkPMColor* t = temp.getAddr32(0, 0);
203 SkPMColor* d = dst->getAddr32(0, 0); 210 SkPMColor* d = dstBitmap.getAddr32(0, 0);
204 int w = dstBounds.width(), h = dstBounds.height(); 211 int w = dstBounds.width(), h = dstBounds.height();
205 int sw = src.rowBytesAsPixels(); 212 int sw = srcBitmap.rowBytesAsPixels();
206 SkBoxBlurProc boxBlurX, boxBlurY, boxBlurXY, boxBlurYX; 213 SkBoxBlurProc boxBlurX, boxBlurY, boxBlurXY, boxBlurYX;
207 if (!SkBoxBlurGetPlatformProcs(&boxBlurX, &boxBlurY, &boxBlurXY, &boxBlurYX) ) { 214 if (!SkBoxBlurGetPlatformProcs(&boxBlurX, &boxBlurY, &boxBlurXY, &boxBlurYX) ) {
208 boxBlurX = boxBlur<kX, kX>; 215 boxBlurX = boxBlur<kX, kX>;
209 boxBlurY = boxBlur<kY, kY>; 216 boxBlurY = boxBlur<kY, kY>;
210 boxBlurXY = boxBlur<kX, kY>; 217 boxBlurXY = boxBlur<kX, kY>;
211 boxBlurYX = boxBlur<kY, kX>; 218 boxBlurYX = boxBlur<kY, kX>;
212 } 219 }
213 220
214 if (kernelSizeX > 0 && kernelSizeY > 0) { 221 if (kernelSizeX > 0 && kernelSizeY > 0) {
215 boxBlurX(s, sw, t, kernelSizeX, lowOffsetX, highOffsetX, w, h); 222 boxBlurX(s, sw, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
216 boxBlurX(t, w, d, kernelSizeX, highOffsetX, lowOffsetX, w, h); 223 boxBlurX(t, w, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
217 boxBlurXY(d, w, t, kernelSizeX3, highOffsetX, highOffsetX, w, h); 224 boxBlurXY(d, w, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
218 boxBlurX(t, h, d, kernelSizeY, lowOffsetY, highOffsetY, h, w); 225 boxBlurX(t, h, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
219 boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w); 226 boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
220 boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w); 227 boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
221 } else if (kernelSizeX > 0) { 228 } else if (kernelSizeX > 0) {
222 boxBlurX(s, sw, d, kernelSizeX, lowOffsetX, highOffsetX, w, h); 229 boxBlurX(s, sw, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
223 boxBlurX(d, w, t, kernelSizeX, highOffsetX, lowOffsetX, w, h); 230 boxBlurX(d, w, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
224 boxBlurX(t, w, d, kernelSizeX3, highOffsetX, highOffsetX, w, h); 231 boxBlurX(t, w, d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
225 } else if (kernelSizeY > 0) { 232 } else if (kernelSizeY > 0) {
226 boxBlurYX(s, sw, d, kernelSizeY, lowOffsetY, highOffsetY, h, w); 233 boxBlurYX(s, sw, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
227 boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w); 234 boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
228 boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w); 235 boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
229 } 236 }
237 temp = SkBitmap();
238 SkImage* image = SkNewImageFromBitmap(dstBitmap, NULL);
239 if (NULL == image) {
240 return false;
241 }
242 dst.reset(image);
243 offset->fX = resultX;
244 offset->fY = resultY;
230 return true; 245 return true;
231 } 246 }
232 247
233 248
234 void SkBlurImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { 249 void SkBlurImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
235 if (getInput(0)) { 250 if (getInput(0)) {
236 getInput(0)->computeFastBounds(src, dst); 251 getInput(0)->computeFastBounds(src, dst);
237 } else { 252 } else {
238 *dst = src; 253 *dst = src;
239 } 254 }
240 255
241 dst->outset(SkScalarMul(fSigma.width(), SkIntToScalar(3)), 256 dst->outset(SkScalarMul(fSigma.width(), SkIntToScalar(3)),
242 SkScalarMul(fSigma.height(), SkIntToScalar(3))); 257 SkScalarMul(fSigma.height(), SkIntToScalar(3)));
243 } 258 }
244 259
245 bool SkBlurImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 260 bool SkBlurImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
246 SkIRect* dst) const { 261 SkIRect* dst) const {
247 SkIRect bounds = src; 262 SkIRect bounds = src;
248 SkVector sigma = mapSigma(fSigma, ctm); 263 SkVector sigma = mapSigma(fSigma, ctm);
249 bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))), 264 bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
250 SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3)))); 265 SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
251 if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { 266 if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) {
252 return false; 267 return false;
253 } 268 }
254 *dst = bounds; 269 *dst = bounds;
255 return true; 270 return true;
256 } 271 }
257 272
258 bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 273 bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkImage* src, const C ontext& ctx,
259 SkBitmap* result, SkIPoint* offset) const { 274 SkAutoTUnref<const SkImage>& result, SkIP oint* offset) const {
260 #if SK_SUPPORT_GPU 275 #if SK_SUPPORT_GPU
261 SkBitmap input = src; 276 SkAutoTUnref<const SkImage> input(SkRef(src));
262 SkIPoint srcOffset = SkIPoint::Make(0, 0); 277 SkIPoint srcOffset = SkIPoint::Make(0, 0);
263 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { 278 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, input, & srcOffset)) {
264 return false; 279 return false;
265 } 280 }
266 SkIRect rect; 281 SkIRect rect;
267 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &rect, &input)) { 282 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &rect, input)) {
268 return false; 283 return false;
269 } 284 }
270 GrTexture* source = input.getTexture(); 285 GrTexture* source = input->getTexture();
271 SkVector sigma = mapSigma(fSigma, ctx.ctm()); 286 SkVector sigma = mapSigma(fSigma, ctx.ctm());
272 offset->fX = rect.fLeft; 287 offset->fX = rect.fLeft;
273 offset->fY = rect.fTop; 288 offset->fY = rect.fTop;
274 rect.offset(-srcOffset); 289 rect.offset(-srcOffset);
275 SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext( ), 290 SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext( ),
276 source, 291 source,
277 false, 292 false,
278 SkRect::Make(rect), 293 SkRect::Make(rect),
279 true, 294 true,
280 sigma.x(), 295 sigma.x(),
281 sigma.y())); 296 sigma.y()));
282 if (!tex) { 297 if (!tex) {
283 return false; 298 return false;
284 } 299 }
285 WrapTexture(tex, rect.width(), rect.height(), result); 300 if (!WrapTexture(tex, rect.width(), rect.height(), result)) {
301 return false;
302 }
286 return true; 303 return true;
287 #else 304 #else
288 SkDEBUGFAIL("Should not call in GPU-less build"); 305 SkDEBUGFAIL("Should not call in GPU-less build");
289 return false; 306 return false;
290 #endif 307 #endif
291 } 308 }
292 309
293 #ifndef SK_IGNORE_TO_STRING 310 #ifndef SK_IGNORE_TO_STRING
294 void SkBlurImageFilter::toString(SkString* str) const { 311 void SkBlurImageFilter::toString(SkString* str) const {
295 str->appendf("SkBlurImageFilter: ("); 312 str->appendf("SkBlurImageFilter: (");
296 str->appendf("sigma: (%f, %f) input (", fSigma.fWidth, fSigma.fHeight); 313 str->appendf("sigma: (%f, %f) input (", fSigma.fWidth, fSigma.fHeight);
297 314
298 if (this->getInput(0)) { 315 if (this->getInput(0)) {
299 this->getInput(0)->toString(str); 316 this->getInput(0)->toString(str);
300 } 317 }
301 318
302 str->append("))"); 319 str->append("))");
303 } 320 }
304 #endif 321 #endif
OLDNEW
« no previous file with comments | « src/effects/SkBitmapSource.cpp ('k') | src/effects/SkColorFilterImageFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698