[sksg] Simplify ScopedRenderContext

ScopedRenderContext tries really hard to avoid unnecessary RenderContext
initializations.

This is most likely unneeded because

  a) the structure is quite lightweight

and

  b) all ScopedRenderContext instantiation sites imediately call setters
     which require a writable context (assuming no-op args are uncommon)

Let's get rid of that over-engineered gunk.

Bug: skia:
Change-Id: Ieedc20c63c66b4d43744359e881c20639654040c
Reviewed-on: https://skia-review.googlesource.com/146761
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/modules/sksg/include/SkSGRenderNode.h b/modules/sksg/include/SkSGRenderNode.h
index efa9934..5d9356f 100644
--- a/modules/sksg/include/SkSGRenderNode.h
+++ b/modules/sksg/include/SkSGRenderNode.h
@@ -11,7 +11,6 @@
 #include "SkSGNode.h"
 
 #include "SkColorFilter.h"
-#include "SkTLazy.h"
 
 class SkCanvas;
 class SkPaint;
@@ -63,7 +62,7 @@
             return *this;
         }
 
-        operator const RenderContext* () const { return fCtx.get(); }
+        operator const RenderContext* () const { return &fCtx; }
 
         // Add (cumulative) paint overrides to a render node sub-DAG.
         ScopedRenderContext&& modulateOpacity(float opacity);
@@ -82,11 +81,9 @@
         ScopedRenderContext(const ScopedRenderContext&)            = delete;
         ScopedRenderContext& operator=(const ScopedRenderContext&) = delete;
 
-        RenderContext* writableContext();
-
-        SkCanvas*                          fCanvas;
-        SkTCopyOnFirstWrite<RenderContext> fCtx;
-        int                                fRestoreCount;
+        SkCanvas*     fCanvas;
+        RenderContext fCtx;
+        int           fRestoreCount;
     };
 
 private:
diff --git a/modules/sksg/src/SkSGRenderNode.cpp b/modules/sksg/src/SkSGRenderNode.cpp
index bfaad0e..64d337f 100644
--- a/modules/sksg/src/SkSGRenderNode.cpp
+++ b/modules/sksg/src/SkSGRenderNode.cpp
@@ -35,7 +35,7 @@
 
 RenderNode::ScopedRenderContext::ScopedRenderContext(SkCanvas* canvas, const RenderContext* ctx)
     : fCanvas(canvas)
-    , fCtx(ctx)
+    , fCtx(ctx ? *ctx : RenderContext())
     , fRestoreCount(canvas->getSaveCount()) {}
 
 RenderNode::ScopedRenderContext::~ScopedRenderContext() {
@@ -44,43 +44,27 @@
     }
 }
 
-RenderNode::RenderContext* RenderNode::ScopedRenderContext::writableContext() {
-    // If no inherited context is present, allocate one in local storage.
-    if (!fCtx.get()) {
-        // N.B.: we have to force a copy while the default source is in scope.
-        // TODO: add SkTCopyOnWrite::init_copy() to simplify this
-        RenderContext default_ctx;
-        fCtx.init(default_ctx);
-        return fCtx.writable();
-    }
-    return fCtx.writable();
-}
-
 RenderNode::ScopedRenderContext&&
 RenderNode::ScopedRenderContext::modulateOpacity(float opacity) {
     SkASSERT(opacity >= 0 && opacity <= 1);
-    if (opacity < 1) {
-        this->writableContext()->fOpacity *= opacity;
-    }
+    fCtx.fOpacity *= opacity;
     return std::move(*this);
 }
 
 RenderNode::ScopedRenderContext&&
 RenderNode::ScopedRenderContext::modulateColorFilter(sk_sp<SkColorFilter> cf) {
-    if (cf) {
-        auto* ctx = this->writableContext();
-        ctx->fColorFilter = SkColorFilter::MakeComposeFilter(std::move(ctx->fColorFilter), cf);
-    }
+    fCtx.fColorFilter = SkColorFilter::MakeComposeFilter(std::move(fCtx.fColorFilter),
+                                                         std::move(cf));
     return std::move(*this);
 }
 
 RenderNode::ScopedRenderContext&&
 RenderNode::ScopedRenderContext::setIsolation(const SkRect& bounds, bool isolation) {
-    if (isolation && fCtx.get()) {
+    if (isolation) {
         SkPaint layer_paint;
-        if (fCtx->modulatePaint(&layer_paint)) {
+        if (fCtx.modulatePaint(&layer_paint)) {
             fCanvas->saveLayer(bounds, &layer_paint);
-            *fCtx.writable() = RenderContext();
+            fCtx = RenderContext();
         }
     }
     return std::move(*this);