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);