// // 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 #include #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());