Refactor pin/unpinImages to work across pipelines.
Test: existing CTS tests still pass
Change-Id: Ib2607e9853396bad42f298829b5c5da0d210af32
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index b61eef2..c322efb 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -80,6 +80,26 @@
}
/**
+ * Pin any mutable images to the GPU cache. A pinned images is guaranteed to
+ * 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
+ * and false otherwise (e.g. cache limits have been exceeded).
+ */
+ bool pinImages(std::vector<SkImage*>& mutableImages) {
+ return mRenderPipeline->pinImages(mutableImages);
+ }
+ bool pinImages(LsaVector<sk_sp<Bitmap>>& images) {
+ return mRenderPipeline->pinImages(images);
+ }
+
+ /**
+ * Unpin any image that had be previously pinned to the GPU cache
+ */
+ void unpinImages() { mRenderPipeline->unpinImages(); }
+
+ /**
* Destroy any layers that have been attached to the provided RenderNode removing
* any state that may have been set during createOrUpdateLayer().
*/
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index e3b6dc6..4ff54a5 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -119,7 +119,7 @@
int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::Vsync)];
mRenderThread->timeLord().vsyncReceived(vsync);
bool canDraw = mContext->makeCurrent();
- Caches::getInstance().textureCache.resetMarkInUse(mContext);
+ mContext->unpinImages();
for (size_t i = 0; i < mLayers.size(); i++) {
mLayers[i]->apply();
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 52894ad..0e4000b 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -73,6 +73,9 @@
virtual TaskManager* getTaskManager() = 0;
virtual bool createOrUpdateLayer(RenderNode* node,
const DamageAccumulator& damageAccumulator) = 0;
+ virtual bool pinImages(std::vector<SkImage*>& mutableImages) = 0;
+ virtual bool pinImages(LsaVector<sk_sp<Bitmap>>& images) = 0;
+ virtual void unpinImages() = 0;
virtual ~IRenderPipeline() {}
};
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index cca0fca..afeeef8 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -31,7 +31,8 @@
namespace renderthread {
OpenGLPipeline::OpenGLPipeline(RenderThread& thread)
- : mEglManager(thread.eglManager()), mRenderThread(thread) {
+ : mEglManager(thread.eglManager())
+ , mRenderThread(thread) {
}
MakeCurrentResult OpenGLPipeline::makeCurrent() {
@@ -222,6 +223,19 @@
return transformUpdateNeeded;
}
+bool OpenGLPipeline::pinImages(LsaVector<sk_sp<Bitmap>>& images) {
+ TextureCache& cache = Caches::getInstance().textureCache;
+ bool prefetchSucceeded = true;
+ for (auto& bitmapResource : images) {
+ prefetchSucceeded &= cache.prefetchAndMarkInUse(this, bitmapResource.get());
+ }
+ return prefetchSucceeded;
+}
+
+void OpenGLPipeline::unpinImages() {
+ Caches::getInstance().textureCache.resetMarkInUse(this);
+}
+
void OpenGLPipeline::destroyLayer(RenderNode* node) {
if (OffscreenBuffer* layer = node->getLayer()) {
layer->renderState.layerPool().putOrDelete(layer);
diff --git a/libs/hwui/renderthread/OpenGLPipeline.h b/libs/hwui/renderthread/OpenGLPipeline.h
index 8722d59..6df8be4 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.h
+++ b/libs/hwui/renderthread/OpenGLPipeline.h
@@ -55,6 +55,9 @@
TaskManager* getTaskManager() override;
bool createOrUpdateLayer(RenderNode* node,
const DamageAccumulator& damageAccumulator) override;
+ bool pinImages(std::vector<SkImage*>& mutableImages) override { return false; }
+ bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override;
+ void unpinImages() override;
static void destroyLayer(RenderNode* node);
static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
static void invokeFunctor(const RenderThread& thread, Functor* functor);