| 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 |