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 "include/core/SkExecutor.h"
9 #include "include/core/SkTypes.h"
10 #include "include/gpu/ganesh/GrContextOptions.h"
11 #include "include/gpu/ganesh/GrDirectContext.h"
12 #include "src/gpu/ganesh/GrDirectContextPriv.h"
13 #include "tests/CtsEnforcement.h"
14 #include "tests/Test.h"
15 #include "tools/gpu/ContextType.h"
16 #include "tools/gpu/FenceSync.h"
17
18 #include <memory>
19
20 using namespace sk_gpu_test;
21
DEF_GANESH_TEST(GrContextFactory_abandon,reporter,options,CtsEnforcement::kNever)22 DEF_GANESH_TEST(GrContextFactory_abandon, reporter, options, CtsEnforcement::kNever) {
23 for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
24 GrContextFactory testFactory(options);
25 skgpu::ContextType ctxType = static_cast<skgpu::ContextType>(i);
26 ContextInfo info1 = testFactory.getContextInfo(ctxType);
27 if (!info1.directContext()) {
28 continue;
29 }
30 REPORTER_ASSERT(reporter, info1.testContext());
31 // Ref for comparison. The API does not explicitly say that this stays alive.
32 info1.directContext()->ref();
33 testFactory.abandonContexts();
34
35 // Test that we get different context after abandon.
36 ContextInfo info2 = testFactory.getContextInfo(ctxType);
37 REPORTER_ASSERT(reporter, info2.directContext());
38 REPORTER_ASSERT(reporter, info2.testContext());
39
40 REPORTER_ASSERT(reporter, info1.directContext() != info2.directContext());
41 // The GL context should also change, but it also could get the same address.
42
43 info1.directContext()->unref();
44 }
45 }
46
DEF_GANESH_TEST(GrContextFactory_sharedContexts,reporter,options,CtsEnforcement::kApiLevel_T)47 DEF_GANESH_TEST(GrContextFactory_sharedContexts, reporter, options, CtsEnforcement::kApiLevel_T) {
48 for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
49 GrContextFactory testFactory(options);
50 skgpu::ContextType ctxType = static_cast<skgpu::ContextType>(i);
51 ContextInfo info1 = testFactory.getContextInfo(ctxType);
52 if (!info1.directContext()) {
53 continue;
54 }
55
56 // Ref for passing in. The API does not explicitly say that this stays alive.
57 info1.directContext()->ref();
58 testFactory.abandonContexts();
59
60 // Test that creating a context in a share group with an abandoned context fails.
61 ContextInfo info2 = testFactory.getSharedContextInfo(info1.directContext());
62 REPORTER_ASSERT(reporter, !info2.directContext());
63 info1.directContext()->unref();
64
65 // Create a new base context
66 ContextInfo info3 = testFactory.getContextInfo(ctxType);
67
68 // Creating a context in a share group may fail, but should never crash.
69 ContextInfo info4 = testFactory.getSharedContextInfo(info3.directContext());
70 if (!info4.directContext()) {
71 continue;
72 }
73 REPORTER_ASSERT(reporter, info3.directContext() != info4.directContext());
74 REPORTER_ASSERT(reporter, info3.testContext() != info4.testContext());
75
76 // Passing a different index should create a new (unique) context.
77 ContextInfo info5 = testFactory.getSharedContextInfo(info3.directContext(), 1);
78 REPORTER_ASSERT(reporter, info5.directContext());
79 REPORTER_ASSERT(reporter, info5.testContext());
80 REPORTER_ASSERT(reporter, info5.directContext() != info4.directContext());
81 REPORTER_ASSERT(reporter, info5.testContext() != info4.testContext());
82 }
83 }
84
DEF_GANESH_TEST(GrContextFactory_executorAndTaskGroup,reporter,options,CtsEnforcement::kNever)85 DEF_GANESH_TEST(GrContextFactory_executorAndTaskGroup, reporter, options, CtsEnforcement::kNever) {
86 for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
87 // Verify that contexts have a task group iff we supply an executor with context options
88 GrContextOptions contextOptions = options;
89 contextOptions.fExecutor = nullptr;
90 GrContextFactory serialFactory(contextOptions);
91
92 std::unique_ptr<SkExecutor> threadPool = SkExecutor::MakeFIFOThreadPool(1);
93 contextOptions.fExecutor = threadPool.get();
94 GrContextFactory threadedFactory(contextOptions);
95
96 skgpu::ContextType ctxType = static_cast<skgpu::ContextType>(i);
97 ContextInfo serialInfo = serialFactory.getContextInfo(ctxType);
98 if (auto serialContext = serialInfo.directContext()) {
99 REPORTER_ASSERT(reporter, nullptr == serialContext->priv().getTaskGroup());
100 }
101
102 ContextInfo threadedInfo = threadedFactory.getContextInfo(ctxType);
103 if (auto threadedContext = threadedInfo.directContext()) {
104 REPORTER_ASSERT(reporter, nullptr != threadedContext->priv().getTaskGroup());
105 }
106 }
107 }
108
109 #ifdef SK_ENABLE_DUMP_GPU
DEF_GANESH_TEST_FOR_ALL_CONTEXTS(GrContextDump,reporter,ctxInfo,CtsEnforcement::kNever)110 DEF_GANESH_TEST_FOR_ALL_CONTEXTS(GrContextDump, reporter, ctxInfo, CtsEnforcement::kNever) {
111 // Ensure that GrDirectContext::dump doesn't assert (which is possible, if the JSON code
112 // is wrong)
113 SkString result = ctxInfo.directContext()->dump();
114 REPORTER_ASSERT(reporter, !result.isEmpty());
115 }
116 #endif
117