Fix A2B JPEG images on GPU backed xform or color-managed canvas

A2B images can't be transformed on the GPU, so ensure that
they're "converted" before being uploaded. (This may just
create a new lazy image with an updated color space).

Then, when we're converting JPEG images (YUV) to textures,
don't allow GPU decode if the result needs to go through
A2B conversion (again, we can't do this). In that case,
we just ask the generator (codec) for RGB data, which will
trigger correct CPU conversion before the upload.

Eventually this will be rewritten further, because we won't
allow A2B data in SkColorSpace, but for now this fixes a
problem that's not actually affecting any clients, but is
blocking a GrColorSpaceXform refactor.

Change-Id: I1ebef4a90773d21ec4011ed1ac16aed486ba5539
Reviewed-on: https://skia-review.googlesource.com/133447
Commit-Queue: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
Auto-Submit: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
Brian Osman 2018-06-08 14:11:37 -04:00 committed by Skia Commit-Bot
parent d2ae4df90d
commit 56893cd175
2 changed files with 17 additions and 12 deletions

View File

@ -331,10 +331,11 @@ public:
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.
// 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. We can't do A2B transforms on the GPU, though, so force those down
// the slower CPU path.
if (gr && (!image->colorSpace() || image->colorSpace()->toXYZD50())) {
sk_sp<SkImage> textureImage = image->makeTextureImage(gr, nullptr);
if (textureImage)
return fXformer->apply(textureImage.get());

View File

@ -819,18 +819,22 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx,
// The pixels in the texture will be in the generator's color space. If onMakeColorSpace
// has been called then this will not match this image's color space. To correct this, apply
// a color space conversion from the generator's color space to this image's color space.
// Note that we can only do this conversion (on the GPU) if both color spaces are XYZ type.
const SkColorSpace* generatorColorSpace =
fSharedGenerator->fGenerator->getInfo().colorSpace();
const SkColorSpace* thisColorSpace = fInfo.colorSpace();
// TODO: Update to create the mipped surface in the YUV generator and draw the base layer
// directly into the mipped surface.
proxy = provider.refAsTextureProxy(ctx, desc, generatorColorSpace, thisColorSpace);
if (proxy) {
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kYUV_LockTexturePath,
kLockTexturePathCount);
set_key_on_proxy(proxyProvider, proxy.get(), nullptr, key);
return proxy;
if ((!generatorColorSpace || generatorColorSpace->toXYZD50()) &&
(!thisColorSpace || thisColorSpace->toXYZD50())) {
// TODO: Update to create the mipped surface in the YUV generator and draw the base
// layer directly into the mipped surface.
proxy = provider.refAsTextureProxy(ctx, desc, generatorColorSpace, thisColorSpace);
if (proxy) {
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kYUV_LockTexturePath,
kLockTexturePathCount);
set_key_on_proxy(proxyProvider, proxy.get(), nullptr, key);
return proxy;
}
}
}