| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 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 "SkImageFilter.h" | 8 #include "SkImageFilter.h" |
| 9 #include "SkImageFilterCacheKey.h" | 9 #include "SkImageFilterCacheKey.h" |
| 10 | 10 |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 } | 222 } |
| 223 } | 223 } |
| 224 | 224 |
| 225 sk_sp<SkSpecialImage> result(this->onFilterImage(src, context, offset)); | 225 sk_sp<SkSpecialImage> result(this->onFilterImage(src, context, offset)); |
| 226 | 226 |
| 227 #if SK_SUPPORT_GPU | 227 #if SK_SUPPORT_GPU |
| 228 if (src->isTextureBacked() && result && !result->isTextureBacked()) { | 228 if (src->isTextureBacked() && result && !result->isTextureBacked()) { |
| 229 // Keep the result on the GPU - this is still required for some | 229 // Keep the result on the GPU - this is still required for some |
| 230 // image filters that don't support GPU in all cases | 230 // image filters that don't support GPU in all cases |
| 231 GrContext* context = src->getContext(); | 231 GrContext* context = src->getContext(); |
| 232 result = result->makeTextureImage(src->internal_getProxy(), context); | 232 result = result->makeTextureImage(context); |
| 233 } | 233 } |
| 234 #endif | 234 #endif |
| 235 | 235 |
| 236 if (result && context.cache()) { | 236 if (result && context.cache()) { |
| 237 context.cache()->set(key, result.get(), *offset); | 237 context.cache()->set(key, result.get(), *offset); |
| 238 SkAutoMutexAcquire mutex(fMutex); | 238 SkAutoMutexAcquire mutex(fMutex); |
| 239 fCacheKeys.push_back(key); | 239 fCacheKeys.push_back(key); |
| 240 } | 240 } |
| 241 | 241 |
| 242 return result; | 242 return result; |
| 243 } | 243 } |
| 244 | 244 |
| 245 bool SkImageFilter::filterImageDeprecated(Proxy* proxy, const SkBitmap& src, | |
| 246 const Context& context, | |
| 247 SkBitmap* result, SkIPoint* offset) co
nst { | |
| 248 SkASSERT(result); | |
| 249 SkASSERT(offset); | |
| 250 uint32_t srcGenID = fUsesSrcInput ? src.getGenerationID() : 0; | |
| 251 Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), | |
| 252 srcGenID, SkIRect::MakeWH(0, 0)); | |
| 253 if (context.cache()) { | |
| 254 if (context.cache()->get(key, result, offset)) { | |
| 255 return true; | |
| 256 } | |
| 257 } | |
| 258 if (this->onFilterImageDeprecated(proxy, src, context, result, offset)) { | |
| 259 if (context.cache()) { | |
| 260 context.cache()->set(key, *result, *offset); | |
| 261 SkAutoMutexAcquire mutex(fMutex); | |
| 262 fCacheKeys.push_back(key); | |
| 263 } | |
| 264 return true; | |
| 265 } | |
| 266 return false; | |
| 267 } | |
| 268 | |
| 269 bool SkImageFilter::filterInputDeprecated(int index, Proxy* proxy, const SkBitma
p& src, | |
| 270 const Context& ctx, | |
| 271 SkBitmap* result, SkIPoint* offset) co
nst { | |
| 272 SkImageFilter* input = this->getInput(index); | |
| 273 if (!input) { | |
| 274 return true; | |
| 275 } | |
| 276 | |
| 277 // SRGBTODO: Don't handle sRGB here, in anticipation of this code path being
deleted. | |
| 278 sk_sp<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src,
nullptr)); | |
| 279 if (!specialSrc) { | |
| 280 return false; | |
| 281 } | |
| 282 | |
| 283 sk_sp<SkSpecialImage> tmp(input->onFilterImage(specialSrc.get(), | |
| 284 this->mapContext(ctx), | |
| 285 offset)); | |
| 286 if (!tmp) { | |
| 287 return false; | |
| 288 } | |
| 289 | |
| 290 return tmp->internal_getBM(result); | |
| 291 } | |
| 292 | |
| 293 SkIRect SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, | 245 SkIRect SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, |
| 294 MapDirection direction) const { | 246 MapDirection direction) const { |
| 295 if (kReverse_MapDirection == direction) { | 247 if (kReverse_MapDirection == direction) { |
| 296 SkIRect bounds = this->onFilterNodeBounds(src, ctm, direction); | 248 SkIRect bounds = this->onFilterNodeBounds(src, ctm, direction); |
| 297 return this->onFilterBounds(bounds, ctm, direction); | 249 return this->onFilterBounds(bounds, ctm, direction); |
| 298 } else { | 250 } else { |
| 299 SkIRect bounds = this->onFilterBounds(src, ctm, direction); | 251 SkIRect bounds = this->onFilterBounds(src, ctm, direction); |
| 300 bounds = this->onFilterNodeBounds(bounds, ctm, direction); | 252 bounds = this->onFilterNodeBounds(bounds, ctm, direction); |
| 301 SkIRect dst; | 253 SkIRect dst; |
| 302 this->getCropRect().applyTo(bounds, ctm, this->affectsTransparentBlack()
, &dst); | 254 this->getCropRect().applyTo(bounds, ctm, this->affectsTransparentBlack()
, &dst); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 326 } | 278 } |
| 327 for (int i = 0; i < this->countInputs(); i++) { | 279 for (int i = 0; i < this->countInputs(); i++) { |
| 328 SkImageFilter* input = this->getInput(i); | 280 SkImageFilter* input = this->getInput(i); |
| 329 if (input && !input->canComputeFastBounds()) { | 281 if (input && !input->canComputeFastBounds()) { |
| 330 return false; | 282 return false; |
| 331 } | 283 } |
| 332 } | 284 } |
| 333 return true; | 285 return true; |
| 334 } | 286 } |
| 335 | 287 |
| 336 bool SkImageFilter::onFilterImageDeprecated(Proxy*, const SkBitmap&, const Conte
xt&, | |
| 337 SkBitmap*, SkIPoint*) const { | |
| 338 // Only classes that now use the new SkSpecialImage-based path will not have | |
| 339 // onFilterImageDeprecated methods. For those classes we should never be | |
| 340 // calling this method. | |
| 341 SkASSERT(0); | |
| 342 return false; | |
| 343 } | |
| 344 | |
| 345 // SkImageFilter-derived classes that do not yet have their own onFilterImage | |
| 346 // implementation convert back to calling the deprecated filterImage method | |
| 347 sk_sp<SkSpecialImage> SkImageFilter::onFilterImage(SkSpecialImage* src, const Co
ntext& ctx, | |
| 348 SkIPoint* offset) const { | |
| 349 SkBitmap srcBM, resultBM; | |
| 350 | |
| 351 if (!src->internal_getBM(&srcBM)) { | |
| 352 return nullptr; | |
| 353 } | |
| 354 | |
| 355 // This is the only valid call to the old filterImage path | |
| 356 if (!this->filterImageDeprecated(src->internal_getProxy(), srcBM, ctx, &resu
ltBM, offset)) { | |
| 357 return nullptr; | |
| 358 } | |
| 359 | |
| 360 return SkSpecialImage::internal_fromBM(src->internal_getProxy(), resultBM, &
src->props()); | |
| 361 } | |
| 362 | |
| 363 #if SK_SUPPORT_GPU | 288 #if SK_SUPPORT_GPU |
| 364 sk_sp<SkSpecialImage> SkImageFilter::DrawWithFP(GrContext* context, | 289 sk_sp<SkSpecialImage> SkImageFilter::DrawWithFP(GrContext* context, |
| 365 sk_sp<GrFragmentProcessor> fp, | 290 sk_sp<GrFragmentProcessor> fp, |
| 366 const SkIRect& bounds, | 291 const SkIRect& bounds) { |
| 367 SkImageFilter::Proxy* proxy) { | |
| 368 GrPaint paint; | 292 GrPaint paint; |
| 369 paint.addColorFragmentProcessor(fp.get()); | 293 paint.addColorFragmentProcessor(fp.get()); |
| 370 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); | 294 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); |
| 371 | 295 |
| 372 GrSurfaceDesc desc; | 296 GrSurfaceDesc desc; |
| 373 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 297 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 374 desc.fWidth = bounds.width(); | 298 desc.fWidth = bounds.width(); |
| 375 desc.fHeight = bounds.height(); | 299 desc.fHeight = bounds.height(); |
| 376 desc.fConfig = kRGBA_8888_GrPixelConfig; | 300 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 377 | 301 |
| 378 sk_sp<GrTexture> dst(context->textureProvider()->createApproxTexture(desc)); | 302 sk_sp<GrTexture> dst(context->textureProvider()->createApproxTexture(desc)); |
| 379 if (!dst) { | 303 if (!dst) { |
| 380 return nullptr; | 304 return nullptr; |
| 381 } | 305 } |
| 382 | 306 |
| 383 sk_sp<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget())
); | 307 sk_sp<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget())
); |
| 384 if (!drawContext) { | 308 if (!drawContext) { |
| 385 return nullptr; | 309 return nullptr; |
| 386 } | 310 } |
| 387 | 311 |
| 388 SkRect srcRect = SkRect::Make(bounds); | 312 SkRect srcRect = SkRect::Make(bounds); |
| 389 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); | 313 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); |
| 390 GrClip clip(dstRect); | 314 GrClip clip(dstRect); |
| 391 drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect); | 315 drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect); |
| 392 | 316 |
| 393 return SkSpecialImage::MakeFromGpu(proxy, | 317 return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.he
ight()), |
| 394 SkIRect::MakeWH(bounds.width(), bounds.he
ight()), | |
| 395 kNeedNewImageUniqueID_SpecialImage, | 318 kNeedNewImageUniqueID_SpecialImage, |
| 396 dst.get()); | 319 dst.get()); |
| 397 | 320 |
| 398 } | 321 } |
| 399 #endif | 322 #endif |
| 400 | 323 |
| 401 bool SkImageFilter::asAColorFilter(SkColorFilter** filterPtr) const { | 324 bool SkImageFilter::asAColorFilter(SkColorFilter** filterPtr) const { |
| 402 SkASSERT(nullptr != filterPtr); | 325 SkASSERT(nullptr != filterPtr); |
| 403 if (!this->isColorFilterNode(filterPtr)) { | 326 if (!this->isColorFilterNode(filterPtr)) { |
| 404 return false; | 327 return false; |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 | 596 |
| 674 SK_DECLARE_STATIC_ONCE_PTR(SkImageFilter::Cache, cache); | 597 SK_DECLARE_STATIC_ONCE_PTR(SkImageFilter::Cache, cache); |
| 675 SkImageFilter::Cache* SkImageFilter::Cache::Get() { | 598 SkImageFilter::Cache* SkImageFilter::Cache::Get() { |
| 676 return cache.get([]{ return SkImageFilter::Cache::Create(kDefaultCacheSize);
}); | 599 return cache.get([]{ return SkImageFilter::Cache::Create(kDefaultCacheSize);
}); |
| 677 } | 600 } |
| 678 | 601 |
| 679 void SkImageFilter::PurgeCache() { | 602 void SkImageFilter::PurgeCache() { |
| 680 Cache::Get()->purge(); | 603 Cache::Get()->purge(); |
| 681 } | 604 } |
| 682 | 605 |
| 683 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | |
| 684 | |
| 685 SkBaseDevice* SkImageFilter::DeviceProxy::createDevice(int w, int h, TileUsage u
sage) { | |
| 686 SkBaseDevice::CreateInfo cinfo(SkImageInfo::MakeN32Premul(w, h), | |
| 687 kPossible_TileUsage == usage ? SkBaseDevice::
kPossible_TileUsage | |
| 688 : SkBaseDevice::
kNever_TileUsage, | |
| 689 kUnknown_SkPixelGeometry, | |
| 690 false, /* preserveLCDText */ | |
| 691 true /*forImageFilter*/); | |
| 692 SkBaseDevice* dev = fDevice->onCreateDevice(cinfo, nullptr); | |
| 693 if (nullptr == dev) { | |
| 694 const SkSurfaceProps surfaceProps(fDevice->fSurfaceProps.flags(), | |
| 695 kUnknown_SkPixelGeometry); | |
| 696 dev = SkBitmapDevice::Create(cinfo.fInfo, surfaceProps); | |
| 697 } | |
| 698 return dev; | |
| 699 } | |
| OLD | NEW |