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

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, 10 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
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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 *lowOffset = *highOffset = (d - 1) / 2; 141 *lowOffset = *highOffset = (d - 1) / 2;
140 *kernelSize3 = d; 142 *kernelSize3 = d;
141 } else { 143 } else {
142 *highOffset = d / 2; 144 *highOffset = d / 2;
143 *lowOffset = *highOffset - 1; 145 *lowOffset = *highOffset - 1;
144 *kernelSize3 = d + 1; 146 *kernelSize3 = d + 1;
145 } 147 }
146 } 148 }
147 149
148 bool SkBlurImageFilter::onFilterImage(Proxy* proxy, 150 bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
149 const SkBitmap& source, const Context& ctx , 151 SkImage& source, const Context& ctx,
150 SkBitmap* dst, SkIPoint* offset) const { 152 SkAutoTUnref<SkImage>& dst, SkIPoint* offs et) const {
151 SkBitmap src = source; 153 SkAutoTUnref<SkImage> src(SkRef(&source));
152 SkIPoint srcOffset = SkIPoint::Make(0, 0); 154 SkIPoint srcOffset = SkIPoint::Make(0, 0);
153 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcO ffset)) { 155 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, src, &srcOf fset)) {
154 return false; 156 return false;
155 } 157 }
156 158
157 if (src.colorType() != kN32_SkColorType) { 159 #if 0 //TODO: colortype
160 if (src->colorType() != kN32_SkColorType) {
161 return false;
162 }
163 #endif
164
165 SkIRect srcBounds, dstBounds;
166 if (!this->applyCropRect(ctx, proxy, *src, &srcOffset, &srcBounds, src)) {
158 return false; 167 return false;
159 } 168 }
160 169
161 SkIRect srcBounds, dstBounds; 170 SkBitmap srcBitmap;
162 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &srcBounds, &src)) { 171 if (!as_IB(src)->getROPixels(&srcBitmap)) {
172 return false;
173 }
174 src.reset(NULL);
175
176 SkAutoLockPixels alp(srcBitmap);
177 if (!srcBitmap.getPixels()) {
163 return false; 178 return false;
164 } 179 }
165 180
166 SkAutoLockPixels alp(src); 181 SkBitmap dstBitmap;
167 if (!src.getPixels()) { 182 if (!dstBitmap.tryAllocPixels(
183 srcBitmap.info().makeWH(srcBounds.width(), srcBounds.height()))) {
168 return false; 184 return false;
169 } 185 }
170 186 dstBitmap.getBounds(&dstBounds);
171 if (!dst->tryAllocPixels(src.info().makeWH(srcBounds.width(), srcBounds.heig ht()))) {
172 return false;
173 }
174 dst->getBounds(&dstBounds);
175 187
176 SkVector sigma = mapSigma(fSigma, ctx.ctm()); 188 SkVector sigma = mapSigma(fSigma, ctx.ctm());
177 189
178 int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX; 190 int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
179 int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY; 191 int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
180 getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffs etX); 192 getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffs etX);
181 getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffs etY); 193 getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffs etY);
182 194
183 if (kernelSizeX < 0 || kernelSizeY < 0) { 195 if (kernelSizeX < 0 || kernelSizeY < 0) {
184 return false; 196 return false;
185 } 197 }
186 198
187 if (kernelSizeX == 0 && kernelSizeY == 0) { 199 if (kernelSizeX == 0 && kernelSizeY == 0) {
188 src.copyTo(dst, dst->colorType()); 200 srcBitmap.copyTo(&dstBitmap, dstBitmap.colorType());
189 offset->fX = srcBounds.fLeft; 201 offset->fX = srcBounds.fLeft;
190 offset->fY = srcBounds.fTop; 202 offset->fY = srcBounds.fTop;
191 return true; 203 return true;
192 } 204 }
193 205
194 SkBitmap temp; 206 SkBitmap temp;
195 if (!temp.tryAllocPixels(dst->info())) { 207 if (!temp.tryAllocPixels(dstBitmap.info())) {
196 return false; 208 return false;
197 } 209 }
198 210
199 offset->fX = srcBounds.fLeft; 211 int32_t resultX = srcBounds.fLeft;
200 offset->fY = srcBounds.fTop; 212 int32_t resultY = srcBounds.fTop;
201 srcBounds.offset(-srcOffset); 213 srcBounds.offset(-srcOffset);
202 const SkPMColor* s = src.getAddr32(srcBounds.left(), srcBounds.top()); 214 const SkPMColor* s = srcBitmap.getAddr32(srcBounds.left(), srcBounds.top());
203 SkPMColor* t = temp.getAddr32(0, 0); 215 SkPMColor* t = temp.getAddr32(0, 0);
204 SkPMColor* d = dst->getAddr32(0, 0); 216 SkPMColor* d = dstBitmap.getAddr32(0, 0);
205 int w = dstBounds.width(), h = dstBounds.height(); 217 int w = dstBounds.width(), h = dstBounds.height();
206 int sw = src.rowBytesAsPixels(); 218 int sw = srcBitmap.rowBytesAsPixels();
207 SkBoxBlurProc boxBlurX, boxBlurY, boxBlurXY, boxBlurYX; 219 SkBoxBlurProc boxBlurX, boxBlurY, boxBlurXY, boxBlurYX;
208 if (!SkBoxBlurGetPlatformProcs(&boxBlurX, &boxBlurY, &boxBlurXY, &boxBlurYX) ) { 220 if (!SkBoxBlurGetPlatformProcs(&boxBlurX, &boxBlurY, &boxBlurXY, &boxBlurYX) ) {
209 boxBlurX = boxBlur<kX, kX>; 221 boxBlurX = boxBlur<kX, kX>;
210 boxBlurY = boxBlur<kY, kY>; 222 boxBlurY = boxBlur<kY, kY>;
211 boxBlurXY = boxBlur<kX, kY>; 223 boxBlurXY = boxBlur<kX, kY>;
212 boxBlurYX = boxBlur<kY, kX>; 224 boxBlurYX = boxBlur<kY, kX>;
213 } 225 }
214 226
215 if (kernelSizeX > 0 && kernelSizeY > 0) { 227 if (kernelSizeX > 0 && kernelSizeY > 0) {
216 boxBlurX(s, sw, t, kernelSizeX, lowOffsetX, highOffsetX, w, h); 228 boxBlurX(s, sw, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
217 boxBlurX(t, w, d, kernelSizeX, highOffsetX, lowOffsetX, w, h); 229 boxBlurX(t, w, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
218 boxBlurXY(d, w, t, kernelSizeX3, highOffsetX, highOffsetX, w, h); 230 boxBlurXY(d, w, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
219 boxBlurX(t, h, d, kernelSizeY, lowOffsetY, highOffsetY, h, w); 231 boxBlurX(t, h, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
220 boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w); 232 boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
221 boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w); 233 boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
222 } else if (kernelSizeX > 0) { 234 } else if (kernelSizeX > 0) {
223 boxBlurX(s, sw, d, kernelSizeX, lowOffsetX, highOffsetX, w, h); 235 boxBlurX(s, sw, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
224 boxBlurX(d, w, t, kernelSizeX, highOffsetX, lowOffsetX, w, h); 236 boxBlurX(d, w, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
225 boxBlurX(t, w, d, kernelSizeX3, highOffsetX, highOffsetX, w, h); 237 boxBlurX(t, w, d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
226 } else if (kernelSizeY > 0) { 238 } else if (kernelSizeY > 0) {
227 boxBlurYX(s, sw, d, kernelSizeY, lowOffsetY, highOffsetY, h, w); 239 boxBlurYX(s, sw, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
228 boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w); 240 boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
229 boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w); 241 boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
230 } 242 }
243 temp = SkBitmap();
244 SkImage* image = SkNewImageFromBitmap(dstBitmap, true, NULL);
245 if (NULL == image) {
246 return false;
247 }
248 dst.reset(image);
249 offset->fX = resultX;
250 offset->fY = resultY;
231 return true; 251 return true;
232 } 252 }
233 253
234 254
235 void SkBlurImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { 255 void SkBlurImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
236 if (getInput(0)) { 256 if (getInput(0)) {
237 getInput(0)->computeFastBounds(src, dst); 257 getInput(0)->computeFastBounds(src, dst);
238 } else { 258 } else {
239 *dst = src; 259 *dst = src;
240 } 260 }
241 261
242 dst->outset(SkScalarMul(fSigma.width(), SkIntToScalar(3)), 262 dst->outset(SkScalarMul(fSigma.width(), SkIntToScalar(3)),
243 SkScalarMul(fSigma.height(), SkIntToScalar(3))); 263 SkScalarMul(fSigma.height(), SkIntToScalar(3)));
244 } 264 }
245 265
246 bool SkBlurImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 266 bool SkBlurImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
247 SkIRect* dst) const { 267 SkIRect* dst) const {
248 SkIRect bounds = src; 268 SkIRect bounds = src;
249 SkVector sigma = mapSigma(fSigma, ctm); 269 SkVector sigma = mapSigma(fSigma, ctm);
250 bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))), 270 bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
251 SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3)))); 271 SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
252 if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { 272 if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) {
253 return false; 273 return false;
254 } 274 }
255 *dst = bounds; 275 *dst = bounds;
256 return true; 276 return true;
257 } 277 }
258 278
259 bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 279 bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, SkImage& src, const Context & ctx,
260 SkBitmap* result, SkIPoint* offset) const { 280 SkAutoTUnref<SkImage>& result, SkIPoint* offset) const {
261 #if SK_SUPPORT_GPU 281 #if SK_SUPPORT_GPU
262 SkBitmap input = src; 282 SkAutoTUnref<SkImage> input(SkRef(&src));
263 SkIPoint srcOffset = SkIPoint::Make(0, 0); 283 SkIPoint srcOffset = SkIPoint::Make(0, 0);
264 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { 284 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, input, & srcOffset)) {
265 return false; 285 return false;
266 } 286 }
267 SkIRect rect; 287 SkIRect rect;
268 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &rect, &input)) { 288 if (!this->applyCropRect(ctx, proxy, *input, &srcOffset, &rect, input)) {
269 return false; 289 return false;
270 } 290 }
271 GrTexture* source = input.getTexture(); 291 GrTexture* source = input->getTexture();
272 SkVector sigma = mapSigma(fSigma, ctx.ctm()); 292 SkVector sigma = mapSigma(fSigma, ctx.ctm());
273 offset->fX = rect.fLeft; 293 offset->fX = rect.fLeft;
274 offset->fY = rect.fTop; 294 offset->fY = rect.fTop;
275 rect.offset(-srcOffset); 295 rect.offset(-srcOffset);
276 SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext( ), 296 SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext( ),
277 source, 297 source,
278 false, 298 false,
279 SkRect::Make(rect), 299 SkRect::Make(rect),
280 true, 300 true,
281 sigma.x(), 301 sigma.x(),
282 sigma.y())); 302 sigma.y()));
283 WrapTexture(tex, rect.width(), rect.height(), result); 303 if (!WrapTexture(tex, rect.width(), rect.height(), result)) {
304 return false;
305 }
284 return true; 306 return true;
285 #else 307 #else
286 SkDEBUGFAIL("Should not call in GPU-less build"); 308 SkDEBUGFAIL("Should not call in GPU-less build");
287 return false; 309 return false;
288 #endif 310 #endif
289 } 311 }
290 312
291 #ifndef SK_IGNORE_TO_STRING 313 #ifndef SK_IGNORE_TO_STRING
292 void SkBlurImageFilter::toString(SkString* str) const { 314 void SkBlurImageFilter::toString(SkString* str) const {
293 str->appendf("SkBlurImageFilter: ("); 315 str->appendf("SkBlurImageFilter: (");
294 str->appendf("sigma: (%f, %f) input (", fSigma.fWidth, fSigma.fHeight); 316 str->appendf("sigma: (%f, %f) input (", fSigma.fWidth, fSigma.fHeight);
295 317
296 if (this->getInput(0)) { 318 if (this->getInput(0)) {
297 this->getInput(0)->toString(str); 319 this->getInput(0)->toString(str);
298 } 320 }
299 321
300 str->append("))"); 322 str->append("))");
301 } 323 }
302 #endif 324 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698