summaryrefslogtreecommitdiff
path: root/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2018-05-04 12:05:59 -0700
committerandroid-build-merger <android-build-merger@google.com>2018-05-04 12:05:59 -0700
commitecbb3144860d4ff0ea4f5af0ce20ae6bcfe3158e (patch)
tree0fc4d08f3f628d263c84c491298f21b66c0bab9a /libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
parentbeffa83a0162ff56be225d385575618bbfdb9160 (diff)
parent1babd54e4ce1d66bb090a13f1af028edd39af4c2 (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.cpp35
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;
}