1 /*
2 * Copyright 2011 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 #include "SkTypes.h"
9
10 #if SK_SUPPORT_GPU
11
12 #include "GrContextFactory.h"
13 #include "GrContextPriv.h"
14 #include "GrCaps.h"
15 #include "SkExecutor.h"
16 #include "Test.h"
17
18 using namespace sk_gpu_test;
19
DEF_GPUTEST(GrContextFactory_NVPRContextOptionHasPathRenderingSupport,reporter,options)20 DEF_GPUTEST(GrContextFactory_NVPRContextOptionHasPathRenderingSupport, reporter, options) {
21 // Test that if NVPR is requested, the context always has path rendering
22 // or the context creation fails.
23 for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
24 GrContextFactory testFactory(options);
25 // Test that if NVPR is possible, caps are in sync.
26 GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
27 GrContext* context = testFactory.get(ctxType,
28 GrContextFactory::ContextOverrides::kRequireNVPRSupport);
29 if (!context) {
30 continue;
31 }
32 REPORTER_ASSERT(
33 reporter,
34 context->caps()->shaderCaps()->pathRenderingSupport());
35 }
36 }
37
DEF_GPUTEST(GrContextFactory_NoPathRenderingIfNVPRDisabled,reporter,options)38 DEF_GPUTEST(GrContextFactory_NoPathRenderingIfNVPRDisabled, reporter, options) {
39 // Test that if NVPR is explicitly disabled, the context has no path rendering support.
40
41 for (int i = 0; i <= GrContextFactory::kLastContextType; ++i) {
42 GrContextFactory testFactory(options);
43 GrContextFactory::ContextType ctxType = (GrContextFactory::ContextType)i;
44 GrContext* context =
45 testFactory.get(ctxType, GrContextFactory::ContextOverrides::kDisableNVPR);
46 if (context) {
47 REPORTER_ASSERT(
48 reporter,
49 !context->caps()->shaderCaps()->pathRenderingSupport());
50 }
51 }
52 }
53
DEF_GPUTEST(GrContextFactory_RequiredSRGBSupport,reporter,options)54 DEF_GPUTEST(GrContextFactory_RequiredSRGBSupport, reporter, options) {
55 // Test that if sRGB support is requested, the context always has that capability
56 // or the context creation fails. Also test that if the creation fails, a context
57 // created without that flag would not have had sRGB support.
58 for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
59 GrContextFactory testFactory(options);
60 // Test that if sRGB is requested, caps are in sync.
61 GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
62 GrContext* context =
63 testFactory.get(ctxType, GrContextFactory::ContextOverrides::kRequireSRGBSupport);
64
65 if (context) {
66 REPORTER_ASSERT(reporter, context->caps()->srgbSupport());
67 } else {
68 context = testFactory.get(ctxType);
69 if (context) {
70 REPORTER_ASSERT(reporter, !context->caps()->srgbSupport());
71 }
72 }
73 }
74 }
75
DEF_GPUTEST(GrContextFactory_abandon,reporter,options)76 DEF_GPUTEST(GrContextFactory_abandon, reporter, options) {
77 for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
78 GrContextFactory testFactory(options);
79 GrContextFactory::ContextType ctxType = (GrContextFactory::ContextType) i;
80 ContextInfo info1 = testFactory.getContextInfo(ctxType);
81 if (!info1.grContext()) {
82 continue;
83 }
84 REPORTER_ASSERT(reporter, info1.testContext());
85 // Ref for comparison. The API does not explicitly say that this stays alive.
86 info1.grContext()->ref();
87 testFactory.abandonContexts();
88
89 // Test that we get different context after abandon.
90 ContextInfo info2 = testFactory.getContextInfo(ctxType);
91 REPORTER_ASSERT(reporter, info2.grContext());
92 REPORTER_ASSERT(reporter, info2.testContext());
93
94 REPORTER_ASSERT(reporter, info1.grContext() != info2.grContext());
95 // The GL context should also change, but it also could get the same address.
96
97 info1.grContext()->unref();
98 }
99 }
100
DEF_GPUTEST(GrContextFactory_sharedContexts,reporter,options)101 DEF_GPUTEST(GrContextFactory_sharedContexts, reporter, options) {
102 for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
103 GrContextFactory testFactory(options);
104 GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
105 ContextInfo info1 = testFactory.getContextInfo(ctxType);
106 if (!info1.grContext()) {
107 continue;
108 }
109
110 // Ref for passing in. The API does not explicitly say that this stays alive.
111 info1.grContext()->ref();
112 testFactory.abandonContexts();
113
114 // Test that creating a context in a share group with an abandoned context fails.
115 ContextInfo info2 = testFactory.getSharedContextInfo(info1.grContext());
116 REPORTER_ASSERT(reporter, !info2.grContext());
117 info1.grContext()->unref();
118
119 // Create a new base context
120 ContextInfo info3 = testFactory.getContextInfo(ctxType);
121 if (!info3.grContext()) {
122 // Vulkan NexusPlayer bot fails here. Sigh.
123 continue;
124 }
125
126 // Creating a context in a share group may fail, but should never crash.
127 ContextInfo info4 = testFactory.getSharedContextInfo(info3.grContext());
128 if (!info4.grContext()) {
129 continue;
130 }
131 REPORTER_ASSERT(reporter, info3.grContext() != info4.grContext());
132 REPORTER_ASSERT(reporter, info3.testContext() != info4.testContext());
133
134 // Passing a different index should create a new (unique) context.
135 ContextInfo info5 = testFactory.getSharedContextInfo(info3.grContext(), 1);
136 REPORTER_ASSERT(reporter, info5.grContext());
137 REPORTER_ASSERT(reporter, info5.testContext());
138 REPORTER_ASSERT(reporter, info5.grContext() != info4.grContext());
139 REPORTER_ASSERT(reporter, info5.testContext() != info4.testContext());
140 }
141 }
142
DEF_GPUTEST(GrContextFactory_executorAndTaskGroup,reporter,options)143 DEF_GPUTEST(GrContextFactory_executorAndTaskGroup, reporter, options) {
144 for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) {
145 // Verify that contexts have a task group iff we supply an executor with context options
146 GrContextOptions contextOptions = options;
147 contextOptions.fExecutor = nullptr;
148 GrContextFactory serialFactory(contextOptions);
149
150 std::unique_ptr<SkExecutor> threadPool = SkExecutor::MakeFIFOThreadPool(1);
151 contextOptions.fExecutor = threadPool.get();
152 GrContextFactory threadedFactory(contextOptions);
153
154 GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i);
155 ContextInfo serialInfo = serialFactory.getContextInfo(ctxType);
156 if (GrContext* serialContext = serialInfo.grContext()) {
157 REPORTER_ASSERT(reporter, nullptr == serialContext->contextPriv().getTaskGroup());
158 }
159
160 ContextInfo threadedInfo = threadedFactory.getContextInfo(ctxType);
161 if (GrContext* threadedContext = threadedInfo.grContext()) {
162 REPORTER_ASSERT(reporter, nullptr != threadedContext->contextPriv().getTaskGroup());
163 }
164 }
165 }
166
DEF_GPUTEST_FOR_ALL_CONTEXTS(GrContextDump,reporter,ctxInfo)167 DEF_GPUTEST_FOR_ALL_CONTEXTS(GrContextDump, reporter, ctxInfo) {
168 // Ensure that GrContext::dump doesn't assert (which is possible, if the JSON code is wrong)
169 SkString result = ctxInfo.grContext()->dump();
170 REPORTER_ASSERT(reporter, !result.isEmpty());
171 }
172
173 #endif
174