Redux merging adjacent ops tasks

The prior CL 358522 was reverted due to relying on
moving SkArenaAlloc which does not work.

This folds in cleanup CL 358156 also.

Bug: skia:10877
Change-Id: I0a29848f0fccb7d6a8f18d307b9f6b6a0311c83a
Cq-Include-Trybots: luci.skia.skia.primary:Build-Debian10-EMCC-wasm-Release-WasmGMTests
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/358527
Commit-Queue: Adlai Holler <adlai@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 69f93e4..62033ae 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -447,6 +447,22 @@
     // TODO: Handle case where proposed order would blow our memory budget.
     // Such cases are currently pathological, so we could just return here and keep current order.
     reorder_array_by_llist(llist, &fDAG);
+
+    int newCount = 0;
+    for (int i = 0; i < fDAG.count(); i++) {
+        sk_sp<GrRenderTask>& task = fDAG[i];
+        if (auto opsTask = task->asOpsTask()) {
+            size_t remaining = fDAG.size() - i - 1;
+            SkSpan<sk_sp<GrRenderTask>> nextTasks{fDAG.end() - remaining, remaining};
+            int removeCount = opsTask->mergeFrom(nextTasks);
+            for (const auto& removed : nextTasks.first(removeCount)) {
+                removed->disown(this);
+            }
+            i += removeCount;
+        }
+        fDAG[newCount++] = std::move(task);
+    }
+    fDAG.resize_back(newCount);
 }
 
 void GrDrawingManager::closeAllTasks() {