xref: /aosp_15_r20/external/skia/tests/GrContextFactoryTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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