1e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen/*
2e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * Copyright 2012 Google Inc.
3e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen *
4e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * Use of this source code is governed by a BSD-style license that can be
5e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * found in the LICENSE file.
6e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen */
7e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
8e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#ifndef GrContextFactory_DEFINED
9e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#define GrContextFactory_DEFINED
10e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
11e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#include "GrContext.h"
12682c269a1511200322916af83053e26004c0ec40bsalomon#include "GrContextOptions.h"
13e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
14273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon#include "gl/GLTestContext.h"
15e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#include "SkTArray.h"
16e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
17dc0fcd41e75682a8bfd5e285d684461475226330bsalomonstruct GrVkBackendContext;
18dc0fcd41e75682a8bfd5e285d684461475226330bsalomon
193724e574a744491b7cfb8187ac865a70ef3d4528bsalomonnamespace sk_gpu_test {
20cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillipsclass ContextInfo;
21f2f1c17e331fe1e0ce695969970ecebc81e12cebbsalomon
22e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen/**
23e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * This is a simple class that is useful in test apps that use different
24e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * GrContexts backed by different types of GL contexts. It manages creating the
25e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * GL context and a GrContext that uses it. The GL/Gr contexts persist until the
26e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * factory is destroyed (though the caller can always grab a ref on the returned
27e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * Gr and GL contexts to make them outlive the factory).
28e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen */
29e4545210c950f98d9fa20f51bc1be6c5591534bddjsollenclass GrContextFactory : SkNoncopyable {
30e4545210c950f98d9fa20f51bc1be6c5591534bddjsollenpublic:
31dc0fcd41e75682a8bfd5e285d684461475226330bsalomon    // The availability of context types is subject to platform and build configuration
32dc0fcd41e75682a8bfd5e285d684461475226330bsalomon    // restrictions.
3385b4b53e78dcdeae2a51935ca5e214b0f1a06492bsalomon    enum ContextType {
3411abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kGL_ContextType,             //! OpenGL context.
3511abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kGLES_ContextType,           //! OpenGL ES context.
3611abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kANGLE_D3D9_ES2_ContextType, //! ANGLE on Direct3D9 OpenGL ES 2 context.
3711abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kANGLE_D3D11_ES2_ContextType,//! ANGLE on Direct3D11 OpenGL ES 2 context.
3811abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kANGLE_D3D11_ES3_ContextType,//! ANGLE on Direct3D11 OpenGL ES 3 context.
3911abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kANGLE_GL_ES2_ContextType,   //! ANGLE on OpenGL OpenGL ES 2 context.
4011abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kANGLE_GL_ES3_ContextType,   //! ANGLE on OpenGL OpenGL ES 3 context.
4111abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kCommandBuffer_ContextType,  //! Chromium command buffer OpenGL ES context.
4211abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kMESA_ContextType,           //! MESA OpenGL context
4311abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kNullGL_ContextType,         //! Non-rendering OpenGL mock context.
4411abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kDebugGL_ContextType,        //! Non-rendering, state verifying OpenGL context.
4511abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        kVulkan_ContextType,         //! Vulkan
462811aa25f1f7c5f5b31eb0cb7dabcbab90d9709dGreg Daniel        kMetal_ContextType,          //! Metal
47cfe910dc794d8def481b532bfe68f4a3ff8fc9d7Brian Salomon        kMock_ContextType,           //! Mock context that does not draw.
48cfe910dc794d8def481b532bfe68f4a3ff8fc9d7Brian Salomon        kLastContextType = kMock_ContextType
49e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    };
50e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
5185b4b53e78dcdeae2a51935ca5e214b0f1a06492bsalomon    static const int kContextTypeCnt = kLastContextType + 1;
52e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
535219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen    /**
54e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton     * Overrides for the initial GrContextOptions provided at construction time, and required
55e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton     * features that will cause context creation to fail if not present.
565219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen     */
57e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton    enum class ContextOverrides {
58e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton        kNone                          = 0x0,
59e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton        kDisableNVPR                   = 0x1,
60e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton        kUseInstanced                  = 0x2,
61e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton        kAllowSRGBWithoutDecodeControl = 0x4,
625c77975e4c00e18e644c72b56f369858acd11b15Eric Karl        kAvoidStencilBuffers           = 0x8,
63e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton
645c77975e4c00e18e644c72b56f369858acd11b15Eric Karl        kRequireNVPRSupport            = 0x10,
655c77975e4c00e18e644c72b56f369858acd11b15Eric Karl        kRequireSRGBSupport            = 0x20,
665219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen    };
675219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen
6885b4b53e78dcdeae2a51935ca5e214b0f1a06492bsalomon    static bool IsRenderingContext(ContextType type) {
69e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        switch (type) {
7085b4b53e78dcdeae2a51935ca5e214b0f1a06492bsalomon            case kNullGL_ContextType:
7185b4b53e78dcdeae2a51935ca5e214b0f1a06492bsalomon            case kDebugGL_ContextType:
72cfe910dc794d8def481b532bfe68f4a3ff8fc9d7Brian Salomon            case kMock_ContextType:
73e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return false;
74e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            default:
75e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return true;
76e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        }
77e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    }
78e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
79758586c7f11a6b3529bd4a1c9b4e982a0d0b0582bsalomon    static GrBackend ContextTypeBackend(ContextType type) {
80dc0fcd41e75682a8bfd5e285d684461475226330bsalomon        switch (type) {
81dc0fcd41e75682a8bfd5e285d684461475226330bsalomon            case kVulkan_ContextType:
82dc0fcd41e75682a8bfd5e285d684461475226330bsalomon                return kVulkan_GrBackend;
832811aa25f1f7c5f5b31eb0cb7dabcbab90d9709dGreg Daniel            case kMetal_ContextType:
842811aa25f1f7c5f5b31eb0cb7dabcbab90d9709dGreg Daniel                return kMetal_GrBackend;
85cfe910dc794d8def481b532bfe68f4a3ff8fc9d7Brian Salomon            case kMock_ContextType:
86cfe910dc794d8def481b532bfe68f4a3ff8fc9d7Brian Salomon                return kMock_GrBackend;
87dc0fcd41e75682a8bfd5e285d684461475226330bsalomon            default:
88dc0fcd41e75682a8bfd5e285d684461475226330bsalomon                return kOpenGL_GrBackend;
89dc0fcd41e75682a8bfd5e285d684461475226330bsalomon        }
90758586c7f11a6b3529bd4a1c9b4e982a0d0b0582bsalomon    }
91758586c7f11a6b3529bd4a1c9b4e982a0d0b0582bsalomon
92a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    static const char* ContextTypeName(ContextType contextType) {
93a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel        switch (contextType) {
94a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kGL_ContextType:
95a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "OpenGL";
96a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kGLES_ContextType:
97a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "OpenGLES";
98a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kANGLE_D3D9_ES2_ContextType:
99a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "ANGLE D3D9 ES2";
100a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kANGLE_D3D11_ES2_ContextType:
101a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "ANGLE D3D11 ES2";
102a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kANGLE_D3D11_ES3_ContextType:
103a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "ANGLE D3D11 ES3";
104a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kANGLE_GL_ES2_ContextType:
105a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "ANGLE GL ES2";
106a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kANGLE_GL_ES3_ContextType:
107a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "ANGLE GL ES3";
108a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kCommandBuffer_ContextType:
109a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "Command Buffer";
110a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kMESA_ContextType:
111a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "Mesa";
112a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kNullGL_ContextType:
113a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "Null GL";
114a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kDebugGL_ContextType:
115a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "Debug GL";
116a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            case kVulkan_ContextType:
117a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                return "Vulkan";
1182811aa25f1f7c5f5b31eb0cb7dabcbab90d9709dGreg Daniel            case kMetal_ContextType:
1192811aa25f1f7c5f5b31eb0cb7dabcbab90d9709dGreg Daniel                return "Metal";
120cfe910dc794d8def481b532bfe68f4a3ff8fc9d7Brian Salomon            case kMock_ContextType:
121cfe910dc794d8def481b532bfe68f4a3ff8fc9d7Brian Salomon                return "Mock";
122a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel        }
123cfe910dc794d8def481b532bfe68f4a3ff8fc9d7Brian Salomon        SkFAIL("Unreachable");
124a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel        return "Unknown";
125a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    }
126a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel
1273405800d7a5407365143eed93e300fd5896caceekkinnunen    explicit GrContextFactory(const GrContextOptions& opts);
1283405800d7a5407365143eed93e300fd5896caceekkinnunen    GrContextFactory();
129e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
1303405800d7a5407365143eed93e300fd5896caceekkinnunen    ~GrContextFactory();
131e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
1323405800d7a5407365143eed93e300fd5896caceekkinnunen    void destroyContexts();
1333405800d7a5407365143eed93e300fd5896caceekkinnunen    void abandonContexts();
1346e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    void releaseResourcesAndAbandonContexts();
135e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
136e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    /**
137179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen     * Get a context initialized with a type of GL context. It also makes the GL context current.
138e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen     */
13985b4b53e78dcdeae2a51935ca5e214b0f1a06492bsalomon    ContextInfo getContextInfo(ContextType type,
1409eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman                               ContextOverrides overrides = ContextOverrides::kNone);
1419eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman
1429eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman    /**
1439eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman     * Get a context in the same share group as the passed in GrContext, with the same type and
1449eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman     * overrides. To get multiple contexts in a single share group, pass the same shareContext,
1459eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman     * with different values for shareIndex.
1469eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman     */
1479eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman    ContextInfo getSharedContextInfo(GrContext* shareContext, uint32_t shareIndex = 0);
1489eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman
149179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen    /**
150179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen     * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
151179a8f5f7feab052e24596d0d04ab5cf2ccab5e0kkinnunen     */
152cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    GrContext* get(ContextType type, ContextOverrides overrides = ContextOverrides::kNone);
153682c269a1511200322916af83053e26004c0ec40bsalomon    const GrContextOptions& getGlobalOptions() const { return fGlobalOptions; }
154e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
155e4545210c950f98d9fa20f51bc1be6c5591534bddjsollenprivate:
1569eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman    ContextInfo getContextInfoInternal(ContextType type, ContextOverrides overrides,
1579eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman                                       GrContext* shareContext, uint32_t shareIndex);
1589eac2ea77340d13bac58c7171e2e3971028ef8f8Brian Osman
1593405800d7a5407365143eed93e300fd5896caceekkinnunen    struct Context {
160e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton        ContextType       fType;
161e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton        ContextOverrides  fOverrides;
162e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton        GrBackend         fBackend;
163e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton        TestContext*      fTestContext;
164e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdalton        GrContext*        fGrContext;
16560c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman        GrContext*        fShareContext;
16660c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman        uint32_t          fShareIndex;
16760c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman
16860c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman        bool            fAbandoned;
1693405800d7a5407365143eed93e300fd5896caceekkinnunen    };
170dc0fcd41e75682a8bfd5e285d684461475226330bsalomon    SkTArray<Context, true>         fContexts;
1717f9c29a887106ab3babe0ec423a3bcae87ae4788Brian Salomon    std::unique_ptr<GLTestContext>  fSentinelGLContext;
172dc0fcd41e75682a8bfd5e285d684461475226330bsalomon    const GrContextOptions          fGlobalOptions;
173e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen};
174cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips
175cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillipsclass ContextInfo {
176cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillipspublic:
177cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    ContextInfo() = default;
178cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    ContextInfo& operator=(const ContextInfo&) = default;
179cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips
180cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    GrContextFactory::ContextType type() const { return fType; }
181cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    GrBackend backend() const { return GrContextFactory::ContextTypeBackend(fType); }
182cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips
183cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    GrContext* grContext() const { return fGrContext; }
184cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips
185cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    TestContext* testContext() const { return fTestContext; }
186cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips
187cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    GLTestContext* glContext() const {
188cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips        SkASSERT(kOpenGL_GrBackend == this->backend());
189cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips        return static_cast<GLTestContext*>(fTestContext);
190cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    }
191cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips
192cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillipsprivate:
193cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    ContextInfo(GrContextFactory::ContextType type,
194cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips                TestContext* testContext,
195cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips                GrContext* grContext)
196cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips        : fType(type)
197cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips        , fTestContext(testContext)
198cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips        , fGrContext(grContext) {
199cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    }
200cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips
201cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    GrContextFactory::ContextType fType = GrContextFactory::kGL_ContextType;
202cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    // Valid until the factory destroys it via abandonContexts() or destroyContexts().
203cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    TestContext*    fTestContext = nullptr;
204cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    GrContext*      fGrContext = nullptr;
205cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips
206cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips    friend class GrContextFactory;
207cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips};
208cdabbcc3b57f7c7e3ef1c28538c9e91b7a1eaa33Robert Phillips
2093724e574a744491b7cfb8187ac865a70ef3d4528bsalomon}  // namespace sk_gpu_test
2106270e558c31b75d02db6f598e93f2e3b701ccb7fcsmartdalton
211e812d496aaa5e5e9f2117de8f442c297c9cb1367csmartdaltonGR_MAKE_BITFIELD_CLASS_OPS(sk_gpu_test::GrContextFactory::ContextOverrides);
2126270e558c31b75d02db6f598e93f2e3b701ccb7fcsmartdalton
213e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#endif
214