aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/GrContextFactoryTest.cpp
blob: b05f2e29ce4b2589f7678bf9f2bdb788c3773e75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkTypes.h"

#include "GrContextFactory.h"
#include "GrContextPriv.h"
#include "GrCaps.h"
#include "SkExecutor.h"
#include "Test.h"

using namespace sk_gpu_test;

DEF_GPUTEST(GrContextFactory_NVPRContextOptionHasPathRenderingSupport, reporter, options) {
    // Test that if NVPR is requested, the context always has path rendering
    // or the context creation fails.
    for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
        GrContextFactory testFactory(options);
        // Test that if NVPR is possible, caps are in sync.
        GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
        GrContext* context = testFactory.get(ctxType,
                                           GrContextFactory::ContextOverrides::kRequireNVPRSupport);
        if (!context) {
            continue;
        }
        REPORTER_ASSERT(reporter,
                        context->contextPriv().caps()->shaderCaps()->pathRenderingSupport());
    }
}

DEF_GPUTEST(GrContextFactory_NoPathRenderingIfNVPRDisabled, reporter, options) {
    // Test that if NVPR is explicitly disabled, the context has no path rendering support.

    for (int i = 0; i <= GrContextFactory::kLastContextType; ++i) {
        GrContextFactory testFactory(options);
        GrContextFactory::ContextType ctxType = (GrContextFactory::ContextType)i;
        GrContext* context =
            testFactory.get(ctxType, GrContextFactory::ContextOverrides::kDisableNVPR);
        if (context) {
            REPORTER_ASSERT(reporter,
                            !context->contextPriv().caps()->shaderCaps()->pathRenderingSupport());
        }
    }
}

DEF_GPUTEST(GrContextFactory_abandon, reporter, options) {
    for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
        GrContextFactory testFactory(options);
        GrContextFactory::ContextType ctxType = (GrContextFactory::ContextType) i;
        ContextInfo info1 = testFactory.getContextInfo(ctxType);
        if (!info1.grContext()) {
            continue;
        }
        REPORTER_ASSERT(reporter, info1.testContext());
         // Ref for comparison. The API does not explicitly say that this stays alive.
        info1.grContext()->ref();
        testFactory.abandonContexts();

        // Test that we get different context after abandon.
        ContextInfo info2 = testFactory.getContextInfo(ctxType);
        REPORTER_ASSERT(reporter, info2.grContext());
        REPORTER_ASSERT(reporter, info2.testContext());

        REPORTER_ASSERT(reporter, info1.grContext() != info2.grContext());
        // The GL context should also change, but it also could get the same address.

        info1.grContext()->unref();
    }
}

DEF_GPUTEST(GrContextFactory_sharedContexts, reporter, options) {
    for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
        GrContextFactory testFactory(options);
        GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
        ContextInfo info1 = testFactory.getContextInfo(ctxType);
        if (!info1.grContext()) {
            continue;
        }

        // Ref for passing in. The API does not explicitly say that this stays alive.
        info1.grContext()->ref();
        testFactory.abandonContexts();

        // Test that creating a context in a share group with an abandoned context fails.
        ContextInfo info2 = testFactory.getSharedContextInfo(info1.grContext());
        REPORTER_ASSERT(reporter, !info2.grContext());
        info1.grContext()->unref();

        // Create a new base context
        ContextInfo info3 = testFactory.getContextInfo(ctxType);
        if (!info3.grContext()) {
            // Vulkan NexusPlayer bot fails here. Sigh.
            continue;
        }

        // Creating a context in a share group may fail, but should never crash.
        ContextInfo info4 = testFactory.getSharedContextInfo(info3.grContext());
        if (!info4.grContext()) {
            continue;
        }
        REPORTER_ASSERT(reporter, info3.grContext() != info4.grContext());
        REPORTER_ASSERT(reporter, info3.testContext() != info4.testContext());

        // Passing a different index should create a new (unique) context.
        ContextInfo info5 = testFactory.getSharedContextInfo(info3.grContext(), 1);
        REPORTER_ASSERT(reporter, info5.grContext());
        REPORTER_ASSERT(reporter, info5.testContext());
        REPORTER_ASSERT(reporter, info5.grContext() != info4.grContext());
        REPORTER_ASSERT(reporter, info5.testContext() != info4.testContext());
    }
}

DEF_GPUTEST(GrContextFactory_executorAndTaskGroup, reporter, options) {
    for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
        // Verify that contexts have a task group iff we supply an executor with context options
        GrContextOptions contextOptions = options;
        contextOptions.fExecutor = nullptr;
        GrContextFactory serialFactory(contextOptions);

        std::unique_ptr<SkExecutor> threadPool = SkExecutor::MakeFIFOThreadPool(1);
        contextOptions.fExecutor = threadPool.get();
        GrContextFactory threadedFactory(contextOptions);

        GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
        ContextInfo serialInfo = serialFactory.getContextInfo(ctxType);
        if (GrContext* serialContext = serialInfo.grContext()) {
            REPORTER_ASSERT(reporter, nullptr == serialContext->contextPriv().getTaskGroup());
        }

        ContextInfo threadedInfo = threadedFactory.getContextInfo(ctxType);
        if (GrContext* threadedContext = threadedInfo.grContext()) {
            REPORTER_ASSERT(reporter, nullptr != threadedContext->contextPriv().getTaskGroup());
        }
    }
}

DEF_GPUTEST_FOR_ALL_CONTEXTS(GrContextDump, reporter, ctxInfo) {
    // Ensure that GrContext::dump doesn't assert (which is possible, if the JSON code is wrong)
    SkString result = ctxInfo.grContext()->contextPriv().dump();
    REPORTER_ASSERT(reporter, !result.isEmpty());
}