// // Copyright 2022 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // MultiThreadSteps.cpp: // Synchronization help for tests that use multiple threads. #include "MultiThreadSteps.h" #include "angle_test_platform.h" #include "gtest/gtest.h" #include "util/EGLWindow.h" namespace angle { void RunLockStepThreads(EGLWindow *window, size_t threadCount, LockStepThreadFunc threadFuncs[]) { constexpr EGLint kPBufferSize = 256; RunLockStepThreadsWithSize(window, kPBufferSize, kPBufferSize, threadCount, threadFuncs); } void RunLockStepThreadsWithSize(EGLWindow *window, EGLint width, EGLint height, size_t threadCount, LockStepThreadFunc threadFuncs[]) { EGLDisplay dpy = window->getDisplay(); EGLConfig config = window->getConfig(); // Initialize the pbuffer and context EGLint pbufferAttributes[] = { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE, EGL_NONE, }; std::vector surfaces(threadCount); std::vector contexts(threadCount); // Create N surfaces and shared contexts, one for each thread for (size_t threadIndex = 0; threadIndex < threadCount; ++threadIndex) { surfaces[threadIndex] = eglCreatePbufferSurface(dpy, config, pbufferAttributes); EXPECT_EQ(eglGetError(), EGL_SUCCESS); EGLint extraAttributes[] = {EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE, static_cast(threadIndex), EGL_NONE}; if (!IsEGLDisplayExtensionEnabled(dpy, "EGL_ANGLE_context_virtualization")) { extraAttributes[0] = EGL_NONE; } contexts[threadIndex] = window->createContext(threadIndex == 0 ? EGL_NO_CONTEXT : contexts[0], extraAttributes); EXPECT_NE(EGL_NO_CONTEXT, contexts[threadIndex]) << threadIndex; } std::vector threads(threadCount); // Run the threads for (size_t threadIndex = 0; threadIndex < threadCount; ++threadIndex) { threads[threadIndex] = std::thread(std::move(threadFuncs[threadIndex]), dpy, surfaces[threadIndex], contexts[threadIndex]); } // Wait for them to finish for (size_t threadIndex = 0; threadIndex < threadCount; ++threadIndex) { threads[threadIndex].join(); // Clean up eglDestroySurface(dpy, surfaces[threadIndex]); eglDestroyContext(dpy, contexts[threadIndex]); } } } // namespace angle