aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrContext.cpp
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2018-05-07 13:33:50 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-07 18:05:29 +0000
commit817847c0c6ca538d5a1b87647dc94cdc31b30c41 (patch)
tree1d439761a0322b39e8a7c2c0249660e639280a32 /src/gpu/GrContext.cpp
parenta724ea55ae788d6a82984571f160de2912875280 (diff)
Update canvas2D read/write pixels fast path to handle BGRA input/output
Change-Id: Ib77b45dc0ea2b00c728b080d6d847f97b1471bff Reviewed-on: https://skia-review.googlesource.com/126482 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/GrContext.cpp')
-rw-r--r--src/gpu/GrContext.cpp66
1 files changed, 44 insertions, 22 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 7b0ab71676..499c71107c 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -887,15 +887,16 @@ bool GrContextPriv::writeSurfacePixels2(GrSurfaceContext* dst, int left, int top
// For canvas2D putImageData performance we have a special code path for unpremul RGBA_8888 srcs
// that are premultiplied on the GPU. This is kept as narrow as possible for now.
- bool canvas2DFastPath = premul &&
- !dst->colorSpaceInfo().isGammaCorrect() &&
- GrColorType::kRGBA_8888 == srcColorType &&
- SkToBool(dst->asRenderTargetContext()) &&
- (dstProxy->config() == kRGBA_8888_GrPixelConfig ||
- dstProxy->config() == kBGRA_8888_GrPixelConfig) &&
- !(pixelOpsFlags & kDontFlush_PixelOpsFlag) &&
- fContext->caps()->isConfigTexturable(kRGBA_8888_GrPixelConfig) &&
- fContext->validPMUPMConversionExists();
+ bool canvas2DFastPath =
+ premul &&
+ !dst->colorSpaceInfo().isGammaCorrect() &&
+ (srcColorType == GrColorType::kRGBA_8888 || srcColorType == GrColorType::kBGRA_8888) &&
+ SkToBool(dst->asRenderTargetContext()) &&
+ (dstProxy->config() == kRGBA_8888_GrPixelConfig ||
+ dstProxy->config() == kBGRA_8888_GrPixelConfig) &&
+ !(pixelOpsFlags & kDontFlush_PixelOpsFlag) &&
+ fContext->caps()->isConfigTexturable(kRGBA_8888_GrPixelConfig) &&
+ fContext->validPMUPMConversionExists();
if (!fContext->caps()->surfaceSupportsWritePixels(dstSurface) || canvas2DFastPath) {
// We don't expect callers that are skipping flushes to require an intermediate draw.
@@ -920,15 +921,27 @@ bool GrContextPriv::writeSurfacePixels2(GrSurfaceContext* dst, int left, int top
return false;
}
uint32_t flags = canvas2DFastPath ? 0 : pixelOpsFlags;
- if (!this->writeSurfacePixels2(tempCtx.get(), 0, 0, width, height, srcColorType,
+ // In the fast path we always write the srcData to the temp context as though it were RGBA.
+ // When the data is really BGRA the write will cause the R and B channels to be swapped in
+ // the intermediate surface which gets corrected by a swizzle effect when drawing to the
+ // dst.
+ auto tmpColorType = canvas2DFastPath ? GrColorType::kRGBA_8888 : srcColorType;
+ if (!this->writeSurfacePixels2(tempCtx.get(), 0, 0, width, height, tmpColorType,
srcColorSpace, buffer, rowBytes, flags)) {
return false;
}
if (canvas2DFastPath) {
GrPaint paint;
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- paint.addColorFragmentProcessor(fContext->createUPMToPMEffect(
- GrSimpleTextureEffect::Make(std::move(tempProxy), SkMatrix::I()), true));
+ auto fp = fContext->createUPMToPMEffect(
+ GrSimpleTextureEffect::Make(std::move(tempProxy), SkMatrix::I()), true);
+ if (srcColorType == GrColorType::kBGRA_8888) {
+ fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
+ }
+ if (!fp) {
+ return false;
+ }
+ paint.addColorFragmentProcessor(std::move(fp));
dst->asRenderTargetContext()->fillRectToRect(
GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
SkRect::MakeXYWH(left, top, width, height), SkRect::MakeWH(width, height));
@@ -1051,14 +1064,15 @@ bool GrContextPriv::readSurfacePixels2(GrSurfaceContext* src, int left, int top,
// getImageData in "legacy" mode are round-trippable we use the GPU to do the complementary
// unpremul step to writeSurfacePixels2's premul step (which is determined empirically in
// fContext->vaildaPMUPMConversionExists()).
- bool canvas2DFastPath = unpremul &&
- !src->colorSpaceInfo().isGammaCorrect() &&
- GrColorType::kRGBA_8888 == dstColorType &&
- SkToBool(srcProxy->asTextureProxy()) &&
- (srcProxy->config() == kRGBA_8888_GrPixelConfig ||
- srcProxy->config() == kBGRA_8888_GrPixelConfig) &&
- fContext->caps()->isConfigRenderable(kRGBA_8888_GrPixelConfig) &&
- fContext->validPMUPMConversionExists();
+ bool canvas2DFastPath =
+ unpremul &&
+ !src->colorSpaceInfo().isGammaCorrect() &&
+ (GrColorType::kRGBA_8888 == dstColorType || GrColorType::kBGRA_8888 == dstColorType) &&
+ SkToBool(srcProxy->asTextureProxy()) &&
+ (srcProxy->config() == kRGBA_8888_GrPixelConfig ||
+ srcProxy->config() == kBGRA_8888_GrPixelConfig) &&
+ fContext->caps()->isConfigRenderable(kRGBA_8888_GrPixelConfig) &&
+ fContext->validPMUPMConversionExists();
if (!fContext->caps()->surfaceSupportsReadPixels(srcSurface) || canvas2DFastPath) {
GrSurfaceDesc desc;
@@ -1088,10 +1102,18 @@ bool GrContextPriv::readSurfacePixels2(GrSurfaceContext* src, int left, int top,
if (canvas2DFastPath) {
GrPaint paint;
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- paint.addColorFragmentProcessor(fContext->createPMToUPMEffect(
+ auto fp = fContext->createPMToUPMEffect(
GrSimpleTextureEffect::Make(sk_ref_sp(srcProxy->asTextureProxy()),
SkMatrix::I()),
- true));
+ true);
+ if (dstColorType == GrColorType::kBGRA_8888) {
+ fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
+ dstColorType = GrColorType::kRGBA_8888;
+ }
+ if (!fp) {
+ return false;
+ }
+ paint.addColorFragmentProcessor(std::move(fp));
tempCtx->asRenderTargetContext()->fillRectToRect(
GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
SkRect::MakeWH(width, height), SkRect::MakeXYWH(left, top, width, height));