summaryrefslogtreecommitdiff
path: root/libs/hwui/VectorDrawable.cpp
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2017-08-31 15:40:12 -0400
committerDerek Sollenberger <djsollen@google.com>2017-08-31 15:50:41 -0400
commit7fe53c1eafff36118d9d6116496d7649b5a3f89d (patch)
treeef8e584e0c905e8d2161d5884b45a4cffc7c6cd7 /libs/hwui/VectorDrawable.cpp
parent9552c2c98c8d9a5a47ec463a2f29e5aa32f774bb (diff)
Render VectorDrawables in software and then upload to the VDAtlas.
For frames with multiple VDs the context switching involved was causing worst case frame times of ~40ms to draw all VDs in the frame whereas this new approach has worst case performance of ~5ms when drawing the same frame (w/ approximately 26 VDs). Bug: 64487466 Test: SystemUiJankTests#testGoToFullShade Change-Id: I5cad0b5df86e5eac3722ee8695fc7511b38b8a7c
Diffstat (limited to 'libs/hwui/VectorDrawable.cpp')
-rw-r--r--libs/hwui/VectorDrawable.cpp43
1 files changed, 15 insertions, 28 deletions
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index f4ce864e83e1..e0373cae9923 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -511,25 +511,19 @@ void Tree::updateCache(sp<skiapipeline::VectorDrawableAtlas>& atlas, GrContext*
}
}
if (!canReuseSurface || mCache.dirty) {
- draw(surface.get(), dst);
+ if (surface) {
+ Bitmap& bitmap = getBitmapUpdateIfDirty();
+ SkBitmap skiaBitmap;
+ bitmap.getSkBitmap(&skiaBitmap);
+ if (!surface->getCanvas()->writePixels(skiaBitmap, dst.fLeft, dst.fTop)) {
+ ALOGD("VectorDrawable caching failed to efficiently upload");
+ surface->getCanvas()->drawBitmap(skiaBitmap, dst.fLeft, dst.fTop);
+ }
+ }
mCache.dirty = false;
}
}
-void Tree::draw(SkSurface* surface, const SkRect& dst) {
- if (surface) {
- SkCanvas* canvas = surface->getCanvas();
- float scaleX = dst.width() / mProperties.getViewportWidth();
- float scaleY = dst.height() / mProperties.getViewportHeight();
- SkAutoCanvasRestore acr(canvas, true);
- canvas->translate(dst.fLeft, dst.fTop);
- canvas->clipRect(SkRect::MakeWH(dst.width(), dst.height()));
- canvas->clear(SK_ColorTRANSPARENT);
- canvas->scale(scaleX, scaleY);
- mRootNode->draw(canvas, false);
- }
-}
-
void Tree::Cache::setAtlas(sp<skiapipeline::VectorDrawableAtlas> newAtlas,
skiapipeline::AtlasKey newAtlasKey) {
LOG_ALWAYS_FATAL_IF(newAtlasKey == INVALID_ATLAS_KEY);
@@ -570,22 +564,15 @@ void Tree::draw(SkCanvas* canvas) {
// Handle the case when VectorDrawableAtlas has been destroyed, because of memory pressure.
// We render the VD into a temporary standalone buffer and mark the frame as dirty. Next
// frame will be cached into the atlas.
+ Bitmap& bitmap = getBitmapUpdateIfDirty();
+ SkBitmap skiaBitmap;
+ bitmap.getSkBitmap(&skiaBitmap);
+
int scaledWidth = SkScalarCeilToInt(mProperties.getScaledWidth());
int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight());
- SkRect src = SkRect::MakeWH(scaledWidth, scaledHeight);
-#ifndef ANDROID_ENABLE_LINEAR_BLENDING
- sk_sp<SkColorSpace> colorSpace = nullptr;
-#else
- sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
-#endif
- SkImageInfo info = SkImageInfo::MakeN32(scaledWidth, scaledHeight, kPremul_SkAlphaType,
- colorSpace);
- sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(canvas->getGrContext(),
- SkBudgeted::kYes, info);
- draw(surface.get(), src);
+ canvas->drawBitmapRect(skiaBitmap, SkRect::MakeWH(scaledWidth, scaledHeight),
+ mutateProperties()->getBounds(), getPaint(), SkCanvas::kFast_SrcRectConstraint);
mCache.clear();
- canvas->drawImageRect(surface->makeImageSnapshot().get(), mutateProperties()->getBounds(),
- getPaint(), SkCanvas::kFast_SrcRectConstraint);
markDirty();
}
}