OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkMaskFilter.h" | 10 #include "SkMaskFilter.h" |
11 #include "SkBlitter.h" | 11 #include "SkBlitter.h" |
12 #include "SkBounder.h" | 12 #include "SkBounder.h" |
13 #include "SkDraw.h" | 13 #include "SkDraw.h" |
14 #include "SkGr.h" | |
15 #include "SkGrPixelRef.h" | |
14 #include "SkRasterClip.h" | 16 #include "SkRasterClip.h" |
17 #include "SkTypes.h" | |
18 #include "GrTexture.h" | |
15 | 19 |
16 | 20 |
17 SK_DEFINE_INST_COUNT(SkMaskFilter) | 21 SK_DEFINE_INST_COUNT(SkMaskFilter) |
18 | 22 |
19 bool SkMaskFilter::filterMask(SkMask*, const SkMask&, const SkMatrix&, | 23 bool SkMaskFilter::filterMask(SkMask*, const SkMask&, const SkMatrix&, |
20 SkIPoint*) const { | 24 SkIPoint*) const { |
21 return false; | 25 return false; |
22 } | 26 } |
23 | 27 |
24 static void extractMaskSubset(const SkMask& src, SkMask* dst) { | 28 static void extractMaskSubset(const SkMask& src, SkMask* dst) { |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 | 263 |
260 return true; | 264 return true; |
261 } | 265 } |
262 | 266 |
263 SkMaskFilter::FilterReturn | 267 SkMaskFilter::FilterReturn |
264 SkMaskFilter::filterRectsToNine(const SkRect[], int count, const SkMatrix&, | 268 SkMaskFilter::filterRectsToNine(const SkRect[], int count, const SkMatrix&, |
265 const SkIRect& clipBounds, NinePatch*) const { | 269 const SkIRect& clipBounds, NinePatch*) const { |
266 return kUnimplemented_FilterReturn; | 270 return kUnimplemented_FilterReturn; |
267 } | 271 } |
268 | 272 |
269 SkMaskFilter::BlurType SkMaskFilter::asABlur(BlurInfo*) const { | 273 bool SkMaskFilter::asNewEffect(GrEffectRef** effect, GrTexture*) const { |
270 return kNone_BlurType; | 274 return false; |
275 } | |
276 | |
277 bool SkMaskFilter::canFilterMaskGPU(const SkRect& devBounds, | |
278 const SkIRect& clipBounds, | |
279 const SkMatrix& ctm, | |
280 SkRect* maskRect) const { | |
281 return false; | |
282 } | |
283 | |
284 bool SkMaskFilter::filterMaskGPU(GrContext* context, | |
285 const SkBitmap& srcBM, | |
286 const SkRect& maskRect, | |
287 SkBitmap* resultBM) const { | |
288 SkAutoTUnref<GrTexture> src; | |
289 bool canOverwriteSrc = false; | |
290 if (NULL == srcBM.getTexture()) { | |
291 GrTextureDesc desc; | |
292 // Needs to be a render target to be overwritten in filterMaskGPU | |
293 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureF lagBit; | |
294 desc.fConfig = SkBitmapConfig2GrPixelConfig(srcBM.config()); | |
295 desc.fWidth = srcBM.width(); | |
296 desc.fHeight = srcBM.height(); | |
297 | |
298 // TODO: right now this is exact to guard against out of bounds reads | |
299 // by the filter code. More thought needs to be devoted to the | |
300 // "filterMaskGPU" contract and then enforced (i.e., clamp the code | |
301 // in "filterMaskGPU" so it never samples beyond maskRect) | |
302 GrAutoScratchTexture ast(context, desc, GrContext::kExact_ScratchTexMatc h); | |
303 if (NULL == ast.texture()) { | |
304 return false; | |
305 } | |
306 | |
307 SkAutoLockPixels alp(srcBM); | |
308 ast.texture()->writePixels(0, 0, srcBM.width(), srcBM.height(), | |
309 desc.fConfig, | |
310 srcBM.getPixels(), srcBM.rowBytes()); | |
311 | |
312 src.reset(ast.detach()); | |
313 canOverwriteSrc = true; | |
314 } else { | |
315 src.reset((GrTexture*) srcBM.getTexture()); | |
316 src.get()->ref(); | |
317 } | |
318 GrTexture* dst; | |
319 | |
320 bool result = this->filterMaskGPU(src, maskRect, &dst, canOverwriteSrc); | |
321 if (!result) { | |
322 return false; | |
323 } | |
324 | |
325 resultBM->setConfig(srcBM.config(), dst->width(), dst->height()); | |
326 resultBM->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (dst)))->unref(); | |
327 dst->unref(); | |
Stephen White
2013/07/03 14:32:56
FYI, one of the reasons I changed the SkImageFilte
| |
328 return true; | |
329 } | |
330 | |
331 bool SkMaskFilter::filterMaskGPU(GrTexture* src, | |
332 const SkRect& maskRect, | |
333 GrTexture** result, | |
334 bool canOverwriteSrc) const { | |
335 return false; | |
271 } | 336 } |
272 | 337 |
273 void SkMaskFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { | 338 void SkMaskFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { |
274 SkMask srcM, dstM; | 339 SkMask srcM, dstM; |
275 | 340 |
276 srcM.fImage = NULL; | 341 srcM.fImage = NULL; |
277 src.roundOut(&srcM.fBounds); | 342 src.roundOut(&srcM.fBounds); |
278 srcM.fRowBytes = 0; | 343 srcM.fRowBytes = 0; |
279 srcM.fFormat = SkMask::kA8_Format; | 344 srcM.fFormat = SkMask::kA8_Format; |
280 | 345 |
281 SkIPoint margin; // ignored | 346 SkIPoint margin; // ignored |
282 if (this->filterMask(&dstM, srcM, SkMatrix::I(), &margin)) { | 347 if (this->filterMask(&dstM, srcM, SkMatrix::I(), &margin)) { |
283 dst->set(dstM.fBounds); | 348 dst->set(dstM.fBounds); |
284 } else { | 349 } else { |
285 dst->set(srcM.fBounds); | 350 dst->set(srcM.fBounds); |
286 } | 351 } |
287 } | 352 } |
OLD | NEW |