Move op memory storage to GrContext (take 2)

TBR=bsalomon@google.com

Change-Id: I4a448694d4114d83cd3a720cfc8bd37de51733d1
Reviewed-on: https://skia-review.googlesource.com/135707
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index eb39079..1ea3ddf 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -8,6 +8,7 @@
 #include "GrAtlasTextOp.h"
 
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrMemoryPool.h"
 #include "GrOpFlushState.h"
 #include "GrResourceProvider.h"
@@ -27,7 +28,9 @@
                                                          GrMaskFormat maskFormat,
                                                          int glyphCount,
                                                          bool needsTransform) {
-        std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(std::move(paint)));
+        GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+        std::unique_ptr<GrAtlasTextOp> op = pool->allocate<GrAtlasTextOp>(std::move(paint));
 
         switch (maskFormat) {
             case kA8_GrMaskFormat:
@@ -57,7 +60,9 @@
                                             const SkSurfaceProps& props,
                                             bool isAntiAliased,
                                             bool useLCD) {
-        std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(std::move(paint)));
+        GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+        std::unique_ptr<GrAtlasTextOp> op = pool->allocate<GrAtlasTextOp>(std::move(paint));
 
         bool isBGR = SkPixelGeometryIsBGR(props.pixelGeometry());
         bool isLCD = useLCD && SkPixelGeometryIsH(props.pixelGeometry());
diff --git a/src/gpu/ops/GrClearOp.cpp b/src/gpu/ops/GrClearOp.cpp
index 70fc160..612ff20 100644
--- a/src/gpu/ops/GrClearOp.cpp
+++ b/src/gpu/ops/GrClearOp.cpp
@@ -21,7 +21,9 @@
         return nullptr;
     }
 
-    return std::unique_ptr<GrClearOp>(new GrClearOp(clip, color, dstProxy));
+    GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+    return pool->allocate<GrClearOp>(clip, color, dstProxy);
 }
 
 std::unique_ptr<GrClearOp> GrClearOp::Make(GrContext* context,
@@ -30,7 +32,9 @@
                                            bool fullScreen) {
     SkASSERT(fullScreen || !rect.isEmpty());
 
-    return std::unique_ptr<GrClearOp>(new GrClearOp(rect, color, fullScreen));
+    GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+    return pool->allocate<GrClearOp>(rect, color, fullScreen);
 }
 
 GrClearOp::GrClearOp(const GrFixedClip& clip, GrColor color, GrSurfaceProxy* proxy)
diff --git a/src/gpu/ops/GrClearStencilClipOp.cpp b/src/gpu/ops/GrClearStencilClipOp.cpp
index 9a0e75a..64985b7 100644
--- a/src/gpu/ops/GrClearStencilClipOp.cpp
+++ b/src/gpu/ops/GrClearStencilClipOp.cpp
@@ -14,7 +14,9 @@
                                                  const GrFixedClip& clip,
                                                  bool insideStencilMask,
                                                  GrRenderTargetProxy* proxy) {
-    return std::unique_ptr<GrOp>(new GrClearStencilClipOp(clip, insideStencilMask, proxy));
+    GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+    return pool->allocate<GrClearStencilClipOp>(clip, insideStencilMask, proxy);
 }
 
 void GrClearStencilClipOp::onExecute(GrOpFlushState* state) {
diff --git a/src/gpu/ops/GrCopySurfaceOp.cpp b/src/gpu/ops/GrCopySurfaceOp.cpp
index da8e910..a90579b 100644
--- a/src/gpu/ops/GrCopySurfaceOp.cpp
+++ b/src/gpu/ops/GrCopySurfaceOp.cpp
@@ -78,8 +78,9 @@
         return nullptr;
     }
 
-    return std::unique_ptr<GrOp>(new GrCopySurfaceOp(dstProxy, srcProxy,
-                                                     clippedSrcRect, clippedDstPoint));
+    GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+    return pool->allocate<GrCopySurfaceOp>(dstProxy, srcProxy, clippedSrcRect, clippedDstPoint);
 }
 
 void GrCopySurfaceOp::onExecute(GrOpFlushState* state) {
diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp
index b784b05..cafb3e5 100644
--- a/src/gpu/ops/GrDashOp.cpp
+++ b/src/gpu/ops/GrDashOp.cpp
@@ -271,8 +271,10 @@
                                           SkPaint::Cap cap,
                                           AAMode aaMode, bool fullDash,
                                           const GrUserStencilSettings* stencilSettings) {
-        return std::unique_ptr<GrDrawOp>(
-                new DashOp(std::move(paint), geometry, cap, aaMode, fullDash, stencilSettings));
+        GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+        return pool->allocate<DashOp>(std::move(paint), geometry, cap,
+                                      aaMode, fullDash, stencilSettings);
     }
 
     const char* name() const override { return "DashOp"; }
diff --git a/src/gpu/ops/GrDebugMarkerOp.cpp b/src/gpu/ops/GrDebugMarkerOp.cpp
index ed54965..712e625 100644
--- a/src/gpu/ops/GrDebugMarkerOp.cpp
+++ b/src/gpu/ops/GrDebugMarkerOp.cpp
@@ -17,7 +17,9 @@
 std::unique_ptr<GrOp> GrDebugMarkerOp::Make(GrContext* context,
                                             GrRenderTargetProxy* proxy,
                                             const SkString& str) {
-    return std::unique_ptr<GrOp>(new GrDebugMarkerOp(proxy, str));
+    GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+    return pool->allocate<GrDebugMarkerOp>(proxy, str);
 }
 
 void GrDebugMarkerOp::onExecute(GrOpFlushState* state) {
diff --git a/src/gpu/ops/GrDrawPathOp.cpp b/src/gpu/ops/GrDrawPathOp.cpp
index a5a98f2..a8081fc 100644
--- a/src/gpu/ops/GrDrawPathOp.cpp
+++ b/src/gpu/ops/GrDrawPathOp.cpp
@@ -69,8 +69,9 @@
                                              GrPaint&& paint,
                                              GrAAType aaType,
                                              GrPath* path) {
-    return std::unique_ptr<GrDrawOp>(
-                new GrDrawPathOp(viewMatrix, std::move(paint), aaType, path));
+    GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+    return pool->allocate<GrDrawPathOp>(viewMatrix, std::move(paint), aaType, path);
 }
 
 void GrDrawPathOp::onExecute(GrOpFlushState* state) {
diff --git a/src/gpu/ops/GrOp.cpp b/src/gpu/ops/GrOp.cpp
index f020cde..cab8ca1 100644
--- a/src/gpu/ops/GrOp.cpp
+++ b/src/gpu/ops/GrOp.cpp
@@ -7,57 +7,27 @@
 
 #include "GrOp.h"
 
-#include "GrMemoryPool.h"
-#include "SkSpinlock.h"
-#include "SkTo.h"
-
-// TODO I noticed a small benefit to using a larger exclusive pool for ops. Its very small, but
-// seems to be mostly consistent.  There is a lot in flux right now, but we should really revisit
-// this.
-
-
-// We use a global pool protected by a mutex(spinlock). Chrome may use the same GrContext on
-// different threads. The GrContext is not used concurrently on different threads and there is a
-// memory barrier between accesses of a context on different threads. Also, there may be multiple
-// GrContexts and those contexts may be in use concurrently on different threads.
-namespace {
-#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
-static SkSpinlock gOpPoolSpinLock;
-#endif
-class MemoryPoolAccessor {
-public:
-
-// We know in the Android framework there is only one GrContext.
-#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
-    MemoryPoolAccessor() {}
-    ~MemoryPoolAccessor() {}
-#else
-    MemoryPoolAccessor() { gOpPoolSpinLock.acquire(); }
-    ~MemoryPoolAccessor() { gOpPoolSpinLock.release(); }
-#endif
-
-    GrMemoryPool* pool() const {
-        static GrMemoryPool gPool(16384, 16384);
-        return &gPool;
-    }
-};
-}
-
 int32_t GrOp::gCurrOpClassID = GrOp::kIllegalOpID;
 
 int32_t GrOp::gCurrOpUniqueID = GrOp::kIllegalOpID;
 
+#ifdef SK_DEBUG
 void* GrOp::operator new(size_t size) {
-    return MemoryPoolAccessor().pool()->allocate(size);
+    // All GrOp-derived class should be allocated in a GrMemoryPool
+    SkASSERT(0);
+    return ::operator new(size);
 }
 
 void GrOp::operator delete(void* target) {
-    return MemoryPoolAccessor().pool()->release(target);
+    // All GrOp-derived class should be released from their owning GrMemoryPool
+    SkASSERT(0);
+    ::operator delete(target);
 }
+#endif
 
 GrOp::GrOp(uint32_t classID)
-    : fClassID(classID)
-    , fUniqueID(kIllegalOpID) {
+        : fClassID(classID)
+        , fUniqueID(kIllegalOpID) {
     SkASSERT(classID == SkToU32(fClassID));
     SkDEBUGCODE(fBoundsFlags = kUninitialized_BoundsFlag);
 }
diff --git a/src/gpu/ops/GrOp.h b/src/gpu/ops/GrOp.h
index 5d79223..5c776fc 100644
--- a/src/gpu/ops/GrOp.h
+++ b/src/gpu/ops/GrOp.h
@@ -104,6 +104,8 @@
         return SkToBool(fBoundsFlags & kZeroArea_BoundsFlag);
     }
 
+#ifdef SK_DEBUG
+    // All GrOp-derived classes should be allocated in and deleted from a GrMemoryPool
     void* operator new(size_t size);
     void operator delete(void* target);
 
@@ -113,6 +115,7 @@
     void operator delete(void* target, void* placement) {
         ::operator delete(target, placement);
     }
+#endif
 
     /**
      * Helper for safely down-casting to a GrOp subclass
diff --git a/src/gpu/ops/GrSemaphoreOp.cpp b/src/gpu/ops/GrSemaphoreOp.cpp
index fedf6b7..9beb2a6 100644
--- a/src/gpu/ops/GrSemaphoreOp.cpp
+++ b/src/gpu/ops/GrSemaphoreOp.cpp
@@ -21,9 +21,9 @@
                                       sk_sp<GrSemaphore> semaphore,
                                       GrRenderTargetProxy* proxy,
                                       bool forceFlush) {
-        return std::unique_ptr<GrSignalSemaphoreOp>(new GrSignalSemaphoreOp(std::move(semaphore),
-                                                                            proxy,
-                                                                            forceFlush));
+        GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+        return pool->allocate<GrSignalSemaphoreOp>(std::move(semaphore), proxy, forceFlush);
     }
 
     const char* name() const override { return "SignalSemaphore"; }
@@ -51,8 +51,9 @@
     static std::unique_ptr<GrOp> Make(GrContext* context,
                                       sk_sp<GrSemaphore> semaphore,
                                       GrRenderTargetProxy* proxy) {
-        return std::unique_ptr<GrWaitSemaphoreOp>(new GrWaitSemaphoreOp(std::move(semaphore),
-                                                                        proxy));
+        GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+        return pool->allocate<GrWaitSemaphoreOp>(std::move(semaphore), proxy);
     }
 
     const char* name() const override { return "WaitSemaphore"; }
diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp
index a2ec230..f61d11d 100644
--- a/src/gpu/ops/GrShadowRRectOp.cpp
+++ b/src/gpu/ops/GrShadowRRectOp.cpp
@@ -678,12 +678,14 @@
     SkScalar scaledRadius = SkScalarAbs(radius*matrixFactor);
     SkScalar scaledInsetWidth = SkScalarAbs(insetWidth*matrixFactor);
 
-    return std::unique_ptr<GrDrawOp>(new ShadowCircularRRectOp(color, bounds,
-                                                               scaledRadius,
-                                                               rrect.isOval(),
-                                                               blurWidth,
-                                                               scaledInsetWidth,
-                                                               blurClamp));
+    GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+    return pool->allocate<ShadowCircularRRectOp>(color, bounds,
+                                                 scaledRadius,
+                                                 rrect.isOval(),
+                                                 blurWidth,
+                                                 scaledInsetWidth,
+                                                 blurClamp);
 }
 }
 
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
index b63728f..e5229a7 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
@@ -174,19 +174,22 @@
 std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrContext* context,
                                                                   GrPaint&& paint,
                                                                   OpArgs... opArgs) {
+    GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
     MakeArgs makeArgs;
     makeArgs.fSRGBFlags = GrPipeline::SRGBFlagsFromPaint(paint);
     GrColor color = paint.getColor();
 
     if (paint.isTrivial()) {
         makeArgs.fProcessorSet = nullptr;
-        return std::unique_ptr<GrDrawOp>(new Op(makeArgs, color, std::forward<OpArgs>(opArgs)...));
+        return pool->allocate<Op>(makeArgs, color, std::forward<OpArgs>(opArgs)...);
     } else {
-        char* mem = (char*)GrOp::operator new(sizeof(Op) + sizeof(GrProcessorSet));
+        char* mem = (char*) pool->allocate(sizeof(Op) + sizeof(GrProcessorSet));
         char* setMem = mem + sizeof(Op);
         makeArgs.fProcessorSet = new (setMem) GrProcessorSet(std::move(paint));
-        return std::unique_ptr<GrDrawOp>(
-                new (mem) Op(makeArgs, color, std::forward<OpArgs>(opArgs)...));
+
+        return std::unique_ptr<GrDrawOp>(new (mem) Op(makeArgs, color,
+                                                      std::forward<OpArgs>(opArgs)...));
     }
 }
 
diff --git a/src/gpu/ops/GrStencilPathOp.cpp b/src/gpu/ops/GrStencilPathOp.cpp
index 5b712cf..25dbf31 100644
--- a/src/gpu/ops/GrStencilPathOp.cpp
+++ b/src/gpu/ops/GrStencilPathOp.cpp
@@ -21,8 +21,10 @@
                                             bool hasStencilClip,
                                             const GrScissorState& scissor,
                                             const GrPath* path) {
-    return std::unique_ptr<GrOp>(new GrStencilPathOp(viewMatrix, useHWAA, fillType,
-                                                     hasStencilClip, scissor, path));
+    GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+    return pool->allocate<GrStencilPathOp>(viewMatrix, useHWAA, fillType,
+                                           hasStencilClip, scissor, path);
 }
 
 void GrStencilPathOp::onExecute(GrOpFlushState* state) {
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index 80174bc..e06d94f 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -621,9 +621,11 @@
                                           SkCanvas::SrcRectConstraint constraint,
                                           const SkMatrix& viewMatrix,
                                           sk_sp<GrColorSpaceXform> csxf) {
-        return std::unique_ptr<GrDrawOp>(new TextureOp(std::move(proxy), filter, color, srcRect,
-                                                       dstRect, aaType, constraint, viewMatrix,
-                                                       std::move(csxf)));
+        GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
+
+        return pool->allocate<TextureOp>(std::move(proxy), filter, color,
+                                         srcRect, dstRect, aaType, constraint,
+                                         viewMatrix, std::move(csxf));
     }
 
     ~TextureOp() override {