Reland "Write pixels goes through GrRenderTask system."

This reverts commit 1eea1ea8c16252a6eed9d02eb913925aa2989ae5.

Reason for revert: fixed implicit copy cons

Original change's description:
> Revert "Write pixels goes through GrRenderTask system."
>
> This reverts commit 27efe6cb1ef8c75ed0bcafb3ffd5065ddc061fd6.
>
> Reason for revert: wasm compile
>
> Original change's description:
> > Write pixels goes through GrRenderTask system.
> >
> > The specific motivation is to remove some uses of GrResourceProvider
> > making textures with data in lazy callbacks. But it's a general
> > improvement that could allow use cases like writePixels in DDL
> > recordings.
> >
> > Bug: skia:11204
> >
> > Change-Id: Ic55c3f75976a1d3a7d93981e21be75a3053ef069
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/356845
> > Reviewed-by: Adlai Holler <adlai@google.com>
> > Commit-Queue: Brian Salomon <bsalomon@google.com>
>
> TBR=bsalomon@google.com,adlai@google.com
>
> Change-Id: I116caf1e4dd9015270b9d4f810bd26e0e30a6497
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:11204
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/359559
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>

TBR=bsalomon@google.com,adlai@google.com

# Not skipping CQ checks because this is a reland.

Bug: skia:11204
Change-Id: I7d8f92415995f03301ffb147500d972e6bd17640
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/359561
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrWritePixelsRenderTask.cpp b/src/gpu/GrWritePixelsRenderTask.cpp
new file mode 100644
index 0000000..1d01bbd
--- /dev/null
+++ b/src/gpu/GrWritePixelsRenderTask.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/gpu/GrWritePixelsRenderTask.h"
+
+#include "src/gpu/GrGpu.h"
+#include "src/gpu/GrOpFlushState.h"
+#include "src/gpu/GrResourceAllocator.h"
+    //
+
+sk_sp<GrRenderTask> GrWritePixelsTask::Make(GrDrawingManager* dm,
+                                            sk_sp<GrSurfaceProxy> dst,
+                                            SkIRect rect,
+                                            GrColorType srcColorType,
+                                            GrColorType dstColorType,
+                                            const GrMipLevel texels[],
+                                            int levelCount,
+                                            sk_sp<SkData> pixelStorage) {
+    return sk_sp<GrRenderTask>(new GrWritePixelsTask(dm,
+                                                     std::move(dst),
+                                                     rect,
+                                                     srcColorType,
+                                                     dstColorType,
+                                                     texels,
+                                                     levelCount,
+                                                     std::move(pixelStorage)));
+}
+
+GrWritePixelsTask::GrWritePixelsTask(GrDrawingManager* dm,
+                                     sk_sp<GrSurfaceProxy> dst,
+                                     SkIRect rect,
+                                     GrColorType srcColorType,
+                                     GrColorType dstColorType,
+                                     const GrMipLevel texels[],
+                                     int levelCount,
+                                     sk_sp<SkData> pixelStorage)
+        : fRect(rect)
+        , fSrcColorType(srcColorType)
+        , fDstColorType(dstColorType)
+        , fStorage(std::move(pixelStorage)) {
+    SkASSERT(fStorage);
+    this->addTarget(dm, std::move(dst));
+    fLevels.reset(levelCount);
+    std::copy_n(texels, levelCount, fLevels.get());
+}
+
+void GrWritePixelsTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
+    alloc->addInterval(this->target(0), alloc->curOp(), alloc->curOp(),
+                       GrResourceAllocator::ActualUse::kYes);
+    alloc->incOps();
+}
+
+GrRenderTask::ExpectedOutcome GrWritePixelsTask::onMakeClosed(const GrCaps&,
+                                                              SkIRect* targetUpdateBounds) {
+    *targetUpdateBounds = fRect;
+    return ExpectedOutcome::kTargetDirty;
+}
+
+bool GrWritePixelsTask::onExecute(GrOpFlushState* flushState) {
+    GrSurfaceProxy* dstProxy = this->target(0);
+    if (!dstProxy->isInstantiated()) {
+        return false;
+    }
+    GrSurface* dstSurface = dstProxy->peekSurface();
+    return flushState->gpu()->writePixels(dstSurface,
+                                          fRect.fLeft,
+                                          fRect.fTop,
+                                          fRect.width(),
+                                          fRect.height(),
+                                          fDstColorType,
+                                          fSrcColorType,
+                                          fLevels.get(),
+                                          fLevels.count());
+}