Add resource tracking output and command buffer recycling

BUG=skia:5042
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2115993002

Review-Url: https://codereview.chromium.org/2115993002
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index 4f6c792..19a2f7d 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -221,8 +221,16 @@
     *outPool = fUniformDescPool;
 }
 
-GrVkPrimaryCommandBuffer* GrVkResourceProvider::createPrimaryCommandBuffer() {
-    GrVkPrimaryCommandBuffer* cmdBuffer = GrVkPrimaryCommandBuffer::Create(fGpu, fGpu->cmdPool());
+GrVkPrimaryCommandBuffer* GrVkResourceProvider::findOrCreatePrimaryCommandBuffer() {
+    GrVkPrimaryCommandBuffer* cmdBuffer = nullptr;
+    int count = fAvailableCommandBuffers.count();
+    if (count > 0) {
+        cmdBuffer = fAvailableCommandBuffers[count -1];
+        SkASSERT(cmdBuffer->finished(fGpu));
+        fAvailableCommandBuffers.removeShuffle(count - 1);
+    } else {
+        cmdBuffer = GrVkPrimaryCommandBuffer::Create(fGpu, fGpu->cmdPool());
+    }
     fActiveCommandBuffers.push_back(cmdBuffer);
     cmdBuffer->ref();
     return cmdBuffer;
@@ -231,20 +239,53 @@
 void GrVkResourceProvider::checkCommandBuffers() {
     for (int i = fActiveCommandBuffers.count()-1; i >= 0; --i) {
         if (fActiveCommandBuffers[i]->finished(fGpu)) {
-            fActiveCommandBuffers[i]->unref(fGpu);
+            GrVkPrimaryCommandBuffer* cmdBuffer = fActiveCommandBuffers[i];
+            cmdBuffer->reset(fGpu);
+            fAvailableCommandBuffers.push_back(cmdBuffer);
             fActiveCommandBuffers.removeShuffle(i);
         }
     }
 }
 
+GrVkSecondaryCommandBuffer* GrVkResourceProvider::findOrCreateSecondaryCommandBuffer() {
+    GrVkSecondaryCommandBuffer* cmdBuffer = nullptr;
+    int count = fAvailableSecondaryCommandBuffers.count();
+    if (count > 0) {
+        cmdBuffer = fAvailableSecondaryCommandBuffers[count-1];
+        fAvailableSecondaryCommandBuffers.removeShuffle(count - 1);
+    } else {
+        cmdBuffer = GrVkSecondaryCommandBuffer::Create(fGpu, fGpu->cmdPool());
+    }
+    return cmdBuffer;
+}
+
+void GrVkResourceProvider::recycleSecondaryCommandBuffer(GrVkSecondaryCommandBuffer* cb) {
+    cb->reset(fGpu);
+    fAvailableSecondaryCommandBuffers.push_back(cb);
+}
+
 void GrVkResourceProvider::destroyResources() {
-    // release our current command buffers
+    // release our active command buffers
     for (int i = 0; i < fActiveCommandBuffers.count(); ++i) {
         SkASSERT(fActiveCommandBuffers[i]->finished(fGpu));
         SkASSERT(fActiveCommandBuffers[i]->unique());
         fActiveCommandBuffers[i]->unref(fGpu);
     }
     fActiveCommandBuffers.reset();
+    // release our available command buffers
+    for (int i = 0; i < fAvailableCommandBuffers.count(); ++i) {
+        SkASSERT(fAvailableCommandBuffers[i]->finished(fGpu));
+        SkASSERT(fAvailableCommandBuffers[i]->unique());
+        fAvailableCommandBuffers[i]->unref(fGpu);
+    }
+    fAvailableCommandBuffers.reset();
+
+    // release our available secondary command buffers
+    for (int i = 0; i < fAvailableSecondaryCommandBuffers.count(); ++i) {
+        SkASSERT(fAvailableSecondaryCommandBuffers[i]->unique());
+        fAvailableSecondaryCommandBuffers[i]->unref(fGpu);
+    }
+    fAvailableSecondaryCommandBuffers.reset();
 
     // loop over all render pass sets to make sure we destroy all the internal VkRenderPasses
     for (int i = 0; i < fRenderPassArray.count(); ++i) {
@@ -273,17 +314,38 @@
     fUniformDescPool->unref(fGpu);
 
 #ifdef SK_TRACE_VK_RESOURCES
+    if (GrVkResource::fTrace.count()) {
+        SkTDynamicHash<GrVkResource, uint32_t>::Iter iter(&GrVkResource::fTrace);
+        for (; !iter.done(); ++iter) {
+            (*iter).dumpInfo();
+        }
+    }
     SkASSERT(0 == GrVkResource::fTrace.count());
 #endif
 }
 
 void GrVkResourceProvider::abandonResources() {
-    // release our current command buffers
+    // release our active command buffers
     for (int i = 0; i < fActiveCommandBuffers.count(); ++i) {
         SkASSERT(fActiveCommandBuffers[i]->finished(fGpu));
+        SkASSERT(fActiveCommandBuffers[i]->unique());
         fActiveCommandBuffers[i]->unrefAndAbandon();
     }
     fActiveCommandBuffers.reset();
+    // release our available command buffers
+    for (int i = 0; i < fAvailableCommandBuffers.count(); ++i) {
+        SkASSERT(fAvailableCommandBuffers[i]->finished(fGpu));
+        SkASSERT(fAvailableCommandBuffers[i]->unique());
+        fAvailableCommandBuffers[i]->unrefAndAbandon();
+    }
+    fAvailableCommandBuffers.reset();
+
+    // release our available secondary command buffers
+    for (int i = 0; i < fAvailableSecondaryCommandBuffers.count(); ++i) {
+        SkASSERT(fAvailableSecondaryCommandBuffers[i]->unique());
+        fAvailableSecondaryCommandBuffers[i]->unrefAndAbandon();
+    }
+    fAvailableSecondaryCommandBuffers.reset();
 
     // loop over all render pass sets to make sure we destroy all the internal VkRenderPasses
     for (int i = 0; i < fRenderPassArray.count(); ++i) {
@@ -306,6 +368,12 @@
     fUniformDescPool->unrefAndAbandon();
 
 #ifdef SK_TRACE_VK_RESOURCES
+    if (GrVkResource::fTrace.count()) {
+        SkTDynamicHash<GrVkResource, uint32_t>::Iter iter(&GrVkResource::fTrace);
+        for (; !iter.done(); ++iter) {
+            (*iter).dumpInfo();
+        }
+    }
     SkASSERT(0 == GrVkResource::fTrace.count());
 #endif
 }