Make SkGLContext lifetime more well-defined

Remove refcounting from SkGLContext.

SkGLContext is expected to behave like GrContextFactory would own
it, as implied by the GrContextFactory function.

If it is refcounted, this does not hold.

Also other use sites, such as in SkOSWindow_win (command buffer gl
object), confirm the behavior. The object is explicitly owned and
destroyed, not shared.

Also fixes potential crashes from using GL context of an abandoned
context.

Also fixes potential crashes in DM/nanobench, if the GrContext lives
longer than GLContext through internal refing of GrContext.

Moves the non-trivial implementations from GrContextFactory.h to
.cpp, just for consistency sake.

Changes pathops_unittest.gyp. The pathops_unittest uses
GrContextFactory, but did not link to its implementation. The reason
they worked was that the implementation used (constructors, destructors)
happened to be in the .h file.

This works towards being able to use command buffer and NVPR from
the SampleApp.

BUG=skia:2992
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1511773005

Committed: https://skia.googlesource.com/skia/+/830e012187f951d49d7e46e196ac8d1e653a25da

Review URL: https://codereview.chromium.org/1511773005
diff --git a/src/gpu/GrContextFactory.cpp b/src/gpu/GrContextFactory.cpp
index 4814e78..b7e4825 100755
--- a/src/gpu/GrContextFactory.cpp
+++ b/src/gpu/GrContextFactory.cpp
@@ -23,16 +23,56 @@
 #include "gl/GrGLGpu.h"
 #include "GrCaps.h"
 
-GrContextFactory::ContextInfo* GrContextFactory::getContextInfo(GLContextType type,
-                                                                GLContextOptions options) {
+GrContextFactory::GrContextFactory() { }
+
+GrContextFactory::GrContextFactory(const GrContextOptions& opts)
+    : fGlobalOptions(opts) {
+}
+
+GrContextFactory::~GrContextFactory() {
+    this->destroyContexts();
+}
+
+void GrContextFactory::destroyContexts() {
+    for (Context& context : fContexts) {
+        if (context.fGLContext) {
+            context.fGLContext->makeCurrent();
+        }
+        if (!context.fGrContext->unique()) {
+            context.fGrContext->abandonContext();
+        }
+        context.fGrContext->unref();
+        delete(context.fGLContext);
+    }
+    fContexts.reset();
+}
+
+void GrContextFactory::abandonContexts() {
+    for (Context& context : fContexts) {
+        if (context.fGLContext) {
+            context.fGLContext->makeCurrent();
+            context.fGLContext->testAbandon();
+            delete(context.fGLContext);
+            context.fGLContext = nullptr;
+        }
+        context.fGrContext->abandonContext();
+    }
+}
+
+GrContextFactory::ContextInfo GrContextFactory::getContextInfo(GLContextType type,
+                                                               GLContextOptions options) {
     for (int i = 0; i < fContexts.count(); ++i) {
-        if (fContexts[i]->fType == type &&
-            fContexts[i]->fOptions == options) {
-            fContexts[i]->fGLContext->makeCurrent();
-            return fContexts[i];
+        Context& context = fContexts[i];
+        if (!context.fGLContext) {
+            continue;
+        }
+        if (context.fType == type &&
+            context.fOptions == options) {
+            context.fGLContext->makeCurrent();
+            return ContextInfo(context.fGrContext, context.fGLContext);
         }
     }
-    SkAutoTUnref<SkGLContext> glCtx;
+    SkAutoTDelete<SkGLContext> glCtx;
     SkAutoTUnref<GrContext> grCtx;
     switch (type) {
         case kNative_GLContextType:
@@ -72,7 +112,7 @@
             break;
     }
     if (nullptr == glCtx.get()) {
-        return nullptr;
+        return ContextInfo();
     }
 
     SkASSERT(glCtx->isValid());
@@ -82,7 +122,7 @@
     if (!(kEnableNVPR_GLContextOptions & options)) {
         glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
         if (!glInterface) {
-            return nullptr;
+            return ContextInfo();
         }
     }
 
@@ -94,18 +134,18 @@
     grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx, fGlobalOptions));
 #endif
     if (!grCtx.get()) {
-        return nullptr;
+        return ContextInfo();
     }
     if (kEnableNVPR_GLContextOptions & options) {
         if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) {
-            return nullptr;
+            return ContextInfo();
         }
     }
 
-    ContextInfo* ctx = fContexts.emplace_back(new ContextInfo);
-    ctx->fGLContext = SkRef(glCtx.get());
-    ctx->fGrContext = SkRef(grCtx.get());
-    ctx->fType = type;
-    ctx->fOptions = options;
-    return ctx;
+    Context& context = fContexts.push_back();
+    context.fGLContext = glCtx.detach();
+    context.fGrContext = SkRef(grCtx.get());
+    context.fType = type;
+    context.fOptions = options;
+    return ContextInfo(context.fGrContext, context.fGLContext);
 }