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" |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 return kUnimplemented_FilterReturn; | 291 return kUnimplemented_FilterReturn; |
292 } | 292 } |
293 | 293 |
294 SkMaskFilter::FilterReturn | 294 SkMaskFilter::FilterReturn |
295 SkMaskFilter::filterRectsToNine(const SkRect[], int count, const SkMatrix&, | 295 SkMaskFilter::filterRectsToNine(const SkRect[], int count, const SkMatrix&, |
296 const SkIRect& clipBounds, NinePatch*) const { | 296 const SkIRect& clipBounds, NinePatch*) const { |
297 return kUnimplemented_FilterReturn; | 297 return kUnimplemented_FilterReturn; |
298 } | 298 } |
299 | 299 |
300 #if SK_SUPPORT_GPU | 300 #if SK_SUPPORT_GPU |
301 bool SkMaskFilter::asNewEffect(GrEffectRef** effect, GrTexture*) const { | 301 bool SkMaskFilter::asNewEffect(GrEffectRef** effect, GrTexture*, const SkMatrix&
) const { |
302 return false; | 302 return false; |
303 } | 303 } |
304 | 304 |
305 bool SkMaskFilter::canFilterMaskGPU(const SkRect& devBounds, | 305 bool SkMaskFilter::canFilterMaskGPU(const SkRect& devBounds, |
306 const SkIRect& clipBounds, | 306 const SkIRect& clipBounds, |
307 const SkMatrix& ctm, | 307 const SkMatrix& ctm, |
308 SkRect* maskRect) const { | 308 SkRect* maskRect) const { |
309 return false; | 309 return false; |
310 } | 310 } |
311 | 311 |
312 bool SkMaskFilter::filterMaskGPU(GrContext* context, | |
313 const SkBitmap& srcBM, | |
314 const SkRect& maskRect, | |
315 SkBitmap* resultBM) const { | |
316 SkAutoTUnref<GrTexture> src; | |
317 bool canOverwriteSrc = false; | |
318 if (NULL == srcBM.getTexture()) { | |
319 GrTextureDesc desc; | |
320 // Needs to be a render target to be overwritten in filterMaskGPU | |
321 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureF
lagBit; | |
322 desc.fConfig = SkBitmapConfig2GrPixelConfig(srcBM.config()); | |
323 desc.fWidth = srcBM.width(); | |
324 desc.fHeight = srcBM.height(); | |
325 | |
326 // TODO: right now this is exact to guard against out of bounds reads | |
327 // by the filter code. More thought needs to be devoted to the | |
328 // "filterMaskGPU" contract and then enforced (i.e., clamp the code | |
329 // in "filterMaskGPU" so it never samples beyond maskRect) | |
330 GrAutoScratchTexture ast(context, desc, GrContext::kExact_ScratchTexMatc
h); | |
331 if (NULL == ast.texture()) { | |
332 return false; | |
333 } | |
334 | |
335 SkAutoLockPixels alp(srcBM); | |
336 ast.texture()->writePixels(0, 0, srcBM.width(), srcBM.height(), | |
337 desc.fConfig, | |
338 srcBM.getPixels(), srcBM.rowBytes()); | |
339 | |
340 src.reset(ast.detach()); | |
341 canOverwriteSrc = true; | |
342 } else { | |
343 src.reset((GrTexture*) srcBM.getTexture()); | |
344 src.get()->ref(); | |
345 } | |
346 GrTexture* dst; | |
347 | |
348 bool result = this->filterMaskGPU(src, maskRect, &dst, canOverwriteSrc); | |
349 if (!result) { | |
350 return false; | |
351 } | |
352 SkAutoUnref aur(dst); | |
353 | |
354 SkImageInfo info; | |
355 resultBM->setConfig(srcBM.config(), dst->width(), dst->height()); | |
356 if (!resultBM->asImageInfo(&info)) { | |
357 return false; | |
358 } | |
359 resultBM->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, dst)))->unref(); | |
360 return true; | |
361 } | |
362 | 312 |
363 bool SkMaskFilter::filterMaskGPU(GrTexture* src, | 313 bool SkMaskFilter::filterMaskGPU(GrTexture* src, |
| 314 const SkMatrix& ctm, |
364 const SkRect& maskRect, | 315 const SkRect& maskRect, |
365 GrTexture** result, | 316 GrTexture** result, |
366 bool canOverwriteSrc) const { | 317 bool canOverwriteSrc) const { |
367 return false; | 318 return false; |
368 } | 319 } |
369 #endif | 320 #endif |
370 | 321 |
371 void SkMaskFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { | 322 void SkMaskFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { |
372 SkMask srcM, dstM; | 323 SkMask srcM, dstM; |
373 | 324 |
374 srcM.fImage = NULL; | 325 srcM.fImage = NULL; |
375 src.roundOut(&srcM.fBounds); | 326 src.roundOut(&srcM.fBounds); |
376 srcM.fRowBytes = 0; | 327 srcM.fRowBytes = 0; |
377 srcM.fFormat = SkMask::kA8_Format; | 328 srcM.fFormat = SkMask::kA8_Format; |
378 | 329 |
379 SkIPoint margin; // ignored | 330 SkIPoint margin; // ignored |
380 if (this->filterMask(&dstM, srcM, SkMatrix::I(), &margin)) { | 331 if (this->filterMask(&dstM, srcM, SkMatrix::I(), &margin)) { |
381 dst->set(dstM.fBounds); | 332 dst->set(dstM.fBounds); |
382 } else { | 333 } else { |
383 dst->set(srcM.fBounds); | 334 dst->set(srcM.fBounds); |
384 } | 335 } |
385 } | 336 } |
OLD | NEW |