diff options
author | Justin Novosad <junov@chromium.org> | 2017-09-05 13:26:16 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-09-05 17:50:25 +0000 |
commit | 19c8726a0829e506c5c42d22d67b3fe7505ed24e (patch) | |
tree | 113f8b630258cb0d30b44b1594bf50d3dc4ae334 /src | |
parent | 63420d6d18cecc3a314a367fe5a1337fd127bd29 (diff) |
Optimize SkColorSpaceXformCanvas for GPU-acceleration
This change ensures that SkImages are uploaded to the GPU before
applying the xform when the destination canvas is on the GPU. This
makes it possible to get hits in the texture cache and it ensure
that transforms get computed on the GPU.
This fixes a severe performance regression in Chrome that happened
when color correction was enabled.
BUG=chromium:760738
Change-Id: I52032a9f06ccbe1a7fd56a91db15377925143b26
Reviewed-on: https://skia-review.googlesource.com/42422
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Justin Novosad <junov@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkColorSpaceXformCanvas.cpp | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/src/core/SkColorSpaceXformCanvas.cpp b/src/core/SkColorSpaceXformCanvas.cpp index 6d6d27b399..4e1b75b117 100644 --- a/src/core/SkColorSpaceXformCanvas.cpp +++ b/src/core/SkColorSpaceXformCanvas.cpp @@ -139,25 +139,25 @@ public: void onDrawImage(const SkImage* img, SkScalar l, SkScalar t, const SkPaint* paint) override { - fTarget->drawImage(fXformer->apply(img).get(), l, t, MaybePaint(paint, fXformer.get())); + fTarget->drawImage(prepareImage(img).get(), l, t, MaybePaint(paint, fXformer.get())); } void onDrawImageRect(const SkImage* img, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) override { - fTarget->drawImageRect(fXformer->apply(img).get(), + fTarget->drawImageRect(prepareImage(img).get(), src ? *src : SkRect::MakeIWH(img->width(), img->height()), dst, MaybePaint(paint, fXformer.get()), constraint); } void onDrawImageNine(const SkImage* img, const SkIRect& center, const SkRect& dst, const SkPaint* paint) override { - fTarget->drawImageNine(fXformer->apply(img).get(), center, dst, + fTarget->drawImageNine(prepareImage(img).get(), center, dst, MaybePaint(paint, fXformer.get())); } void onDrawImageLattice(const SkImage* img, const Lattice& lattice, const SkRect& dst, const SkPaint* paint) override { - fTarget->drawImageLattice(fXformer->apply(img).get(), lattice, dst, + fTarget->drawImageLattice(prepareImage(img).get(), lattice, dst, MaybePaint(paint, fXformer.get())); } void onDrawAtlas(const SkImage* atlas, const SkRSXform* xforms, const SkRect* tex, @@ -169,7 +169,7 @@ public: fXformer->apply(xformed.begin(), colors, count); colors = xformed.begin(); } - fTarget->drawAtlas(fXformer->apply(atlas).get(), xforms, tex, colors, count, mode, cull, + fTarget->drawAtlas(prepareImage(atlas).get(), xforms, tex, colors, count, mode, cull, MaybePaint(paint, fXformer.get())); } @@ -308,6 +308,20 @@ public: void onFlush() override { return fTarget->flush(); } private: + sk_sp<SkImage> prepareImage(const SkImage* image) { + GrContext* gr = fTarget->getGrContext(); + if (gr) { + // If fTarget is GPU-accelerated, we want to upload to a texture + // before applying the transform. This way, we can get cache hits + // in the texture cache and the transform gets applied on the GPU. + return fXformer->apply(image->makeTextureImage(gr, nullptr).get()); + } + // TODO: Extract a sub image corresponding to the src rect in order + // to xform only the useful part of the image. Sub image could be reduced + // even further by taking into account dst_rect+ctm+clip + return fXformer->apply(image); + } + bool skipXform(const SkBitmap& bitmap) { return (!bitmap.colorSpace() && fTargetCS->isSRGB()) || (SkColorSpace::Equals(bitmap.colorSpace(), fTargetCS.get())) || |