diff options
author | Derek Sollenberger <djsollen@google.com> | 2018-05-04 12:05:59 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2018-05-04 12:05:59 -0700 |
commit | ecbb3144860d4ff0ea4f5af0ce20ae6bcfe3158e (patch) | |
tree | 0fc4d08f3f628d263c84c491298f21b66c0bab9a /libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp | |
parent | beffa83a0162ff56be225d385575618bbfdb9160 (diff) | |
parent | 1babd54e4ce1d66bb090a13f1af028edd39af4c2 (diff) |
Support readback of TextureView into 565 and extended sRGB. am: 2324991a77
am: 1babd54e4c
Change-Id: Idad79c50a32cdb4c65042da13d08eb68a27fcd6c
Diffstat (limited to 'libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp')
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp index 15277f175350..188ad78b8c82 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp @@ -29,6 +29,8 @@ #include "utils/TraceUtils.h" #include <GrBackendSurface.h> +#include <SkImageInfo.h> +#include <SkBlendMode.h> #include <cutils/properties.h> #include <strings.h> @@ -136,20 +138,49 @@ bool SkiaOpenGLPipeline::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBi deferredLayer->updateTexImage(); deferredLayer->apply(); + // drop the colorSpace as we only support readback into sRGB or extended sRGB + SkImageInfo surfaceInfo = bitmap->info().makeColorSpace(nullptr); + /* This intermediate surface is present to work around a bug in SwiftShader that * prevents us from reading the contents of the layer's texture directly. The * workaround involves first rendering that texture into an intermediate buffer and * then reading from the intermediate buffer into the bitmap. */ sk_sp<SkSurface> tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), - SkBudgeted::kYes, bitmap->info()); + SkBudgeted::kYes, surfaceInfo); + + if (!tmpSurface.get()) { + surfaceInfo = surfaceInfo.makeColorType(SkColorType::kN32_SkColorType); + tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), + SkBudgeted::kYes, surfaceInfo); + if (!tmpSurface.get()) { + ALOGW("Unable to readback GPU contents into the provided bitmap"); + return false; + } + } Layer* layer = deferredLayer->backingLayer(); const SkRect dstRect = SkRect::MakeIWH(bitmap->width(), bitmap->height()); if (LayerDrawable::DrawLayer(mRenderThread.getGrContext(), tmpSurface->getCanvas(), layer, &dstRect)) { sk_sp<SkImage> tmpImage = tmpSurface->makeImageSnapshot(); - if (tmpImage->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), 0, 0)) { + if (tmpImage->readPixels(surfaceInfo, bitmap->getPixels(), bitmap->rowBytes(), 0, 0)) { + bitmap->notifyPixelsChanged(); + return true; + } + + // if we fail to readback from the GPU directly (e.g. 565) then we attempt to read into 8888 + // and then draw that into the destination format before giving up. + SkBitmap tmpBitmap; + SkImageInfo bitmapInfo = SkImageInfo::MakeN32(bitmap->width(), bitmap->height(), + bitmap->alphaType()); + if (tmpBitmap.tryAllocPixels(bitmapInfo) && + tmpImage->readPixels(bitmapInfo, tmpBitmap.getPixels(), + tmpBitmap.rowBytes(), 0, 0)) { + SkCanvas canvas(*bitmap); + SkPaint paint; + paint.setBlendMode(SkBlendMode::kSrc); + canvas.drawBitmap(tmpBitmap, 0, 0, &paint); bitmap->notifyPixelsChanged(); return true; } |