aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Justin Novosad <junov@chromium.org>2017-09-07 13:03:34 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-07 17:47:51 +0000
commit1d3df3848ff297e353a2d0f0fae6ec4a55ab7ba6 (patch)
treea8de8b9c163690fb6c1baec55012523e6736ef63 /src/core
parent60f42494f5d45c38e260ce089cdddfb600f799b2 (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 ensures that transforms get computed on the GPU. This fixes a severe performance regression in Chrome that happened when color correction was enabled. Associated chromium patch for layout test rebaselines: https://chromium-review.googlesource.com/c/chromium/src/+/655483 Merge dependency: Merging this change to the M-62 and M-61 branches also requires merging the following change, otherwise there will be rendering errors: https://skia-review.googlesource.com/c/skia/+/43562 BUG=chromium:760738 Change-Id: I49fd5ef7968272d311249c3824fe15bee4648b73 Reviewed-on: https://skia-review.googlesource.com/43183 Commit-Queue: Justin Novosad <junov@chromium.org> Reviewed-by: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkColorSpaceXformCanvas.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/core/SkColorSpaceXformCanvas.cpp b/src/core/SkColorSpaceXformCanvas.cpp
index 6d6d27b399..dc36d36716 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,22 @@ 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.
+ sk_sp<SkImage> textureImage = image->makeTextureImage(gr, nullptr);
+ if (textureImage)
+ return fXformer->apply(textureImage.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())) ||