From 189e87498f666e94dc8c8201e7bac56bb09b9251 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Wed, 16 Nov 2016 16:00:17 -0500 Subject: [PATCH] Update pinImages to report when GPU resource limits are exceeded. Bug: 32691999 Test: proposed CTS test (ag/1500396) and existing UiRendering tests Change-Id: I190f888ae5499ac048569af8256fdd31d19d1285 --- libs/hwui/pipeline/skia/SkiaDisplayList.cpp | 14 +++++++++----- libs/hwui/pipeline/skia/SkiaPipeline.cpp | 8 +++++--- libs/hwui/renderthread/CanvasContext.h | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp index 4abaa90974a63..2ad7f74560d6e 100644 --- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp +++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp @@ -53,11 +53,15 @@ void SkiaDisplayList::updateChildren(std::function updateFn) bool SkiaDisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLayer, std::function childFn) { - // 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); + // If the prepare tree is triggered by the UI thread and no previous call to + // pinImages has failed then we must pin all mutable images in the GPU cache + // until the next UI thread draw. + if (info.prepareTextures && !info.canvasContext.pinImages(mMutableImages)) { + // In the event that pinning failed we prevent future pinImage calls for the + // remainder of this tree traversal and also unpin any currently pinned images + // to free up GPU resources. + info.prepareTextures = false; + info.canvasContext.unpinImages(); } for (auto& child : mChildNodes) { diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index a6612c96b8f3f..c11a2bb80ee54 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -48,9 +48,11 @@ void SkiaPipeline::onDestroyHardwareResources() { bool SkiaPipeline::pinImages(std::vector& 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()); + if (SkImage_pinAsTexture(image, mRenderThread.getGrContext())) { + mPinnedImages.emplace_back(sk_ref_sp(image)); + } else { + return false; + } } return true; } diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index c322efb183a9e..0174b86d22d56 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -84,7 +84,7 @@ public: * remain in the cache until it has been unpinned. We leverage this feature * to avoid making a CPU copy of the pixels. * - * @return true if the images have been successfully pinned to the GPU cache + * @return true if all images have been successfully pinned to the GPU cache * and false otherwise (e.g. cache limits have been exceeded). */ bool pinImages(std::vector& mutableImages) {