Add flag to map buffer flags in GrCaps to indicate whether mapping a
GrGpuBuffer for reading is synchronous or not.

Update transfer-from test to not call GrGpu->finishFlush() when maps
are synchronous.

Bug: skia:8962
Change-Id: I5eb003081725e5199157473faf7f916a65408dc8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/208509
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index c4e24f0..f2589f5 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -175,6 +175,12 @@
             str.append(" full");
         }
         SkDEBUGCODE(flags &= ~GrCaps::kSubset_MapFlag);
+        if (GrCaps::kAsyncRead_MapFlag & flags) {
+            str.append(" async_read");
+        } else {
+            str.append(" sync_read");
+        }
+        SkDEBUGCODE(flags &= ~GrCaps::kAsyncRead_MapFlag);
     }
     SkASSERT(0 == flags); // Make sure we handled all the flags.
     return str;
diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h
index 2977ccd..8ae8bba 100644
--- a/src/gpu/GrCaps.h
+++ b/src/gpu/GrCaps.h
@@ -114,11 +114,13 @@
      * textures allows partial mappings or full mappings.
      */
     enum MapFlags {
-        kNone_MapFlags   = 0x0,       //<! Cannot map the resource.
+        kNone_MapFlags      = 0x0,   //<! Cannot map the resource.
 
-        kCanMap_MapFlag  = 0x1,       //<! The resource can be mapped. Must be set for any of
-                                      //   the other flags to have meaning.
-        kSubset_MapFlag  = 0x2,       //<! The resource can be partially mapped.
+        kCanMap_MapFlag     = 0x1,   //<! The resource can be mapped. Must be set for any of
+                                     //   the other flags to have meaning.
+        kSubset_MapFlag     = 0x2,   //<! The resource can be partially mapped.
+        kAsyncRead_MapFlag  = 0x4,   //<! Are maps for reading asynchronous WRT GrGpuCommandBuffers
+                                     //   submitted to GrGpu.
     };
 
     uint32_t mapBufferFlags() const { return fMapBufferFlags; }
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index a207938..9df7afe 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -40,8 +40,6 @@
     fCrossContextTextureSupport = true;
     fHalfFloatVertexAttributeSupport = true;
 
-    fMapBufferFlags = kNone_MapFlags; //TODO: figure this out
-    fBufferMapThreshold = SK_MaxS32;  //TODO: figure this out
     fTransferBufferSupport = true;
 
     fMaxRenderTargetSize = 4096; // minimum required by spec
@@ -515,7 +513,7 @@
     // from the get go. There is no hard data to suggest this is faster or slower.
     fBufferMapThreshold = 0;
 
-    fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
+    fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag | kAsyncRead_MapFlag;
 
     fOversizedStencilSupport = true;
 
diff --git a/tests/TransferPixelsTest.cpp b/tests/TransferPixelsTest.cpp
index 771f9c7..a9f43d5 100644
--- a/tests/TransferPixelsTest.cpp
+++ b/tests/TransferPixelsTest.cpp
@@ -272,9 +272,10 @@
         }
         ++expectedTransferCnt;
 
-        // TODO(bsalomon): caps to know if the map() is synchronous and skip the flush if so.
-        gpu->finishFlush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
-                         kSyncCpu_GrFlushFlag, 0, nullptr, nullptr, nullptr);
+        if (context->priv().caps()->mapBufferFlags() & GrCaps::kAsyncRead_MapFlag) {
+            gpu->finishFlush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
+                             kSyncCpu_GrFlushFlag, 0, nullptr, nullptr, nullptr);
+        }
 
         const auto* map = reinterpret_cast<const GrColor*>(buffer->map());
         REPORTER_ASSERT(reporter, map);
@@ -301,9 +302,10 @@
         }
         ++expectedTransferCnt;
 
-        // TODO(bsalomon): caps to know if the map() is synchronous and skip the flush if so.
-        gpu->finishFlush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
-                         kSyncCpu_GrFlushFlag, 0, nullptr, nullptr, nullptr);
+        if (context->priv().caps()->mapBufferFlags() & GrCaps::kAsyncRead_MapFlag) {
+            gpu->finishFlush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
+                             kSyncCpu_GrFlushFlag, 0, nullptr, nullptr, nullptr);
+        }
 
         map = reinterpret_cast<const GrColor*>(buffer->map());
         REPORTER_ASSERT(reporter, map);