diff options
author | Derek Sollenberger <djsollen@google.com> | 2018-05-03 16:12:18 -0400 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2018-05-04 18:46:52 +0000 |
commit | 2324991a77bfe35705c6105f87dcc4fad5f4626c (patch) | |
tree | fe739ff34f446e74e55cbc9eb3cef683fe030529 /libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp | |
parent | 1ed9f4294c408dade7575cae9a7814f79b965be6 (diff) |
Support readback of TextureView into 565 and extended sRGB.
Bug: 78906699
Test: CtsViewTestCases
Change-Id: I89e8544a883dcb3eb222c164ab57d20e55a073c3
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; } |