Free unused scratch space from idle Pools.

GrBlockAllocators will hang onto an extra scratch node unless you ask
them to reset. When a Pool is detached from its thread, we know that
we're done with whatever work we needed to do, so it's a good time to
reset any scratch space and reclaim that memory.

Change-Id: I0ff2c4fad9f51a2f3dc911730abad77c06af8d57
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330276
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/gpu/GrMemoryPool.h b/src/gpu/GrMemoryPool.h
index 662ef6a..5c612ea 100644
--- a/src/gpu/GrMemoryPool.h
+++ b/src/gpu/GrMemoryPool.h
@@ -91,6 +91,13 @@
         return offsetof(GrMemoryPool, fAllocator) + fAllocator.preallocSize();
     }
 
+    /**
+     * Frees any scratch blocks that are no longer being used.
+     */
+    void resetScratchSpace() {
+        fAllocator.resetScratchSpace();
+    }
+
 #ifdef SK_DEBUG
     void validate() const;
 #endif
diff --git a/src/sksl/SkSLMemoryPool.h b/src/sksl/SkSLMemoryPool.h
index 75bae16..f616c3b 100644
--- a/src/sksl/SkSLMemoryPool.h
+++ b/src/sksl/SkSLMemoryPool.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Google Inc.
+ * Copyright 2020 Google LLC
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
@@ -31,6 +31,7 @@
     static std::unique_ptr<MemoryPool> Make(size_t, size_t) {
         return std::make_unique<MemoryPool>();
     }
+    void resetScratchSpace() {}
     void reportLeaks() const {}
     bool isEmpty() const { return true; }
     void* allocate(size_t size) { return ::operator new(size); }
diff --git a/src/sksl/SkSLPool.cpp b/src/sksl/SkSLPool.cpp
index 31f32ec..ee8eeb5 100644
--- a/src/sksl/SkSLPool.cpp
+++ b/src/sksl/SkSLPool.cpp
@@ -89,6 +89,10 @@
 
 void Pool::Recycle(std::unique_ptr<Pool> pool) {
     if (pool) {
+        if (get_thread_local_memory_pool() == pool->fMemPool.get()) {
+            SkDEBUGFAIL("SkSL pool is being recycled while it is still attached to the thread");
+        }
+
         pool->fMemPool->reportLeaks();
         SkASSERT(pool->fMemPool->isEmpty());
     }
@@ -109,8 +113,10 @@
 }
 
 void Pool::detachFromThread() {
-    VLOG("DETACH Pool:0x%016llX\n", (uint64_t)get_thread_local_memory_pool());
-    SkASSERT(get_thread_local_memory_pool() != nullptr);
+    MemoryPool* memPool = get_thread_local_memory_pool();
+    VLOG("DETACH Pool:0x%016llX\n", (uint64_t)memPool);
+    SkASSERT(memPool == fMemPool.get());
+    memPool->resetScratchSpace();
     set_thread_local_memory_pool(nullptr);
 }