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 |