Loading libs/hwui/Android.bp +0 −2 Original line number Diff line number Diff line Loading @@ -221,7 +221,6 @@ cc_defaults { "pipeline/skia/SkiaPipeline.cpp", "pipeline/skia/SkiaProfileRenderer.cpp", "pipeline/skia/SkiaVulkanPipeline.cpp", "pipeline/skia/VectorDrawableAtlas.cpp", "pipeline/skia/VkFunctorDrawable.cpp", "pipeline/skia/VkInteropFunctorDrawable.cpp", "renderstate/RenderState.cpp", Loading Loading @@ -347,7 +346,6 @@ cc_test { "tests/unit/ThreadBaseTests.cpp", "tests/unit/TypefaceTests.cpp", "tests/unit/VectorDrawableTests.cpp", "tests/unit/VectorDrawableAtlasTests.cpp", "tests/unit/WebViewFunctorManagerTests.cpp", ], } Loading libs/hwui/VectorDrawable.cpp +7 −113 Original line number Diff line number Diff line Loading @@ -496,87 +496,6 @@ Bitmap& Tree::getBitmapUpdateIfDirty() { return *mCache.bitmap; } void Tree::updateCache(sp<skiapipeline::VectorDrawableAtlas>& atlas, GrContext* context) { #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration SkRect dst; sk_sp<SkSurface> surface = mCache.getSurface(&dst); bool canReuseSurface = surface && dst.width() >= mProperties.getScaledWidth() && dst.height() >= mProperties.getScaledHeight(); if (!canReuseSurface) { int scaledWidth = SkScalarCeilToInt(mProperties.getScaledWidth()); int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight()); auto atlasEntry = atlas->requestNewEntry(scaledWidth, scaledHeight, context); if (INVALID_ATLAS_KEY != atlasEntry.key) { dst = atlasEntry.rect; surface = atlasEntry.surface; mCache.setAtlas(atlas, atlasEntry.key); } else { // don't draw, if we failed to allocate an offscreen buffer mCache.clear(); surface.reset(); } } if (!canReuseSurface || mCache.dirty) { if (surface) { Bitmap& bitmap = getBitmapUpdateIfDirty(); SkBitmap skiaBitmap; bitmap.getSkBitmap(&skiaBitmap); surface->writePixels(skiaBitmap, dst.fLeft, dst.fTop); } mCache.dirty = false; } #endif } void Tree::Cache::setAtlas(sp<skiapipeline::VectorDrawableAtlas> newAtlas, skiapipeline::AtlasKey newAtlasKey) { LOG_ALWAYS_FATAL_IF(newAtlasKey == INVALID_ATLAS_KEY); clear(); mAtlas = newAtlas; mAtlasKey = newAtlasKey; } sk_sp<SkSurface> Tree::Cache::getSurface(SkRect* bounds) { sk_sp<SkSurface> surface; #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration sp<skiapipeline::VectorDrawableAtlas> atlas = mAtlas.promote(); if (atlas.get() && mAtlasKey != INVALID_ATLAS_KEY) { auto atlasEntry = atlas->getEntry(mAtlasKey); *bounds = atlasEntry.rect; surface = atlasEntry.surface; mAtlasKey = atlasEntry.key; } #endif return surface; } void Tree::Cache::clear() { #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration if (mAtlasKey != INVALID_ATLAS_KEY) { if (renderthread::RenderThread::isCurrent()) { sp<skiapipeline::VectorDrawableAtlas> lockAtlas = mAtlas.promote(); if (lockAtlas.get()) { lockAtlas->releaseEntry(mAtlasKey); } } else { // VectorDrawableAtlas can be accessed only on RenderThread. // Use by-copy capture of the current Cache variables, because "this" may not be valid // by the time the lambda is evaluated on RenderThread. renderthread::RenderThread::getInstance().queue().post( [atlas = mAtlas, atlasKey = mAtlasKey]() { sp<skiapipeline::VectorDrawableAtlas> lockAtlas = atlas.promote(); if (lockAtlas.get()) { lockAtlas->releaseEntry(atlasKey); } }); } mAtlasKey = INVALID_ATLAS_KEY; } mAtlas = nullptr; #endif } void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) { if (canvas->quickReject(bounds)) { // The RenderNode is on screen, but the AVD is not. Loading @@ -587,8 +506,6 @@ void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) SkPaint paint = inPaint; paint.setAlpha(mProperties.getRootAlpha() * 255); if (canvas->getGrContext() == nullptr) { // Recording to picture, don't use the SkSurface which won't work off of renderthread. Bitmap& bitmap = getBitmapUpdateIfDirty(); SkBitmap skiaBitmap; bitmap.getSkBitmap(&skiaBitmap); Loading @@ -597,29 +514,6 @@ void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight()); canvas->drawBitmapRect(skiaBitmap, SkRect::MakeWH(scaledWidth, scaledHeight), bounds, &paint, SkCanvas::kFast_SrcRectConstraint); return; } SkRect src; sk_sp<SkSurface> vdSurface = mCache.getSurface(&src); if (vdSurface) { canvas->drawImageRect(vdSurface->makeImageSnapshot().get(), src, bounds, &paint, SkCanvas::kFast_SrcRectConstraint); } else { // 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()); canvas->drawBitmapRect(skiaBitmap, SkRect::MakeWH(scaledWidth, scaledHeight), bounds, &paint, SkCanvas::kFast_SrcRectConstraint); mCache.clear(); markDirty(); } } void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) { Loading libs/hwui/VectorDrawable.h +0 −33 Original line number Diff line number Diff line Loading @@ -651,46 +651,13 @@ public: void getPaintFor(SkPaint* outPaint, const TreeProperties &props) const; BitmapPalette computePalette(); /** * Draws VD into a GPU backed surface. * This should always be called from RT and it works with Skia pipeline only. */ void updateCache(sp<skiapipeline::VectorDrawableAtlas>& atlas, GrContext* context); void setAntiAlias(bool aa) { mRootNode->setAntiAlias(aa); } private: class Cache { public: sk_sp<Bitmap> bitmap; // used by HWUI pipeline and software // TODO: use surface instead of bitmap when drawing in software canvas bool dirty = true; // the rest of the code in Cache is used by Skia pipelines only ~Cache() { clear(); } /** * Stores a weak pointer to the atlas and a key. */ void setAtlas(sp<skiapipeline::VectorDrawableAtlas> atlas, skiapipeline::AtlasKey newAtlasKey); /** * Gets a surface and bounds from the atlas. * * @return nullptr if the altas has been deleted. */ sk_sp<SkSurface> getSurface(SkRect* bounds); /** * Releases atlas key from the atlas, which makes it available for reuse. */ void clear(); private: wp<skiapipeline::VectorDrawableAtlas> mAtlas; skiapipeline::AtlasKey mAtlasKey = INVALID_ATLAS_KEY; }; bool allocateBitmapIfNeeded(Cache& cache, int width, int height); Loading libs/hwui/pipeline/skia/SkiaDisplayList.cpp +0 −5 Original line number Diff line number Diff line Loading @@ -150,12 +150,7 @@ bool SkiaDisplayList::prepareListAndChildren( const SkRect& bounds = vectorDrawable->properties().getBounds(); if (intersects(info.screenSize, totalMatrix, bounds)) { isDirty = true; #ifdef __ANDROID__ // Layoutlib does not support CanvasContext static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline()) ->getVectorDrawables() ->push_back(vectorDrawable); vectorDrawable->setPropertyChangeWillBeConsumed(true); #endif } } } Loading libs/hwui/pipeline/skia/SkiaPipeline.cpp +0 −23 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ namespace uirenderer { namespace skiapipeline { SkiaPipeline::SkiaPipeline(RenderThread& thread) : mRenderThread(thread) { mVectorDrawables.reserve(30); } SkiaPipeline::~SkiaPipeline() { Loading Loading @@ -73,18 +72,11 @@ void SkiaPipeline::unpinImages() { mPinnedImages.clear(); } void SkiaPipeline::onPrepareTree() { // The only time mVectorDrawables is not empty is if prepare tree was called 2 times without // a renderFrame in the middle. mVectorDrawables.clear(); } void SkiaPipeline::renderLayers(const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, bool opaque, const LightInfo& lightInfo) { LightingInfo::updateLighting(lightGeometry, lightInfo); ATRACE_NAME("draw layers"); renderVectorDrawableCache(); renderLayersImpl(*layerUpdateQueue, opaque); layerUpdateQueue->clear(); } Loading Loading @@ -213,19 +205,6 @@ void SkiaPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) { } } void SkiaPipeline::renderVectorDrawableCache() { if (!mVectorDrawables.empty()) { sp<VectorDrawableAtlas> atlas = mRenderThread.cacheManager().acquireVectorDrawableAtlas(); auto grContext = mRenderThread.getGrContext(); atlas->prepareForDraw(grContext); ATRACE_NAME("Update VectorDrawables"); for (auto vd : mVectorDrawables) { vd->updateCache(atlas, grContext); } mVectorDrawables.clear(); } } static void savePictureAsync(const sk_sp<SkData>& data, const std::string& filename) { CommonPool::post([data, filename] { if (0 == access(filename.c_str(), F_OK)) { Loading Loading @@ -380,8 +359,6 @@ void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& cli Properties::skpCaptureEnabled = true; } renderVectorDrawableCache(); // draw all layers up front renderLayersImpl(layers, opaque); Loading Loading
libs/hwui/Android.bp +0 −2 Original line number Diff line number Diff line Loading @@ -221,7 +221,6 @@ cc_defaults { "pipeline/skia/SkiaPipeline.cpp", "pipeline/skia/SkiaProfileRenderer.cpp", "pipeline/skia/SkiaVulkanPipeline.cpp", "pipeline/skia/VectorDrawableAtlas.cpp", "pipeline/skia/VkFunctorDrawable.cpp", "pipeline/skia/VkInteropFunctorDrawable.cpp", "renderstate/RenderState.cpp", Loading Loading @@ -347,7 +346,6 @@ cc_test { "tests/unit/ThreadBaseTests.cpp", "tests/unit/TypefaceTests.cpp", "tests/unit/VectorDrawableTests.cpp", "tests/unit/VectorDrawableAtlasTests.cpp", "tests/unit/WebViewFunctorManagerTests.cpp", ], } Loading
libs/hwui/VectorDrawable.cpp +7 −113 Original line number Diff line number Diff line Loading @@ -496,87 +496,6 @@ Bitmap& Tree::getBitmapUpdateIfDirty() { return *mCache.bitmap; } void Tree::updateCache(sp<skiapipeline::VectorDrawableAtlas>& atlas, GrContext* context) { #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration SkRect dst; sk_sp<SkSurface> surface = mCache.getSurface(&dst); bool canReuseSurface = surface && dst.width() >= mProperties.getScaledWidth() && dst.height() >= mProperties.getScaledHeight(); if (!canReuseSurface) { int scaledWidth = SkScalarCeilToInt(mProperties.getScaledWidth()); int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight()); auto atlasEntry = atlas->requestNewEntry(scaledWidth, scaledHeight, context); if (INVALID_ATLAS_KEY != atlasEntry.key) { dst = atlasEntry.rect; surface = atlasEntry.surface; mCache.setAtlas(atlas, atlasEntry.key); } else { // don't draw, if we failed to allocate an offscreen buffer mCache.clear(); surface.reset(); } } if (!canReuseSurface || mCache.dirty) { if (surface) { Bitmap& bitmap = getBitmapUpdateIfDirty(); SkBitmap skiaBitmap; bitmap.getSkBitmap(&skiaBitmap); surface->writePixels(skiaBitmap, dst.fLeft, dst.fTop); } mCache.dirty = false; } #endif } void Tree::Cache::setAtlas(sp<skiapipeline::VectorDrawableAtlas> newAtlas, skiapipeline::AtlasKey newAtlasKey) { LOG_ALWAYS_FATAL_IF(newAtlasKey == INVALID_ATLAS_KEY); clear(); mAtlas = newAtlas; mAtlasKey = newAtlasKey; } sk_sp<SkSurface> Tree::Cache::getSurface(SkRect* bounds) { sk_sp<SkSurface> surface; #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration sp<skiapipeline::VectorDrawableAtlas> atlas = mAtlas.promote(); if (atlas.get() && mAtlasKey != INVALID_ATLAS_KEY) { auto atlasEntry = atlas->getEntry(mAtlasKey); *bounds = atlasEntry.rect; surface = atlasEntry.surface; mAtlasKey = atlasEntry.key; } #endif return surface; } void Tree::Cache::clear() { #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration if (mAtlasKey != INVALID_ATLAS_KEY) { if (renderthread::RenderThread::isCurrent()) { sp<skiapipeline::VectorDrawableAtlas> lockAtlas = mAtlas.promote(); if (lockAtlas.get()) { lockAtlas->releaseEntry(mAtlasKey); } } else { // VectorDrawableAtlas can be accessed only on RenderThread. // Use by-copy capture of the current Cache variables, because "this" may not be valid // by the time the lambda is evaluated on RenderThread. renderthread::RenderThread::getInstance().queue().post( [atlas = mAtlas, atlasKey = mAtlasKey]() { sp<skiapipeline::VectorDrawableAtlas> lockAtlas = atlas.promote(); if (lockAtlas.get()) { lockAtlas->releaseEntry(atlasKey); } }); } mAtlasKey = INVALID_ATLAS_KEY; } mAtlas = nullptr; #endif } void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) { if (canvas->quickReject(bounds)) { // The RenderNode is on screen, but the AVD is not. Loading @@ -587,8 +506,6 @@ void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) SkPaint paint = inPaint; paint.setAlpha(mProperties.getRootAlpha() * 255); if (canvas->getGrContext() == nullptr) { // Recording to picture, don't use the SkSurface which won't work off of renderthread. Bitmap& bitmap = getBitmapUpdateIfDirty(); SkBitmap skiaBitmap; bitmap.getSkBitmap(&skiaBitmap); Loading @@ -597,29 +514,6 @@ void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight()); canvas->drawBitmapRect(skiaBitmap, SkRect::MakeWH(scaledWidth, scaledHeight), bounds, &paint, SkCanvas::kFast_SrcRectConstraint); return; } SkRect src; sk_sp<SkSurface> vdSurface = mCache.getSurface(&src); if (vdSurface) { canvas->drawImageRect(vdSurface->makeImageSnapshot().get(), src, bounds, &paint, SkCanvas::kFast_SrcRectConstraint); } else { // 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()); canvas->drawBitmapRect(skiaBitmap, SkRect::MakeWH(scaledWidth, scaledHeight), bounds, &paint, SkCanvas::kFast_SrcRectConstraint); mCache.clear(); markDirty(); } } void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) { Loading
libs/hwui/VectorDrawable.h +0 −33 Original line number Diff line number Diff line Loading @@ -651,46 +651,13 @@ public: void getPaintFor(SkPaint* outPaint, const TreeProperties &props) const; BitmapPalette computePalette(); /** * Draws VD into a GPU backed surface. * This should always be called from RT and it works with Skia pipeline only. */ void updateCache(sp<skiapipeline::VectorDrawableAtlas>& atlas, GrContext* context); void setAntiAlias(bool aa) { mRootNode->setAntiAlias(aa); } private: class Cache { public: sk_sp<Bitmap> bitmap; // used by HWUI pipeline and software // TODO: use surface instead of bitmap when drawing in software canvas bool dirty = true; // the rest of the code in Cache is used by Skia pipelines only ~Cache() { clear(); } /** * Stores a weak pointer to the atlas and a key. */ void setAtlas(sp<skiapipeline::VectorDrawableAtlas> atlas, skiapipeline::AtlasKey newAtlasKey); /** * Gets a surface and bounds from the atlas. * * @return nullptr if the altas has been deleted. */ sk_sp<SkSurface> getSurface(SkRect* bounds); /** * Releases atlas key from the atlas, which makes it available for reuse. */ void clear(); private: wp<skiapipeline::VectorDrawableAtlas> mAtlas; skiapipeline::AtlasKey mAtlasKey = INVALID_ATLAS_KEY; }; bool allocateBitmapIfNeeded(Cache& cache, int width, int height); Loading
libs/hwui/pipeline/skia/SkiaDisplayList.cpp +0 −5 Original line number Diff line number Diff line Loading @@ -150,12 +150,7 @@ bool SkiaDisplayList::prepareListAndChildren( const SkRect& bounds = vectorDrawable->properties().getBounds(); if (intersects(info.screenSize, totalMatrix, bounds)) { isDirty = true; #ifdef __ANDROID__ // Layoutlib does not support CanvasContext static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline()) ->getVectorDrawables() ->push_back(vectorDrawable); vectorDrawable->setPropertyChangeWillBeConsumed(true); #endif } } } Loading
libs/hwui/pipeline/skia/SkiaPipeline.cpp +0 −23 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ namespace uirenderer { namespace skiapipeline { SkiaPipeline::SkiaPipeline(RenderThread& thread) : mRenderThread(thread) { mVectorDrawables.reserve(30); } SkiaPipeline::~SkiaPipeline() { Loading Loading @@ -73,18 +72,11 @@ void SkiaPipeline::unpinImages() { mPinnedImages.clear(); } void SkiaPipeline::onPrepareTree() { // The only time mVectorDrawables is not empty is if prepare tree was called 2 times without // a renderFrame in the middle. mVectorDrawables.clear(); } void SkiaPipeline::renderLayers(const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, bool opaque, const LightInfo& lightInfo) { LightingInfo::updateLighting(lightGeometry, lightInfo); ATRACE_NAME("draw layers"); renderVectorDrawableCache(); renderLayersImpl(*layerUpdateQueue, opaque); layerUpdateQueue->clear(); } Loading Loading @@ -213,19 +205,6 @@ void SkiaPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) { } } void SkiaPipeline::renderVectorDrawableCache() { if (!mVectorDrawables.empty()) { sp<VectorDrawableAtlas> atlas = mRenderThread.cacheManager().acquireVectorDrawableAtlas(); auto grContext = mRenderThread.getGrContext(); atlas->prepareForDraw(grContext); ATRACE_NAME("Update VectorDrawables"); for (auto vd : mVectorDrawables) { vd->updateCache(atlas, grContext); } mVectorDrawables.clear(); } } static void savePictureAsync(const sk_sp<SkData>& data, const std::string& filename) { CommonPool::post([data, filename] { if (0 == access(filename.c_str(), F_OK)) { Loading Loading @@ -380,8 +359,6 @@ void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& cli Properties::skpCaptureEnabled = true; } renderVectorDrawableCache(); // draw all layers up front renderLayersImpl(layers, opaque); Loading