Implement flush finish proc support for d3d backend.

This also adds a GPUTEST_FOR_D3D_CONTEXT macro to help with debugging
tests.

Change-Id: I72db01d148755c3bbbbb4d948d441a31dcf9482b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297717
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/d3d/GrD3DGpu.cpp b/src/gpu/d3d/GrD3DGpu.cpp
index 4c80ae7..31d0dd2 100644
--- a/src/gpu/d3d/GrD3DGpu.cpp
+++ b/src/gpu/d3d/GrD3DGpu.cpp
@@ -186,6 +186,24 @@
     fCachedOpsRenderPass.reset();
 }
 
+void GrD3DGpu::addFinishedProc(GrGpuFinishedProc finishedProc,
+                               GrGpuFinishedContext finishedContext) {
+    SkASSERT(finishedProc);
+    sk_sp<GrRefCntedCallback> finishedCallback(
+            new GrRefCntedCallback(finishedProc, finishedContext));
+    // Besides the current command list, we also add the finishedCallback to the newest outstanding
+    // command list. Our contract for calling the proc is that all previous submitted command lists
+    // have finished when we call it. However, if our current command list has no work when it is
+    // flushed it will drop its ref to the callback immediately. But the previous work may not have
+    // finished. It is safe to only add the proc to the newest outstanding commandlist cause that
+    // must finish after all previously submitted command lists.
+    OutstandingCommandList* back = (OutstandingCommandList*)fOutstandingCommandLists.back();
+    if (back) {
+        back->fCommandList->addFinishedCallback(finishedCallback);
+    }
+    fCurrentDirectCommandList->addFinishedCallback(std::move(finishedCallback));
+}
+
 void GrD3DGpu::querySampleLocations(GrRenderTarget* rt, SkTArray<SkPoint>* sampleLocations) {
     // TODO
 }