Delete Gr testing contexts in reverse order

This fixes issues where we create a child shared context and expect work
on that to finish before deleting the parent.

Bug: skia:
Change-Id: Iab41b22026cd4b9ec1b9d74e7841ee5051df6036
Reviewed-on: https://skia-review.googlesource.com/94962
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/tools/gpu/GrContextFactory.cpp b/tools/gpu/GrContextFactory.cpp
index 109d028..c6cceb4 100644
--- a/tools/gpu/GrContextFactory.cpp
+++ b/tools/gpu/GrContextFactory.cpp
@@ -51,7 +51,12 @@
 }
 
 void GrContextFactory::destroyContexts() {
-    for (Context& context : fContexts) {
+    // We must delete the test contexts in reverse order so that any child context is finished and
+    // deleted before a parent context. This relies on the fact that when we make a new context we
+    // append it to the end of fContexts array.
+    // TODO: Look into keeping a dependency dag for contexts and deletion order
+    for (int i = fContexts.count() - 1; i >= 0; --i) {
+        Context& context = fContexts[i];
         SkScopeExit restore(nullptr);
         if (context.fTestContext) {
             restore = context.fTestContext->makeCurrentAndAutoRestore();
@@ -67,7 +72,12 @@
 }
 
 void GrContextFactory::abandonContexts() {
-    for (Context& context : fContexts) {
+    // We must abandon the test contexts in reverse order so that any child context is finished and
+    // abandoned before a parent context. This relies on the fact that when we make a new context we
+    // append it to the end of fContexts array.
+    // TODO: Look into keeping a dependency dag for contexts and deletion order
+    for (int i = fContexts.count() - 1; i >= 0; --i) {
+        Context& context = fContexts[i];
         if (!context.fAbandoned) {
             if (context.fTestContext) {
                 auto restore = context.fTestContext->makeCurrentAndAutoRestore();
@@ -82,7 +92,12 @@
 }
 
 void GrContextFactory::releaseResourcesAndAbandonContexts() {
-    for (Context& context : fContexts) {
+    // We must abandon the test contexts in reverse order so that any child context is finished and
+    // abandoned before a parent context. This relies on the fact that when we make a new context we
+    // append it to the end of fContexts array.
+    // TODO: Look into keeping a dependency dag for contexts and deletion order
+    for (int i = fContexts.count() - 1; i >= 0; --i) {
+        Context& context = fContexts[i];
         SkScopeExit restore(nullptr);
         if (!context.fAbandoned) {
             if (context.fTestContext) {
@@ -270,6 +285,8 @@
         }
     }
 
+    // We must always add new contexts by pushing to the back so that when we delete them we delete
+    // them in reverse order in which they were made.
     Context& context = fContexts.push_back();
     context.fBackend = backend;
     context.fTestContext = testCtx.release();