Path: blob/main_old/src/tests/egl_tests/EGLProgramCacheControlTest.cpp
1693 views
//1// Copyright 2017 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// EGLProgramCacheControlTest:6// Unit tests for the EGL_ANGLE_program_cache_control extension.78#include "common/angleutils.h"9#include "test_utils/ANGLETest.h"10#include "test_utils/gl_raii.h"11#include "util/EGLWindow.h"1213using namespace angle;1415constexpr EGLint kEnabledCacheSize = 0x10000;16constexpr char kEGLExtName[] = "EGL_ANGLE_program_cache_control";1718void TestCacheProgram(PlatformMethods *platform,19const ProgramKeyType &key,20size_t programSize,21const uint8_t *programBytes);2223class EGLProgramCacheControlTest : public ANGLETest24{25public:26void onCache(const ProgramKeyType &key, size_t programSize, const uint8_t *programBytes)27{28mCachedKey = key;29mCachedBinary.assign(&programBytes[0], &programBytes[programSize]);30}3132protected:33EGLProgramCacheControlTest()34{35// Test flakiness was noticed when reusing displays.36forceNewDisplay();37setDeferContextInit(true);38setContextProgramCacheEnabled(true);39gDefaultPlatformMethods.cacheProgram = TestCacheProgram;40}4142void testSetUp() override43{44if (extensionAvailable())45{46EGLDisplay display = getEGLWindow()->getDisplay();47eglProgramCacheResizeANGLE(display, kEnabledCacheSize, EGL_PROGRAM_CACHE_RESIZE_ANGLE);48ASSERT_EGL_SUCCESS();49}5051ASSERT_TRUE(getEGLWindow()->initializeContext());52}5354void testTearDown() override { gDefaultPlatformMethods.cacheProgram = DefaultCacheProgram; }5556bool extensionAvailable()57{58EGLDisplay display = getEGLWindow()->getDisplay();59return IsEGLDisplayExtensionEnabled(display, kEGLExtName);60}6162bool programBinaryAvailable()63{64return (getClientMajorVersion() >= 3 || IsGLExtensionEnabled("GL_OES_get_program_binary"));65}6667ProgramKeyType mCachedKey;68std::vector<uint8_t> mCachedBinary;69};7071void TestCacheProgram(PlatformMethods *platform,72const ProgramKeyType &key,73size_t programSize,74const uint8_t *programBytes)75{76auto *testPlatformContext = static_cast<TestPlatformContext *>(platform->context);77auto *testCase =78reinterpret_cast<EGLProgramCacheControlTest *>(testPlatformContext->currentTest);79testCase->onCache(key, programSize, programBytes);80}8182// Tests error conditions of the APIs.83TEST_P(EGLProgramCacheControlTest, NegativeAPI)84{85ANGLE_SKIP_TEST_IF(!extensionAvailable());8687constexpr char kDefaultKey[] = "defaultMakeItLongEnough";88constexpr char kDefaultBinary[] = "defaultMakeItLongEnough";89constexpr EGLint kDefaultKeySize = static_cast<EGLint>(ArraySize(kDefaultKey));90constexpr EGLint kDefaultBinarySize = static_cast<EGLint>(ArraySize(kDefaultBinary));9192// Test that passing an invalid display to the entry point methods fails.93eglProgramCacheGetAttribANGLE(EGL_NO_DISPLAY, EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE);94EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);9596eglProgramCachePopulateANGLE(EGL_NO_DISPLAY, kDefaultKey, kDefaultKeySize, kDefaultBinary,97kDefaultBinarySize);98EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);99100EGLint tempKeySize = 0;101EGLint tempBinarySize = 0;102eglProgramCacheQueryANGLE(EGL_NO_DISPLAY, 0, nullptr, &tempKeySize, nullptr, &tempBinarySize);103EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);104105eglProgramCacheResizeANGLE(EGL_NO_DISPLAY, 0, EGL_PROGRAM_CACHE_TRIM_ANGLE);106EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);107108// Test querying properties with bad parameters.109EGLDisplay display = getEGLWindow()->getDisplay();110eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_RESIZE_ANGLE);111EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);112113// Test populating with invalid parameters.114EGLint keySize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE);115EXPECT_GT(kDefaultKeySize, keySize);116eglProgramCachePopulateANGLE(display, kDefaultKey, keySize + 1, kDefaultBinary,117kDefaultBinarySize);118EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);119120eglProgramCachePopulateANGLE(display, kDefaultKey, keySize, kDefaultBinary, -1);121EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);122123eglProgramCachePopulateANGLE(display, nullptr, keySize, kDefaultBinary, kDefaultBinarySize);124EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);125126eglProgramCachePopulateANGLE(display, kDefaultKey, keySize, nullptr, kDefaultBinarySize);127EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);128129// Test querying cache entries with invalid parameters.130eglProgramCachePopulateANGLE(display, kDefaultKey, keySize, kDefaultBinary, kDefaultBinarySize);131ASSERT_EGL_SUCCESS();132133EGLint cacheSize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_SIZE_ANGLE);134ASSERT_EQ(1, cacheSize);135136eglProgramCacheQueryANGLE(display, -1, nullptr, &tempKeySize, nullptr, &tempBinarySize);137EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);138139eglProgramCacheQueryANGLE(display, 1, nullptr, &tempKeySize, nullptr, &tempBinarySize);140EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);141142eglProgramCacheQueryANGLE(display, 0, nullptr, nullptr, nullptr, &tempBinarySize);143EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);144145eglProgramCacheQueryANGLE(display, 0, nullptr, &tempKeySize, nullptr, nullptr);146EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);147148eglProgramCacheQueryANGLE(display, 0, nullptr, &tempKeySize, nullptr, &tempBinarySize);149ASSERT_EGL_SUCCESS();150ASSERT_EQ(keySize, tempKeySize);151ASSERT_EQ(kDefaultBinarySize, tempBinarySize);152153std::vector<uint8_t> tempKey(tempKeySize + 5);154std::vector<uint8_t> tempBinary(tempBinarySize + 5);155156tempKeySize--;157158eglProgramCacheQueryANGLE(display, 0, tempKey.data(), &tempKeySize, tempBinary.data(),159&tempBinarySize);160EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);161162tempKeySize++;163tempBinarySize--;164165eglProgramCacheQueryANGLE(display, 0, tempKey.data(), &tempKeySize, tempBinary.data(),166&tempBinarySize);167EXPECT_EGL_ERROR(EGL_BAD_ACCESS);168169// Test resizing with invalid parameters.170eglProgramCacheResizeANGLE(display, -1, EGL_PROGRAM_CACHE_TRIM_ANGLE);171EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);172173eglProgramCacheResizeANGLE(display, 0, EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE);174EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);175}176177// Tests a basic use case.178TEST_P(EGLProgramCacheControlTest, SaveAndReload)179{180ANGLE_SKIP_TEST_IF(!extensionAvailable() || !programBinaryAvailable());181182constexpr char kVS[] = "attribute vec4 position; void main() { gl_Position = position; }";183constexpr char kFS[] = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";184185// Link a program, which will miss the cache.186{187glClearColor(0.0f, 1.0f, 0.0f, 1.0f);188glClear(GL_COLOR_BUFFER_BIT);189EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);190191ANGLE_GL_PROGRAM(program, kVS, kFS);192drawQuad(program, "position", 0.5f);193EXPECT_GL_NO_ERROR();194EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);195}196197EGLDisplay display = getEGLWindow()->getDisplay();198EGLint cacheSize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_SIZE_ANGLE);199EXPECT_EQ(1, cacheSize);200201EGLint keySize = 0;202EGLint binarySize = 0;203eglProgramCacheQueryANGLE(display, 0, nullptr, &keySize, nullptr, &binarySize);204EXPECT_EQ(static_cast<EGLint>(mCachedKey.size()), keySize);205ASSERT_EGL_SUCCESS();206207ProgramKeyType keyBuffer;208std::vector<uint8_t> binaryBuffer(binarySize);209eglProgramCacheQueryANGLE(display, 0, keyBuffer.data(), &keySize, binaryBuffer.data(),210&binarySize);211ASSERT_EGL_SUCCESS();212213EXPECT_EQ(mCachedKey, keyBuffer);214EXPECT_EQ(mCachedBinary, binaryBuffer);215216// Restart EGL and GL.217recreateTestFixture();218219// Warm up the cache.220EGLint newCacheSize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_SIZE_ANGLE);221EXPECT_EQ(0, newCacheSize);222eglProgramCachePopulateANGLE(display, keyBuffer.data(), keySize, binaryBuffer.data(),223binarySize);224225mCachedBinary.clear();226227// Link a program, which will hit the cache.228{229glClearColor(0.0f, 1.0f, 0.0f, 1.0f);230glClear(GL_COLOR_BUFFER_BIT);231EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);232233ANGLE_GL_PROGRAM(program, kVS, kFS);234drawQuad(program, "position", 0.5f);235EXPECT_GL_NO_ERROR();236EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);237}238239// Verify no new shader was compiled.240EXPECT_TRUE(mCachedBinary.empty());241}242243// Tests that trying to link a program without correct shaders doesn't buggily call the cache.244TEST_P(EGLProgramCacheControlTest, LinkProgramWithBadShaders)245{246ANGLE_SKIP_TEST_IF(!extensionAvailable());247248GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);249250GLuint program = glCreateProgram();251glAttachShader(program, shader);252glLinkProgram(program);253254GLint linkStatus = 0;255glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);256EXPECT_GL_FALSE(linkStatus);257EXPECT_GL_NO_ERROR();258259glDeleteShader(shader);260glDeleteProgram(program);261}262263GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLProgramCacheControlTest);264ANGLE_INSTANTIATE_TEST(EGLProgramCacheControlTest,265ES2_D3D9(),266ES2_D3D11(),267ES2_OPENGL(),268ES2_VULKAN());269270271