Some fixes for Flutter memory issues.

Now that we're using GrBuffers for uploads, we need to match the size
of the upload buffer a little better to avoid wasting memory, so this
switches to a using either a power-of-two size, or the midpoint between
two powers-of-two.

Also, the mechanism of adding the staging buffers to the current
command buffer was not being invoked when calling submit for a cross-
context texture. Switching to submitToGpu() should handle this.

Change-Id: I8e0e5ae7e4dd00b5969d5e5554e3a2bff5758e81
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/310339
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 29f76bc..39689df 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -464,9 +464,13 @@
     if (kDynamic_GrAccessPattern != accessPattern) {
         return this->gpu()->createBuffer(size, intendedType, accessPattern, data);
     }
-    // bin by pow2 with a reasonable min
+    // bin by pow2+midpoint with a reasonable min
     static const size_t MIN_SIZE = 1 << 12;
-    size_t allocSize = std::max(MIN_SIZE, GrNextSizePow2(size));
+    size_t allocSize = std::max(size, MIN_SIZE);
+    size_t ceilPow2 = GrNextSizePow2(allocSize);
+    size_t floorPow2 = ceilPow2 >> 1;
+    size_t mid = floorPow2 + (floorPow2 >> 1);
+    allocSize = (allocSize <= mid) ? mid : ceilPow2;
 
     GrScratchKey key;
     GrGpuBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key);