Make NVPR a GL context option instead of a GL context

Make NVPR a GL context option instead of a GL context.
This may enable NVPR to be run with command buffer
interface.

No functionality change in DM or nanobench. NVPR can
only be run with normal GL APIs.

BUG=skia:2992

Committed: https://skia.googlesource.com/skia/+/eeebdb538d476c1bfc8b63a946094ca1b505ecd1

Review URL: https://codereview.chromium.org/1448883002
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index a4453f9..f1841e5 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -170,10 +170,13 @@
         uint32_t flags = this->config.useDFText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag :
                                                   0;
         SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
-        this->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(this->config.ctxType),
+        this->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(this->config.ctxType,
+                                                                       kNone_GrGLStandard,
+                                                                       this->config.ctxOptions),
                                                          SkSurface::kNo_Budgeted, info,
                                                          this->config.samples, &props));
-        this->gl = gGrFactory->getContextInfo(this->config.ctxType)->fGLContext;
+        this->gl = gGrFactory->getContextInfo(this->config.ctxType, kNone_GrGLStandard,
+                                              this->config.ctxOptions)->fGLContext;
         if (!this->surface.get()) {
             return false;
         }
@@ -385,11 +388,12 @@
 
 #if SK_SUPPORT_GPU
 static bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextType ctxType,
+                                  GrContextFactory::GLContextOptions ctxOptions,
                                   int sampleCnt) {
     if (!is_cpu_config_allowed(name)) {
         return false;
     }
-    if (const GrContext* ctx = gGrFactory->get(ctxType)) {
+    if (const GrContext* ctx = gGrFactory->get(ctxType, kNone_GrGLStandard, ctxOptions)) {
         return sampleCnt <= ctx->caps()->maxSampleCount();
     }
     return false;
@@ -398,17 +402,20 @@
 
 #if SK_SUPPORT_GPU
 #define kBogusGLContextType GrContextFactory::kNative_GLContextType
+#define kBogusGLContextOptions GrContextFactory::kNone_GLContextOptions
 #else
 #define kBogusGLContextType 0
+#define kBogusGLContextOptions 0
 #endif
 
 // Append all configs that are enabled and supported.
 static void create_configs(SkTDArray<Config>* configs) {
-    #define CPU_CONFIG(name, backend, color, alpha)                       \
-        if (is_cpu_config_allowed(#name)) {                               \
-            Config config = { #name, Benchmark::backend, color, alpha, 0, \
-                              kBogusGLContextType, false };               \
-            configs->push(config);                                        \
+    #define CPU_CONFIG(name, backend, color, alpha)                        \
+        if (is_cpu_config_allowed(#name)) {                                \
+            Config config = { #name, Benchmark::backend, color, alpha, 0,  \
+                              kBogusGLContextType, kBogusGLContextOptions, \
+                              false };                                     \
+            configs->push(config);                                         \
         }
 
     if (FLAGS_cpu) {
@@ -418,8 +425,9 @@
     }
 
 #if SK_SUPPORT_GPU
-    #define GPU_CONFIG(name, ctxType, samples, useDFText)                        \
-        if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, samples)) {  \
+    #define GPU_CONFIG(name, ctxType, ctxOptions, samples, useDFText)            \
+        if (is_gpu_config_allowed(#name, GrContextFactory::ctxType,              \
+                                  GrContextFactory::ctxOptions, samples)) {      \
             Config config = {                                                    \
                 #name,                                                           \
                 Benchmark::kGPU_Backend,                                         \
@@ -427,28 +435,29 @@
                 kPremul_SkAlphaType,                                             \
                 samples,                                                         \
                 GrContextFactory::ctxType,                                       \
+                GrContextFactory::ctxOptions,                                    \
                 useDFText };                                                     \
             configs->push(config);                                               \
         }
 
     if (FLAGS_gpu) {
-        GPU_CONFIG(gpu, kNative_GLContextType, 0, false)
-        GPU_CONFIG(msaa4, kNative_GLContextType, 4, false)
-        GPU_CONFIG(msaa16, kNative_GLContextType, 16, false)
-        GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4, false)
-        GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16, false)
-        GPU_CONFIG(gpudft, kNative_GLContextType, 0, true)
-        GPU_CONFIG(debug, kDebug_GLContextType, 0, false)
-        GPU_CONFIG(nullgpu, kNull_GLContextType, 0, false)
+        GPU_CONFIG(gpu, kNative_GLContextType, kNone_GLContextOptions, 0, false)
+        GPU_CONFIG(msaa4, kNative_GLContextType, kNone_GLContextOptions, 4, false)
+        GPU_CONFIG(msaa16, kNative_GLContextType, kNone_GLContextOptions, 16, false)
+        GPU_CONFIG(nvprmsaa4, kNative_GLContextType, kEnableNVPR_GLContextOptions, 4, false)
+        GPU_CONFIG(nvprmsaa16, kNative_GLContextType, kEnableNVPR_GLContextOptions, 16, false)
+        GPU_CONFIG(gpudft, kNative_GLContextType, kNone_GLContextOptions, 0, true)
+        GPU_CONFIG(debug, kDebug_GLContextType, kNone_GLContextOptions, 0, false)
+        GPU_CONFIG(nullgpu, kNull_GLContextType, kNone_GLContextOptions, 0, false)
 #ifdef SK_ANGLE
-        GPU_CONFIG(angle, kANGLE_GLContextType, 0, false)
-        GPU_CONFIG(angle-gl, kANGLE_GL_GLContextType, 0, false)
+        GPU_CONFIG(angle, kANGLE_GLContextType, kNone_GLContextOptions, 0, false)
+        GPU_CONFIG(angle-gl, kANGLE_GL_GLContextType, kNone_GLContextOptions, 0, false)
 #endif
 #ifdef SK_COMMAND_BUFFER
-        GPU_CONFIG(commandbuffer, kCommandBuffer_GLContextType, 0, false)
+        GPU_CONFIG(commandbuffer, kCommandBuffer_GLContextType, kNone_GLContextOptions, 0, false)
 #endif
 #if SK_MESA
-        GPU_CONFIG(mesa, kMESA_GLContextType, 0, false)
+        GPU_CONFIG(mesa, kMESA_GLContextType, kNone_GLContextOptions, 0, false)
 #endif
     }
 #endif
@@ -456,7 +465,8 @@
 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
     if (is_cpu_config_allowed("hwui")) {
         Config config = { "hwui", Benchmark::kHWUI_Backend, kRGBA_8888_SkColorType,
-                          kPremul_SkAlphaType, 0, kBogusGLContextType, false };
+                          kPremul_SkAlphaType, 0, kBogusGLContextType, kBogusGLContextOptions,
+                          false };
         configs->push(config);
     }
 #endif
@@ -1268,8 +1278,10 @@
 
 #if SK_SUPPORT_GPU
             if (FLAGS_gpuStats && Benchmark::kGPU_Backend == configs[i].backend) {
-                gGrFactory->get(configs[i].ctxType)->printCacheStats();
-                gGrFactory->get(configs[i].ctxType)->printGpuStats();
+                GrContext* context = gGrFactory->get(configs[i].ctxType,
+                                                     kNone_GrGLStandard, configs[i].ctxOptions);
+                context->printCacheStats();
+                context->printGpuStats();
             }
 #endif
 
diff --git a/bench/nanobench.h b/bench/nanobench.h
index 36f5ad5..2dac30a 100644
--- a/bench/nanobench.h
+++ b/bench/nanobench.h
@@ -29,9 +29,11 @@
     int samples;
 #if SK_SUPPORT_GPU
     GrContextFactory::GLContextType ctxType;
+    GrContextFactory::GLContextOptions ctxOptions;
     bool useDFText;
 #else
     int bogusInt;
+    int bogusIntOption;
     bool bogusBool;
 #endif
 };
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 41e4c8d..9adfa9b 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -537,11 +537,13 @@
     }
 }
 
+#if SK_SUPPORT_GPU
 static GrGLStandard get_gpu_api() {
     if (FLAGS_gpuAPI.contains("gl"))   { return kGL_GrGLStandard; }
     if (FLAGS_gpuAPI.contains("gles")) { return kGLES_GrGLStandard; }
     return kNone_GrGLStandard;
 }
+#endif
 
 static void push_sink(const char* tag, Sink* s) {
     SkAutoTDelete<Sink> sink(s);
@@ -579,12 +581,14 @@
     return false;
 #endif
 }
-static Sink* create_gpu_sink(const char* tag, GrContextFactory::GLContextType contextType, int samples, bool diText, bool threaded) {
+static Sink* create_gpu_sink(const char* tag, GrContextFactory::GLContextType contextType,
+                             GrContextFactory::GLContextOptions contextOptions, int samples,
+                             bool diText, bool threaded) {
 #if SK_SUPPORT_GPU
     GrContextFactory testFactory;
     const GrGLStandard api = get_gpu_api();
     if (testFactory.get(contextType, api)) {
-        return new GPUSink(contextType, api, samples, diText, threaded);
+        return new GPUSink(contextType, contextOptions, api, samples, diText, threaded);
     }
     SkDebugf("WARNING: can not create GPU context for config '%s'. GM tests will be skipped.\n", tag);
 #endif
@@ -594,23 +598,23 @@
 #define GPU_SINK(t, ...) if (0 == strcmp(t, tag)) { return create_gpu_sink(tag, __VA_ARGS__); }
     if (gpu_supported()) {
         typedef GrContextFactory Gr;
-        GPU_SINK("gpunull",       Gr::kNull_GLContextType,           0, false, FLAGS_gpu_threading);
-        GPU_SINK("gpudebug",      Gr::kDebug_GLContextType,          0, false, FLAGS_gpu_threading);
-        GPU_SINK("gpu",           Gr::kNative_GLContextType,         0, false, FLAGS_gpu_threading);
-        GPU_SINK("gpudft",        Gr::kNative_GLContextType,         0,  true, FLAGS_gpu_threading);
-        GPU_SINK("msaa4",         Gr::kNative_GLContextType,         4, false, FLAGS_gpu_threading);
-        GPU_SINK("msaa16",        Gr::kNative_GLContextType,        16, false, FLAGS_gpu_threading);
-        GPU_SINK("nvprmsaa4",     Gr::kNVPR_GLContextType,           4,  true, FLAGS_gpu_threading);
-        GPU_SINK("nvprmsaa16",    Gr::kNVPR_GLContextType,          16,  true, FLAGS_gpu_threading);
+        GPU_SINK("gpunull",       Gr::kNull_GLContextType,          Gr::kNone_GLContextOptions,        0, false, FLAGS_gpu_threading);
+        GPU_SINK("gpudebug",      Gr::kDebug_GLContextType,         Gr::kNone_GLContextOptions,        0, false, FLAGS_gpu_threading);
+        GPU_SINK("gpu",           Gr::kNative_GLContextType,        Gr::kNone_GLContextOptions,        0, false, FLAGS_gpu_threading);
+        GPU_SINK("gpudft",        Gr::kNative_GLContextType,        Gr::kNone_GLContextOptions,        0,  true, FLAGS_gpu_threading);
+        GPU_SINK("msaa4",         Gr::kNative_GLContextType,        Gr::kNone_GLContextOptions,        4, false, FLAGS_gpu_threading);
+        GPU_SINK("msaa16",        Gr::kNative_GLContextType,        Gr::kNone_GLContextOptions,       16, false, FLAGS_gpu_threading);
+        GPU_SINK("nvprmsaa4",     Gr::kNative_GLContextType,        Gr::kEnableNVPR_GLContextOptions,  4,  true, FLAGS_gpu_threading);
+        GPU_SINK("nvprmsaa16",    Gr::kNative_GLContextType,        Gr::kEnableNVPR_GLContextOptions, 16,  true, FLAGS_gpu_threading);
 #if SK_ANGLE
-        GPU_SINK("angle",         Gr::kANGLE_GLContextType,          0, false, FLAGS_gpu_threading);
-        GPU_SINK("angle-gl",      Gr::kANGLE_GL_GLContextType,       0, false, FLAGS_gpu_threading);
+        GPU_SINK("angle",         Gr::kANGLE_GLContextType,         Gr::kNone_GLContextOptions,        0, false, FLAGS_gpu_threading);
+        GPU_SINK("angle-gl",      Gr::kANGLE_GL_GLContextType,      Gr::kNone_GLContextOptions,        0, false, FLAGS_gpu_threading);
 #endif
 #if SK_COMMAND_BUFFER
-        GPU_SINK("commandbuffer", Gr::kCommandBuffer_GLContextType,  0, false, FLAGS_gpu_threading);
+        GPU_SINK("commandbuffer", Gr::kCommandBuffer_GLContextType, Gr::kNone_GLContextOptions,        0, false, FLAGS_gpu_threading);
 #endif
 #if SK_MESA
-        GPU_SINK("mesa",          Gr::kMESA_GLContextType,           0, false, FLAGS_gpu_threading);
+        GPU_SINK("mesa",          Gr::kMESA_GLContextType,          Gr::kNone_GLContextOptions,        0, false, FLAGS_gpu_threading);
 #endif
     }
 #undef GPU_SINK
@@ -1164,6 +1168,7 @@
 void RunWithGPUTestContexts(T test, GPUTestContexts testContexts, Reporter* reporter,
                             GrContextFactory* factory) {
 #if SK_SUPPORT_GPU
+    const GrGLStandard api = get_gpu_api();
     for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
         GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
         int contextSelector = kNone_GPUTestContexts;
@@ -1179,7 +1184,12 @@
         if ((testContexts & contextSelector) == 0) {
             continue;
         }
-        if (GrContextFactory::ContextInfo* context = factory->getContextInfo(glCtxType)) {
+        if (GrContextFactory::ContextInfo* context = factory->getContextInfo(glCtxType, api)) {
+            call_test(test, reporter, context);
+        }
+        if (GrContextFactory::ContextInfo* context =
+            factory->getContextInfo(glCtxType, api,
+                                    GrContextFactory::kEnableNVPR_GLContextOptions)) {
             call_test(test, reporter, context);
         }
     }
diff --git a/dm/DMGpuSupport.h b/dm/DMGpuSupport.h
index bccf112..627dc4f 100644
--- a/dm/DMGpuSupport.h
+++ b/dm/DMGpuSupport.h
@@ -30,14 +30,15 @@
 
 static inline SkSurface* NewGpuSurface(GrContextFactory* grFactory,
                                        GrContextFactory::GLContextType type,
+                                       GrContextFactory::GLContextOptions options,
                                        GrGLStandard gpuAPI,
                                        SkImageInfo info,
                                        int samples,
                                        bool useDIText) {
     uint32_t flags = useDIText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 0;
     SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
-    return SkSurface::NewRenderTarget(grFactory->get(type, gpuAPI), SkSurface::kNo_Budgeted,
-                                      info, samples, &props);
+    return SkSurface::NewRenderTarget(grFactory->get(type, gpuAPI, options),
+                                      SkSurface::kNo_Budgeted, info, samples, &props);
 }
 
 }  // namespace DM
@@ -75,6 +76,10 @@
                                kNative_GLContextType        = 0,
                                kNull_GLContextType          = 0;
     static const int kGLContextTypeCnt = 1;
+    enum GLContextOptions {
+        kNone_GLContextOptions = 0,
+        kEnableNVPR_GLContextOptions = 0x1,
+    };
     void destroyContexts() {}
 
     void abandonContexts() {}
@@ -86,6 +91,7 @@
 
 static inline SkSurface* NewGpuSurface(GrContextFactory*,
                                        GrContextFactory::GLContextType,
+                                       GrContextFactory::GLContextOptions,
                                        GrGLStandard,
                                        SkImageInfo,
                                        int,
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 26ba13b..6e03923 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -789,12 +789,14 @@
 DEFINE_bool(gpuStats, false, "Append GPU stats to the log for each GPU task?");
 
 GPUSink::GPUSink(GrContextFactory::GLContextType ct,
-                 GrGLStandard api,
+                 GrContextFactory::GLContextOptions options,
+                 GrGLStandard gpuAPI,
                  int samples,
                  bool diText,
                  bool threaded)
     : fContextType(ct)
-    , fGpuAPI(api)
+    , fContextOptions(options)
+    , fGpuAPI(gpuAPI)
     , fSampleCount(samples)
     , fUseDIText(diText)
     , fThreaded(threaded) {}
@@ -810,24 +812,26 @@
 DEFINE_bool(batchBounds, false, "Draw a wireframe bounds of each GrBatch.");
 
 Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) const {
-    GrContextOptions options;
+    GrContextOptions grOptions;
     if (FLAGS_imm) {
-        options.fImmediateMode = true;
+        grOptions.fImmediateMode = true;
     }
     if (FLAGS_batchClip) {
-        options.fClipBatchToBounds = true;
+        grOptions.fClipBatchToBounds = true;
     }
-    if (FLAGS_batchBounds) {
-        options.fDrawBatchBounds = true;
-    }
-    src.modifyGrContextOptions(&options);
 
-    GrContextFactory factory(options);
+    if (FLAGS_batchBounds) {
+        grOptions.fDrawBatchBounds = true;
+    }
+    src.modifyGrContextOptions(&grOptions);
+
+    GrContextFactory factory(grOptions);
     const SkISize size = src.size();
     const SkImageInfo info =
         SkImageInfo::Make(size.width(), size.height(), kN32_SkColorType, kPremul_SkAlphaType);
     SkAutoTUnref<SkSurface> surface(
-            NewGpuSurface(&factory, fContextType, fGpuAPI, info, fSampleCount, fUseDIText));
+            NewGpuSurface(&factory, fContextType, fContextOptions, fGpuAPI, info, fSampleCount,
+                          fUseDIText));
     if (!surface) {
         return "Could not create a surface.";
     }
diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h
index e155508..6b644ec 100644
--- a/dm/DMSrcSink.h
+++ b/dm/DMSrcSink.h
@@ -214,18 +214,20 @@
 
 class GPUSink : public Sink {
 public:
-    GPUSink(GrContextFactory::GLContextType, GrGLStandard, int samples, bool diText, bool threaded);
+    GPUSink(GrContextFactory::GLContextType, GrContextFactory::GLContextOptions,
+            GrGLStandard, int samples, bool diText, bool threaded);
 
     Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
     int enclave() const override;
     const char* fileExtension() const override { return "png"; }
     SinkFlags flags() const override { return SinkFlags{ SinkFlags::kGPU, SinkFlags::kDirect }; }
 private:
-    GrContextFactory::GLContextType fContextType;
-    GrGLStandard                    fGpuAPI;
-    int                             fSampleCount;
-    bool                            fUseDIText;
-    bool                            fThreaded;
+    GrContextFactory::GLContextType    fContextType;
+    GrContextFactory::GLContextOptions fContextOptions;
+    GrGLStandard                       fGpuAPI;
+    int                                fSampleCount;
+    bool                               fUseDIText;
+    bool                               fThreaded;
 };
 
 class PDFSink : public Sink {
diff --git a/src/gpu/GrContextFactory.cpp b/src/gpu/GrContextFactory.cpp
index 097b99b..15af816 100755
--- a/src/gpu/GrContextFactory.cpp
+++ b/src/gpu/GrContextFactory.cpp
@@ -24,13 +24,13 @@
 #include "GrCaps.h"
 
 GrContextFactory::ContextInfo* GrContextFactory::getContextInfo(GLContextType type,
-                                                                GrGLStandard forcedGpuAPI) {
+                                                                GrGLStandard forcedGpuAPI,
+                                                                GLContextOptions options) {
     for (int i = 0; i < fContexts.count(); ++i) {
-        if (forcedGpuAPI != kNone_GrGLStandard &&
-            forcedGpuAPI != fContexts[i]->fGLContext->gl()->fStandard)
-            continue;
-
-        if (fContexts[i]->fType == type) {
+        if (fContexts[i]->fType == type &&
+            fContexts[i]->fOptions == options &&
+            (forcedGpuAPI == kNone_GrGLStandard ||
+             forcedGpuAPI == fContexts[i]->fGLContext->gl()->fStandard)) {
             fContexts[i]->fGLContext->makeCurrent();
             return fContexts[i];
         }
@@ -38,7 +38,6 @@
     SkAutoTUnref<SkGLContext> glCtx;
     SkAutoTUnref<GrContext> grCtx;
     switch (type) {
-        case kNVPR_GLContextType: // fallthru
         case kNative_GLContextType:
             glCtx.reset(SkCreatePlatformGLContext(forcedGpuAPI));
             break;
@@ -75,7 +74,7 @@
 
     // Block NVPR from non-NVPR types.
     SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx->gl()));
-    if (kNVPR_GLContextType != type) {
+    if (!(kEnableNVPR_GLContextOptions & options)) {
         glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
         if (!glInterface) {
             return nullptr;
@@ -92,7 +91,7 @@
     if (!grCtx.get()) {
         return nullptr;
     }
-    if (kNVPR_GLContextType == type) {
+    if (kEnableNVPR_GLContextOptions & options) {
         if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) {
             return nullptr;
         }
@@ -102,5 +101,6 @@
     ctx->fGLContext = SkRef(glCtx.get());
     ctx->fGrContext = SkRef(grCtx.get());
     ctx->fType = type;
+    ctx->fOptions = options;
     return ctx;
 }
diff --git a/src/gpu/GrContextFactory.h b/src/gpu/GrContextFactory.h
index c837e74..5097813 100644
--- a/src/gpu/GrContextFactory.h
+++ b/src/gpu/GrContextFactory.h
@@ -23,35 +23,34 @@
  */
 class GrContextFactory : SkNoncopyable {
 public:
-    /**
-     * Types of GL contexts supported. For historical and testing reasons the native GrContext will
-     * not use "GL_NV_path_rendering" even when the driver supports it. There is a separate context
-     * type that does not remove NVPR support and which will fail when the driver does not support
-     * the extension.
-     */
     enum GLContextType {
-      kNative_GLContextType,
+        kNative_GLContextType,
 #if SK_ANGLE
-      kANGLE_GLContextType,
-      kANGLE_GL_GLContextType,
+        kANGLE_GLContextType,
+        kANGLE_GL_GLContextType,
 #endif
 #if SK_COMMAND_BUFFER
-      kCommandBuffer_GLContextType,
+        kCommandBuffer_GLContextType,
 #endif
 #if SK_MESA
-      kMESA_GLContextType,
+        kMESA_GLContextType,
 #endif
-      /** Similar to kNative but does not filter NVPR. It will fail if the GL driver does not
-          support NVPR */
-      kNVPR_GLContextType,
-      kNull_GLContextType,
-      kDebug_GLContextType,
-
-      kLastGLContextType = kDebug_GLContextType
+        kNull_GLContextType,
+        kDebug_GLContextType,
+        kLastGLContextType = kDebug_GLContextType
     };
 
     static const int kGLContextTypeCnt = kLastGLContextType + 1;
 
+    /**
+     * Options for GL context creation. For historical and testing reasons the options will default
+     * to not using GL_NV_path_rendering extension  even when the driver supports it.
+     */
+    enum GLContextOptions {
+        kNone_GLContextOptions = 0,
+        kEnableNVPR_GLContextOptions = 0x1,
+    };
+
     static bool IsRenderingGLContext(GLContextType type) {
         switch (type) {
             case kNull_GLContextType:
@@ -82,8 +81,6 @@
             case kMESA_GLContextType:
                 return "mesa";
 #endif
-            case kNVPR_GLContextType:
-                return "nvpr";
             case kDebug_GLContextType:
                 return "debug";
             default:
@@ -119,6 +116,7 @@
 
     struct ContextInfo {
         GLContextType             fType;
+        GLContextOptions          fOptions;
         SkGLContext*              fGLContext;
         GrContext*                fGrContext;
     };
@@ -126,13 +124,15 @@
      * Get a context initialized with a type of GL context. It also makes the GL context current.
      * Pointer is valid until destroyContexts() is called.
      */
-    ContextInfo* getContextInfo(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard);
+    ContextInfo* getContextInfo(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard,
+                                GLContextOptions options = kNone_GLContextOptions);
 
     /**
      * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
      */
-    GrContext* get(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard) {
-        if (ContextInfo* info = this->getContextInfo(type, forcedGpuAPI)) {
+    GrContext* get(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard,
+                   GLContextOptions options = kNone_GLContextOptions) {
+        if (ContextInfo* info = this->getContextInfo(type, forcedGpuAPI, options)) {
             return info->fGrContext;
         }
         return nullptr;
diff --git a/tests/GrContextFactoryTest.cpp b/tests/GrContextFactoryTest.cpp
index 176391e..50bdedff 100644
--- a/tests/GrContextFactoryTest.cpp
+++ b/tests/GrContextFactoryTest.cpp
@@ -13,11 +13,13 @@
 #include "GrCaps.h"
 #include "Test.h"
 
-DEF_GPUTEST(GrContextFactory_NVPRContextTypeHasPathRenderingSupport, reporter, /*factory*/) {
+DEF_GPUTEST(GrContextFactory_NVPRContextOptionHasPathRenderingSupport, reporter, /*factory*/) {
     // Test that if NVPR is requested, the context always has path rendering
     // or the context creation fails.
     GrContextFactory testFactory;
-    GrContext* context = testFactory.get(GrContextFactory::kNVPR_GLContextType);
+    GrContext* context = testFactory.get(GrContextFactory::kNative_GLContextType,
+                                         kNone_GrGLStandard,
+                                         GrContextFactory::kEnableNVPR_GLContextOptions);
     if (context) {
         REPORTER_ASSERT(
             reporter,
@@ -31,9 +33,6 @@
     GrContextFactory testFactory;
     for (int i = 0; i <= GrContextFactory::kLastGLContextType; ++i) {
         GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType)i;
-        if (glCtxType == GrContextFactory::kNVPR_GLContextType) {
-            continue;
-        }
         GrContext* context = testFactory.get(glCtxType);
         if (context) {
             REPORTER_ASSERT(