Loading libs/hwui/DisplayList.cpp +3 −5 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "RecordedOp.h" #include "RenderNode.h" #include "VectorDrawable.h" #include "renderthread/CanvasContext.h" namespace android { namespace uirenderer { Loading Loading @@ -105,11 +106,8 @@ void DisplayList::updateChildren(std::function<void(RenderNode*)> updateFn) { bool DisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLayer, std::function<void(RenderNode*, TreeInfo&, bool)> childFn) { TextureCache& cache = Caches::getInstance().textureCache; for (auto& bitmapResource : bitmapResources) { void* ownerToken = &info.canvasContext; info.prepareTextures = cache.prefetchAndMarkInUse(ownerToken, bitmapResource.get()); } info.prepareTextures = info.canvasContext.pinImages(bitmapResources); for (auto&& op : children) { RenderNode* childNode = op->renderNode; info.damageAccumulator->pushTransform(&op->localMatrix); Loading libs/hwui/pipeline/skia/SkiaDisplayList.cpp +9 −44 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ #include "VectorDrawable.h" #include <SkImagePriv.h> #include <SkMutex.h> namespace android { namespace uirenderer { Loading @@ -40,7 +40,7 @@ void SkiaDisplayList::syncContents() { } bool SkiaDisplayList::reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context) { reset(context ? context->getGrContext() : nullptr, SkRect::MakeEmpty()); reset(SkRect::MakeEmpty()); node->attachAvailableList(this); return true; } Loading @@ -53,9 +53,12 @@ void SkiaDisplayList::updateChildren(std::function<void(RenderNode*)> updateFn) bool SkiaDisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLayer, std::function<void(RenderNode*, TreeInfo&, bool)> childFn) { // force all mutable images to be pinned in the GPU cache for the duration // of this frame pinImages(info.canvasContext.getGrContext()); // If the prepare tree is triggered by the UI thread then we must force all // mutable images to be pinned in the GPU cache until the next UI thread // draw if (info.mode == TreeInfo::MODE_FULL) { info.prepareTextures = info.canvasContext.pinImages(mMutableImages); } for (auto& child : mChildNodes) { RenderNode* childNode = child.getRenderNode(); Loading @@ -78,45 +81,7 @@ bool SkiaDisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLa return isDirty; } static std::vector<sk_sp<SkImage>> gPinnedImages; static SkBaseMutex gLock; void SkiaDisplayList::pinImages(GrContext* context) { if (mPinnedImages) return; for (SkImage* image : mMutableImages) { SkImage_pinAsTexture(image, context); } mPinnedImages = true; } void SkiaDisplayList::unpinImages(GrContext* context) { if (!mPinnedImages) return; if (context) { for (SkImage* image : mMutableImages) { SkImage_unpinAsTexture(image, context); } } else { gLock.acquire(); for (SkImage* image : mMutableImages) { gPinnedImages.emplace_back(sk_ref_sp(image)); } gLock.release(); } mPinnedImages = false; } void SkiaDisplayList::cleanupImages(GrContext* context) { gLock.acquire(); for (auto& image : gPinnedImages) { SkImage_unpinAsTexture(image.get(), context); } gPinnedImages.clear(); gLock.release(); } void SkiaDisplayList::reset(GrContext* context, SkRect bounds) { unpinImages(context); SkASSERT(!mPinnedImages); void SkiaDisplayList::reset(SkRect bounds) { mIsProjectionReceiver = false; mDrawable->reset(bounds); Loading libs/hwui/pipeline/skia/SkiaDisplayList.h +1 −19 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ public: * constructed with the provided bounds. The reuse avoids any overhead * associated with destroying the SkLiteDL as well as the deques and vectors. */ void reset(GrContext* context, SkRect bounds); void reset(SkRect bounds); /** * Use the linear allocator to create any SkDrawables needed by the display Loading Loading @@ -118,21 +118,6 @@ public: */ void updateChildren(std::function<void(RenderNode*)> updateFn) override; /** * Pin/Unpin any mutable images to the GPU cache. A pinned images is * guaranteed to be remain in the cache until it has been unpinned which * we leverage to avoid making a CPU copy of the pixels. */ void pinImages(GrContext* context); void unpinImages(GrContext* context); /** * If a SkiaDisplayList is deleted on the UI thread we cache a list of any * images that need unpinned from the GPU cache and call this function on * a subsequent frame to perform that cleanup. */ static void cleanupImages(GrContext* context); /** * We use std::deque here because (1) we need to iterate through these * elements and (2) mDrawable holds pointers to the elements, so they cannot Loading @@ -145,9 +130,6 @@ public: sk_sp<SkLiteDL> mDrawable; bool mIsProjectionReceiver = false; private: bool mPinnedImages = false; }; }; // namespace skiapipeline Loading libs/hwui/pipeline/skia/SkiaPipeline.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -46,6 +46,22 @@ void SkiaPipeline::onDestroyHardwareResources() { // which will flush temporary resources over time. } bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) { for (SkImage* image : mutableImages) { mPinnedImages.emplace_back(sk_ref_sp(image)); // TODO: return false if texture creation fails (see b/32691999) SkImage_pinAsTexture(image, mRenderThread.getGrContext()); } return true; } void SkiaPipeline::unpinImages() { for (auto& image : mPinnedImages) { SkImage_unpinAsTexture(image.get(), mRenderThread.getGrContext()); } mPinnedImages.clear(); } void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, bool opaque, const BakedOpRenderer::LightInfo& lightInfo) { Loading Loading @@ -154,9 +170,6 @@ void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& cli const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds, sk_sp<SkSurface> surface) { // unpin all mutable images that were attached to nodes deleted while on the UI thread SkiaDisplayList::cleanupImages(surface->getCanvas()->getGrContext()); // draw all layers up front renderLayersImpl(layers, opaque); Loading libs/hwui/pipeline/skia/SkiaPipeline.h +5 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,10 @@ public: void onDestroyHardwareResources() override; bool pinImages(std::vector<SkImage*>& mutableImages) override; bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override { return false; } void unpinImages() override; void renderLayers(const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, bool opaque, const BakedOpRenderer::LightInfo& lightInfo) override; Loading Loading @@ -101,6 +105,7 @@ protected: private: TaskManager mTaskManager; std::vector<sk_sp<SkImage>> mPinnedImages; static float mLightRadius; static uint8_t mAmbientShadowAlpha; static uint8_t mSpotShadowAlpha; Loading Loading
libs/hwui/DisplayList.cpp +3 −5 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "RecordedOp.h" #include "RenderNode.h" #include "VectorDrawable.h" #include "renderthread/CanvasContext.h" namespace android { namespace uirenderer { Loading Loading @@ -105,11 +106,8 @@ void DisplayList::updateChildren(std::function<void(RenderNode*)> updateFn) { bool DisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLayer, std::function<void(RenderNode*, TreeInfo&, bool)> childFn) { TextureCache& cache = Caches::getInstance().textureCache; for (auto& bitmapResource : bitmapResources) { void* ownerToken = &info.canvasContext; info.prepareTextures = cache.prefetchAndMarkInUse(ownerToken, bitmapResource.get()); } info.prepareTextures = info.canvasContext.pinImages(bitmapResources); for (auto&& op : children) { RenderNode* childNode = op->renderNode; info.damageAccumulator->pushTransform(&op->localMatrix); Loading
libs/hwui/pipeline/skia/SkiaDisplayList.cpp +9 −44 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ #include "VectorDrawable.h" #include <SkImagePriv.h> #include <SkMutex.h> namespace android { namespace uirenderer { Loading @@ -40,7 +40,7 @@ void SkiaDisplayList::syncContents() { } bool SkiaDisplayList::reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context) { reset(context ? context->getGrContext() : nullptr, SkRect::MakeEmpty()); reset(SkRect::MakeEmpty()); node->attachAvailableList(this); return true; } Loading @@ -53,9 +53,12 @@ void SkiaDisplayList::updateChildren(std::function<void(RenderNode*)> updateFn) bool SkiaDisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLayer, std::function<void(RenderNode*, TreeInfo&, bool)> childFn) { // force all mutable images to be pinned in the GPU cache for the duration // of this frame pinImages(info.canvasContext.getGrContext()); // If the prepare tree is triggered by the UI thread then we must force all // mutable images to be pinned in the GPU cache until the next UI thread // draw if (info.mode == TreeInfo::MODE_FULL) { info.prepareTextures = info.canvasContext.pinImages(mMutableImages); } for (auto& child : mChildNodes) { RenderNode* childNode = child.getRenderNode(); Loading @@ -78,45 +81,7 @@ bool SkiaDisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLa return isDirty; } static std::vector<sk_sp<SkImage>> gPinnedImages; static SkBaseMutex gLock; void SkiaDisplayList::pinImages(GrContext* context) { if (mPinnedImages) return; for (SkImage* image : mMutableImages) { SkImage_pinAsTexture(image, context); } mPinnedImages = true; } void SkiaDisplayList::unpinImages(GrContext* context) { if (!mPinnedImages) return; if (context) { for (SkImage* image : mMutableImages) { SkImage_unpinAsTexture(image, context); } } else { gLock.acquire(); for (SkImage* image : mMutableImages) { gPinnedImages.emplace_back(sk_ref_sp(image)); } gLock.release(); } mPinnedImages = false; } void SkiaDisplayList::cleanupImages(GrContext* context) { gLock.acquire(); for (auto& image : gPinnedImages) { SkImage_unpinAsTexture(image.get(), context); } gPinnedImages.clear(); gLock.release(); } void SkiaDisplayList::reset(GrContext* context, SkRect bounds) { unpinImages(context); SkASSERT(!mPinnedImages); void SkiaDisplayList::reset(SkRect bounds) { mIsProjectionReceiver = false; mDrawable->reset(bounds); Loading
libs/hwui/pipeline/skia/SkiaDisplayList.h +1 −19 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ public: * constructed with the provided bounds. The reuse avoids any overhead * associated with destroying the SkLiteDL as well as the deques and vectors. */ void reset(GrContext* context, SkRect bounds); void reset(SkRect bounds); /** * Use the linear allocator to create any SkDrawables needed by the display Loading Loading @@ -118,21 +118,6 @@ public: */ void updateChildren(std::function<void(RenderNode*)> updateFn) override; /** * Pin/Unpin any mutable images to the GPU cache. A pinned images is * guaranteed to be remain in the cache until it has been unpinned which * we leverage to avoid making a CPU copy of the pixels. */ void pinImages(GrContext* context); void unpinImages(GrContext* context); /** * If a SkiaDisplayList is deleted on the UI thread we cache a list of any * images that need unpinned from the GPU cache and call this function on * a subsequent frame to perform that cleanup. */ static void cleanupImages(GrContext* context); /** * We use std::deque here because (1) we need to iterate through these * elements and (2) mDrawable holds pointers to the elements, so they cannot Loading @@ -145,9 +130,6 @@ public: sk_sp<SkLiteDL> mDrawable; bool mIsProjectionReceiver = false; private: bool mPinnedImages = false; }; }; // namespace skiapipeline Loading
libs/hwui/pipeline/skia/SkiaPipeline.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -46,6 +46,22 @@ void SkiaPipeline::onDestroyHardwareResources() { // which will flush temporary resources over time. } bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) { for (SkImage* image : mutableImages) { mPinnedImages.emplace_back(sk_ref_sp(image)); // TODO: return false if texture creation fails (see b/32691999) SkImage_pinAsTexture(image, mRenderThread.getGrContext()); } return true; } void SkiaPipeline::unpinImages() { for (auto& image : mPinnedImages) { SkImage_unpinAsTexture(image.get(), mRenderThread.getGrContext()); } mPinnedImages.clear(); } void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, bool opaque, const BakedOpRenderer::LightInfo& lightInfo) { Loading Loading @@ -154,9 +170,6 @@ void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& cli const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds, sk_sp<SkSurface> surface) { // unpin all mutable images that were attached to nodes deleted while on the UI thread SkiaDisplayList::cleanupImages(surface->getCanvas()->getGrContext()); // draw all layers up front renderLayersImpl(layers, opaque); Loading
libs/hwui/pipeline/skia/SkiaPipeline.h +5 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,10 @@ public: void onDestroyHardwareResources() override; bool pinImages(std::vector<SkImage*>& mutableImages) override; bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override { return false; } void unpinImages() override; void renderLayers(const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, bool opaque, const BakedOpRenderer::LightInfo& lightInfo) override; Loading Loading @@ -101,6 +105,7 @@ protected: private: TaskManager mTaskManager; std::vector<sk_sp<SkImage>> mPinnedImages; static float mLightRadius; static uint8_t mAmbientShadowAlpha; static uint8_t mSpotShadowAlpha; Loading