Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2012 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef GrContextFactory_DEFINED
      9 #define GrContextFactory_DEFINED
     10 
     11 #include "GrContext.h"
     12 #include "GrContextOptions.h"
     13 
     14 #include "gl/GLTestContext.h"
     15 #include "SkTArray.h"
     16 
     17 struct GrVkBackendContext;
     18 
     19 namespace sk_gpu_test {
     20 class ContextInfo;
     21 
     22 /**
     23  * This is a simple class that is useful in test apps that use different
     24  * GrContexts backed by different types of GL contexts. It manages creating the
     25  * GL context and a GrContext that uses it. The GL/Gr contexts persist until the
     26  * factory is destroyed (though the caller can always grab a ref on the returned
     27  * Gr and GL contexts to make them outlive the factory).
     28  */
     29 class GrContextFactory : SkNoncopyable {
     30 public:
     31     // The availability of context types is subject to platform and build configuration
     32     // restrictions.
     33     enum ContextType {
     34         kGL_ContextType,             //! OpenGL context.
     35         kGLES_ContextType,           //! OpenGL ES context.
     36         kANGLE_D3D9_ES2_ContextType, //! ANGLE on Direct3D9 OpenGL ES 2 context.
     37         kANGLE_D3D11_ES2_ContextType,//! ANGLE on Direct3D11 OpenGL ES 2 context.
     38         kANGLE_D3D11_ES3_ContextType,//! ANGLE on Direct3D11 OpenGL ES 3 context.
     39         kANGLE_GL_ES2_ContextType,   //! ANGLE on OpenGL OpenGL ES 2 context.
     40         kANGLE_GL_ES3_ContextType,   //! ANGLE on OpenGL OpenGL ES 3 context.
     41         kCommandBuffer_ContextType,  //! Chromium command buffer OpenGL ES context.
     42         kMESA_ContextType,           //! MESA OpenGL context
     43         kNullGL_ContextType,         //! Non-rendering OpenGL mock context.
     44         kDebugGL_ContextType,        //! Non-rendering, state verifying OpenGL context.
     45         kVulkan_ContextType,         //! Vulkan
     46         kMetal_ContextType,          //! Metal
     47         kMock_ContextType,           //! Mock context that does not draw.
     48         kLastContextType = kMock_ContextType
     49     };
     50 
     51     static const int kContextTypeCnt = kLastContextType + 1;
     52 
     53     /**
     54      * Overrides for the initial GrContextOptions provided at construction time, and required
     55      * features that will cause context creation to fail if not present.
     56      */
     57     enum class ContextOverrides {
     58         kNone                          = 0x0,
     59         kDisableNVPR                   = 0x1,
     60         kUseInstanced                  = 0x2,
     61         kAllowSRGBWithoutDecodeControl = 0x4,
     62         kAvoidStencilBuffers           = 0x8,
     63 
     64         kRequireNVPRSupport            = 0x10,
     65         kRequireSRGBSupport            = 0x20,
     66     };
     67 
     68     static bool IsRenderingContext(ContextType type) {
     69         switch (type) {
     70             case kNullGL_ContextType:
     71             case kDebugGL_ContextType:
     72             case kMock_ContextType:
     73                 return false;
     74             default:
     75                 return true;
     76         }
     77     }
     78 
     79     static GrBackend ContextTypeBackend(ContextType type) {
     80         switch (type) {
     81             case kVulkan_ContextType:
     82                 return kVulkan_GrBackend;
     83             case kMetal_ContextType:
     84                 return kMetal_GrBackend;
     85             case kMock_ContextType:
     86                 return kMock_GrBackend;
     87             default:
     88                 return kOpenGL_GrBackend;
     89         }
     90     }
     91 
     92     static const char* ContextTypeName(ContextType contextType) {
     93         switch (contextType) {
     94             case kGL_ContextType:
     95                 return "OpenGL";
     96             case kGLES_ContextType:
     97                 return "OpenGLES";
     98             case kANGLE_D3D9_ES2_ContextType:
     99                 return "ANGLE D3D9 ES2";
    100             case kANGLE_D3D11_ES2_ContextType:
    101                 return "ANGLE D3D11 ES2";
    102             case kANGLE_D3D11_ES3_ContextType:
    103                 return "ANGLE D3D11 ES3";
    104             case kANGLE_GL_ES2_ContextType:
    105                 return "ANGLE GL ES2";
    106             case kANGLE_GL_ES3_ContextType:
    107                 return "ANGLE GL ES3";
    108             case kCommandBuffer_ContextType:
    109                 return "Command Buffer";
    110             case kMESA_ContextType:
    111                 return "Mesa";
    112             case kNullGL_ContextType:
    113                 return "Null GL";
    114             case kDebugGL_ContextType:
    115                 return "Debug GL";
    116             case kVulkan_ContextType:
    117                 return "Vulkan";
    118             case kMetal_ContextType:
    119                 return "Metal";
    120             case kMock_ContextType:
    121                 return "Mock";
    122         }
    123         SkFAIL("Unreachable");
    124         return "Unknown";
    125     }
    126 
    127     explicit GrContextFactory(const GrContextOptions& opts);
    128     GrContextFactory();
    129 
    130     ~GrContextFactory();
    131 
    132     void destroyContexts();
    133     void abandonContexts();
    134     void releaseResourcesAndAbandonContexts();
    135 
    136     /**
    137      * Get a context initialized with a type of GL context. It also makes the GL context current.
    138      */
    139     ContextInfo getContextInfo(ContextType type,
    140                                ContextOverrides overrides = ContextOverrides::kNone);
    141 
    142     /**
    143      * Get a context in the same share group as the passed in GrContext, with the same type and
    144      * overrides. To get multiple contexts in a single share group, pass the same shareContext,
    145      * with different values for shareIndex.
    146      */
    147     ContextInfo getSharedContextInfo(GrContext* shareContext, uint32_t shareIndex = 0);
    148 
    149     /**
    150      * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
    151      */
    152     GrContext* get(ContextType type, ContextOverrides overrides = ContextOverrides::kNone);
    153     const GrContextOptions& getGlobalOptions() const { return fGlobalOptions; }
    154 
    155 private:
    156     ContextInfo getContextInfoInternal(ContextType type, ContextOverrides overrides,
    157                                        GrContext* shareContext, uint32_t shareIndex);
    158 
    159     struct Context {
    160         ContextType       fType;
    161         ContextOverrides  fOverrides;
    162         GrBackend         fBackend;
    163         TestContext*      fTestContext;
    164         GrContext*        fGrContext;
    165         GrContext*        fShareContext;
    166         uint32_t          fShareIndex;
    167 
    168         bool            fAbandoned;
    169     };
    170     SkTArray<Context, true>         fContexts;
    171     std::unique_ptr<GLTestContext>  fSentinelGLContext;
    172     const GrContextOptions          fGlobalOptions;
    173 };
    174 
    175 class ContextInfo {
    176 public:
    177     ContextInfo() = default;
    178     ContextInfo& operator=(const ContextInfo&) = default;
    179 
    180     GrContextFactory::ContextType type() const { return fType; }
    181     GrBackend backend() const { return GrContextFactory::ContextTypeBackend(fType); }
    182 
    183     GrContext* grContext() const { return fGrContext; }
    184 
    185     TestContext* testContext() const { return fTestContext; }
    186 
    187     GLTestContext* glContext() const {
    188         SkASSERT(kOpenGL_GrBackend == this->backend());
    189         return static_cast<GLTestContext*>(fTestContext);
    190     }
    191 
    192 private:
    193     ContextInfo(GrContextFactory::ContextType type,
    194                 TestContext* testContext,
    195                 GrContext* grContext)
    196         : fType(type)
    197         , fTestContext(testContext)
    198         , fGrContext(grContext) {
    199     }
    200 
    201     GrContextFactory::ContextType fType = GrContextFactory::kGL_ContextType;
    202     // Valid until the factory destroys it via abandonContexts() or destroyContexts().
    203     TestContext*    fTestContext = nullptr;
    204     GrContext*      fGrContext = nullptr;
    205 
    206     friend class GrContextFactory;
    207 };
    208 
    209 }  // namespace sk_gpu_test
    210 
    211 GR_MAKE_BITFIELD_CLASS_OPS(sk_gpu_test::GrContextFactory::ContextOverrides);
    212 
    213 #endif
    214