xref: /aosp_15_r20/external/angle/src/tests/test_utils/MultiThreadSteps.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2022 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // MultiThreadSteps.cpp:
7*8975f5c5SAndroid Build Coastguard Worker //   Synchronization help for tests that use multiple threads.
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "MultiThreadSteps.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "angle_test_platform.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "gtest/gtest.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "util/EGLWindow.h"
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker namespace angle
16*8975f5c5SAndroid Build Coastguard Worker {
17*8975f5c5SAndroid Build Coastguard Worker 
RunLockStepThreads(EGLWindow * window,size_t threadCount,LockStepThreadFunc threadFuncs[])18*8975f5c5SAndroid Build Coastguard Worker void RunLockStepThreads(EGLWindow *window, size_t threadCount, LockStepThreadFunc threadFuncs[])
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker     constexpr EGLint kPBufferSize = 256;
21*8975f5c5SAndroid Build Coastguard Worker     RunLockStepThreadsWithSize(window, kPBufferSize, kPBufferSize, threadCount, threadFuncs);
22*8975f5c5SAndroid Build Coastguard Worker }
23*8975f5c5SAndroid Build Coastguard Worker 
RunLockStepThreadsWithSize(EGLWindow * window,EGLint width,EGLint height,size_t threadCount,LockStepThreadFunc threadFuncs[])24*8975f5c5SAndroid Build Coastguard Worker void RunLockStepThreadsWithSize(EGLWindow *window,
25*8975f5c5SAndroid Build Coastguard Worker                                 EGLint width,
26*8975f5c5SAndroid Build Coastguard Worker                                 EGLint height,
27*8975f5c5SAndroid Build Coastguard Worker                                 size_t threadCount,
28*8975f5c5SAndroid Build Coastguard Worker                                 LockStepThreadFunc threadFuncs[])
29*8975f5c5SAndroid Build Coastguard Worker {
30*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay dpy   = window->getDisplay();
31*8975f5c5SAndroid Build Coastguard Worker     EGLConfig config = window->getConfig();
32*8975f5c5SAndroid Build Coastguard Worker 
33*8975f5c5SAndroid Build Coastguard Worker     // Initialize the pbuffer and context
34*8975f5c5SAndroid Build Coastguard Worker     EGLint pbufferAttributes[] = {
35*8975f5c5SAndroid Build Coastguard Worker         EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE, EGL_NONE,
36*8975f5c5SAndroid Build Coastguard Worker     };
37*8975f5c5SAndroid Build Coastguard Worker 
38*8975f5c5SAndroid Build Coastguard Worker     std::vector<EGLSurface> surfaces(threadCount);
39*8975f5c5SAndroid Build Coastguard Worker     std::vector<EGLContext> contexts(threadCount);
40*8975f5c5SAndroid Build Coastguard Worker 
41*8975f5c5SAndroid Build Coastguard Worker     // Create N surfaces and shared contexts, one for each thread
42*8975f5c5SAndroid Build Coastguard Worker     for (size_t threadIndex = 0; threadIndex < threadCount; ++threadIndex)
43*8975f5c5SAndroid Build Coastguard Worker     {
44*8975f5c5SAndroid Build Coastguard Worker         surfaces[threadIndex] = eglCreatePbufferSurface(dpy, config, pbufferAttributes);
45*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(eglGetError(), EGL_SUCCESS);
46*8975f5c5SAndroid Build Coastguard Worker         EGLint extraAttributes[] = {EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE,
47*8975f5c5SAndroid Build Coastguard Worker                                     static_cast<EGLint>(threadIndex), EGL_NONE};
48*8975f5c5SAndroid Build Coastguard Worker         if (!IsEGLDisplayExtensionEnabled(dpy, "EGL_ANGLE_context_virtualization"))
49*8975f5c5SAndroid Build Coastguard Worker         {
50*8975f5c5SAndroid Build Coastguard Worker             extraAttributes[0] = EGL_NONE;
51*8975f5c5SAndroid Build Coastguard Worker         }
52*8975f5c5SAndroid Build Coastguard Worker         contexts[threadIndex] =
53*8975f5c5SAndroid Build Coastguard Worker             window->createContext(threadIndex == 0 ? EGL_NO_CONTEXT : contexts[0], extraAttributes);
54*8975f5c5SAndroid Build Coastguard Worker         EXPECT_NE(EGL_NO_CONTEXT, contexts[threadIndex]) << threadIndex;
55*8975f5c5SAndroid Build Coastguard Worker     }
56*8975f5c5SAndroid Build Coastguard Worker 
57*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::thread> threads(threadCount);
58*8975f5c5SAndroid Build Coastguard Worker 
59*8975f5c5SAndroid Build Coastguard Worker     // Run the threads
60*8975f5c5SAndroid Build Coastguard Worker     for (size_t threadIndex = 0; threadIndex < threadCount; ++threadIndex)
61*8975f5c5SAndroid Build Coastguard Worker     {
62*8975f5c5SAndroid Build Coastguard Worker         threads[threadIndex] = std::thread(std::move(threadFuncs[threadIndex]), dpy,
63*8975f5c5SAndroid Build Coastguard Worker                                            surfaces[threadIndex], contexts[threadIndex]);
64*8975f5c5SAndroid Build Coastguard Worker     }
65*8975f5c5SAndroid Build Coastguard Worker 
66*8975f5c5SAndroid Build Coastguard Worker     // Wait for them to finish
67*8975f5c5SAndroid Build Coastguard Worker     for (size_t threadIndex = 0; threadIndex < threadCount; ++threadIndex)
68*8975f5c5SAndroid Build Coastguard Worker     {
69*8975f5c5SAndroid Build Coastguard Worker         threads[threadIndex].join();
70*8975f5c5SAndroid Build Coastguard Worker 
71*8975f5c5SAndroid Build Coastguard Worker         // Clean up
72*8975f5c5SAndroid Build Coastguard Worker         eglDestroySurface(dpy, surfaces[threadIndex]);
73*8975f5c5SAndroid Build Coastguard Worker         eglDestroyContext(dpy, contexts[threadIndex]);
74*8975f5c5SAndroid Build Coastguard Worker     }
75*8975f5c5SAndroid Build Coastguard Worker }
76*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
77