diff options
author | Derek Sollenberger <djsollen@google.com> | 2017-08-31 15:40:12 -0400 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2017-08-31 15:50:41 -0400 |
commit | 7fe53c1eafff36118d9d6116496d7649b5a3f89d (patch) | |
tree | ef8e584e0c905e8d2161d5884b45a4cffc7c6cd7 /libs/hwui/VectorDrawable.cpp | |
parent | 9552c2c98c8d9a5a47ec463a2f29e5aa32f774bb (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.cpp | 43 |
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(); } } |