diff options
author | Derek Sollenberger <djsollen@google.com> | 2018-05-04 12:00:32 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2018-05-04 12:00:32 -0700 |
commit | 1babd54e4ce1d66bb090a13f1af028edd39af4c2 (patch) | |
tree | af27989ae914c6371b27f78aea48195e8b3a82dd /libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp | |
parent | 20086c70453452ee392c606cd68a4f66416e3a5c (diff) | |
parent | 2324991a77bfe35705c6105f87dcc4fad5f4626c (diff) |
Support readback of TextureView into 565 and extended sRGB.
am: 2324991a77
Change-Id: If80572b06965089415c32b6ded8b6b1b5fda19b5
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 d732a46e6ee4..79bb534a99be 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp @@ -28,6 +28,8 @@ #include "utils/TraceUtils.h" #include <GrBackendSurface.h> +#include <SkImageInfo.h> +#include <SkBlendMode.h> #include <cutils/properties.h> #include <strings.h> @@ -129,20 +131,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; } |