Chromium Code Reviews| 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 |