| // | |
| // 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. | |
| // | |
| // EGLPowerPreferenceTest.cpp: | |
| // Checks the implementation of EGL_ANGLE_power_preference. | |
| // | |
| #include <gtest/gtest.h> | |
| #include <tuple> | |
| #include "common/debug.h" | |
| #include "common/string_utils.h" | |
| #include "gpu_info_util/SystemInfo.h" | |
| #include "test_utils/ANGLETest.h" | |
| #include "test_utils/angle_test_platform.h" | |
| #include "test_utils/system_info_util.h" | |
| #include "util/OSWindow.h" | |
| using namespace angle; | |
| class EGLPowerPreferenceTest : public ANGLETest<> | |
| { | |
| public: | |
| void testSetUp() override { (void)GetSystemInfo(&mSystemInfo); } | |
| protected: | |
| auto getGpuIdParts(size_t gpuIndex) const | |
| { | |
| uint64_t deviceId = mSystemInfo.gpus[gpuIndex].systemDeviceId; | |
| return std::make_tuple(GetSystemDeviceIdHighPart(deviceId), | |
| GetSystemDeviceIdLowPart(deviceId)); | |
| } | |
| EGLDisplay getDisplay() const { return getEGLWindow()->getDisplay(); } | |
| SystemInfo mSystemInfo; | |
| }; | |
| TEST_P(EGLPowerPreferenceTest, ForceGPUSwitch) | |
| { | |
| ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(getDisplay(), "EGL_ANGLE_power_preference")); | |
| size_t lowPower = FindLowPowerGPU(mSystemInfo); | |
| size_t highPower = FindHighPowerGPU(mSystemInfo); | |
| size_t initialGPU = FindActiveOpenGLGPU(mSystemInfo); | |
| ASSERT_TRUE(lowPower == initialGPU || highPower == initialGPU); | |
| EGLint hi = 0; | |
| EGLint lo = 0; | |
| for (int i = 0; i < 5; ++i) | |
| { | |
| std::tie(hi, lo) = getGpuIdParts(lowPower); | |
| eglForceGPUSwitchANGLE(getDisplay(), hi, lo); | |
| EXPECT_EQ(lowPower, FindActiveOpenGLGPU(mSystemInfo)); | |
| std::tie(hi, lo) = getGpuIdParts(highPower); | |
| eglForceGPUSwitchANGLE(getDisplay(), hi, lo); | |
| EXPECT_EQ(highPower, FindActiveOpenGLGPU(mSystemInfo)); | |
| } | |
| } | |
| TEST_P(EGLPowerPreferenceTest, HandleGPUSwitchAfterForceGPUSwitch) | |
| { | |
| ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(getDisplay(), "EGL_ANGLE_power_preference")); | |
| size_t initialGPU = FindActiveOpenGLGPU(mSystemInfo); | |
| size_t changedGPU = FindLowPowerGPU(mSystemInfo); | |
| // On all platforms the extension is implemented (e.g. CGL): If we start with integrated, and | |
| // force DGPU, we cannot eglHandleGPUSwitchANGLE() from DGPU to integrated. | |
| // eglHandleGPUSwitchANGLE() will switch to the "default", which will be DGPU. | |
| // If we start with DGPU and switch to integrated, we *can* eglHandleGPUSwitchANGLE() back | |
| // to the default, DGPU. | |
| ANGLE_SKIP_TEST_IF(initialGPU == changedGPU); | |
| EGLint hi = 0; | |
| EGLint lo = 0; | |
| for (int i = 0; i < 5; ++i) | |
| { | |
| std::tie(hi, lo) = getGpuIdParts(changedGPU); | |
| eglForceGPUSwitchANGLE(getDisplay(), hi, lo); | |
| ASSERT_EQ(changedGPU, FindActiveOpenGLGPU(mSystemInfo)); | |
| eglHandleGPUSwitchANGLE(getDisplay()); | |
| ASSERT_EQ(initialGPU, FindActiveOpenGLGPU(mSystemInfo)); | |
| } | |
| } | |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPowerPreferenceTest); | |
| ANGLE_INSTANTIATE_TEST(EGLPowerPreferenceTest, ES2_OPENGL(), ES3_OPENGL()); |