Path: blob/main_old/src/tests/egl_tests/EGLBlobCacheTest.cpp
1693 views
//1// Copyright 2018 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// EGLBlobCacheTest:6// Unit tests for the EGL_ANDROID_blob_cache extension.78// Must be included first to prevent errors with "None".9#include "test_utils/ANGLETest.h"1011#include <map>12#include <vector>1314#include "common/PackedEnums.h"15#include "common/angleutils.h"16#include "test_utils/gl_raii.h"17#include "util/EGLWindow.h"1819using namespace angle;2021constexpr char kEGLExtName[] = "EGL_ANDROID_blob_cache";2223enum class CacheOpResult24{25SetSuccess,26GetNotFound,27GetMemoryTooSmall,28GetSuccess,29ValueNotSet,30EnumCount31};3233angle::PackedEnumMap<CacheOpResult, std::string> kCacheOpToString = {34{CacheOpResult::SetSuccess, "SetSuccess"},35{CacheOpResult::GetNotFound, "GetNotFound"},36{CacheOpResult::GetMemoryTooSmall, "GetMemoryTooSmall"},37{CacheOpResult::GetSuccess, "GetSuccess"},38{CacheOpResult::ValueNotSet, "ValueNotSet"},39};4041std::ostream &operator<<(std::ostream &os, CacheOpResult result)42{43return os << kCacheOpToString[result];44}4546namespace47{48std::map<std::vector<uint8_t>, std::vector<uint8_t>> gApplicationCache;49CacheOpResult gLastCacheOpResult = CacheOpResult::ValueNotSet;5051void SetBlob(const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize)52{53std::vector<uint8_t> keyVec(keySize);54memcpy(keyVec.data(), key, keySize);5556std::vector<uint8_t> valueVec(valueSize);57memcpy(valueVec.data(), value, valueSize);5859gApplicationCache[keyVec] = valueVec;6061gLastCacheOpResult = CacheOpResult::SetSuccess;62}6364EGLsizeiANDROID GetBlob(const void *key,65EGLsizeiANDROID keySize,66void *value,67EGLsizeiANDROID valueSize)68{69std::vector<uint8_t> keyVec(keySize);70memcpy(keyVec.data(), key, keySize);7172auto entry = gApplicationCache.find(keyVec);73if (entry == gApplicationCache.end())74{75gLastCacheOpResult = CacheOpResult::GetNotFound;76return 0;77}7879if (entry->second.size() <= static_cast<size_t>(valueSize))80{81memcpy(value, entry->second.data(), entry->second.size());82gLastCacheOpResult = CacheOpResult::GetSuccess;83}84else85{86gLastCacheOpResult = CacheOpResult::GetMemoryTooSmall;87}8889return entry->second.size();90}91} // anonymous namespace9293class EGLBlobCacheTest : public ANGLETest94{95protected:96EGLBlobCacheTest() : mHasBlobCache(false)97{98// Force disply caching off. Blob cache functions require it.99forceNewDisplay();100}101102void testSetUp() override103{104EGLDisplay display = getEGLWindow()->getDisplay();105mHasBlobCache = IsEGLDisplayExtensionEnabled(display, kEGLExtName);106}107108void testTearDown() override { gApplicationCache.clear(); }109110bool programBinaryAvailable() { return IsGLExtensionEnabled("GL_OES_get_program_binary"); }111112bool mHasBlobCache;113};114115// Makes sure the extension exists and works116TEST_P(EGLBlobCacheTest, Functional)117{118EGLDisplay display = getEGLWindow()->getDisplay();119120EXPECT_TRUE(mHasBlobCache);121eglSetBlobCacheFuncsANDROID(display, SetBlob, GetBlob);122ASSERT_EGL_SUCCESS();123124constexpr char kVertexShaderSrc[] = R"(attribute vec4 aTest;125attribute vec2 aPosition;126varying vec4 vTest;127void main()128{129vTest = aTest;130gl_Position = vec4(aPosition, 0.0, 1.0);131gl_PointSize = 1.0;132})";133134constexpr char kFragmentShaderSrc[] = R"(precision mediump float;135varying vec4 vTest;136void main()137{138gl_FragColor = vTest;139})";140141constexpr char kVertexShaderSrc2[] = R"(attribute vec4 aTest;142attribute vec2 aPosition;143varying vec4 vTest;144void main()145{146vTest = aTest;147gl_Position = vec4(aPosition, 1.0, 1.0);148gl_PointSize = 1.0;149})";150151constexpr char kFragmentShaderSrc2[] = R"(precision mediump float;152varying vec4 vTest;153void main()154{155gl_FragColor = vTest - vec4(0.0, 1.0, 0.0, 0.0);156})";157158// Compile a shader so it puts something in the cache159if (programBinaryAvailable())160{161ANGLE_GL_PROGRAM(program, kVertexShaderSrc, kFragmentShaderSrc);162EXPECT_EQ(CacheOpResult::SetSuccess, gLastCacheOpResult);163gLastCacheOpResult = CacheOpResult::ValueNotSet;164165// Compile the same shader again, so it would try to retrieve it from the cache166program.makeRaster(kVertexShaderSrc, kFragmentShaderSrc);167ASSERT_TRUE(program.valid());168EXPECT_EQ(CacheOpResult::GetSuccess, gLastCacheOpResult);169gLastCacheOpResult = CacheOpResult::ValueNotSet;170171// Compile another shader, which should create a new entry172program.makeRaster(kVertexShaderSrc2, kFragmentShaderSrc2);173ASSERT_TRUE(program.valid());174EXPECT_EQ(CacheOpResult::SetSuccess, gLastCacheOpResult);175gLastCacheOpResult = CacheOpResult::ValueNotSet;176177// Compile the first shader again, which should still reside in the cache178program.makeRaster(kVertexShaderSrc, kFragmentShaderSrc);179ASSERT_TRUE(program.valid());180EXPECT_EQ(CacheOpResult::GetSuccess, gLastCacheOpResult);181gLastCacheOpResult = CacheOpResult::ValueNotSet;182}183}184185// Tests error conditions of the APIs.186TEST_P(EGLBlobCacheTest, NegativeAPI)187{188EXPECT_TRUE(mHasBlobCache);189190// Test bad display191eglSetBlobCacheFuncsANDROID(EGL_NO_DISPLAY, nullptr, nullptr);192EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);193194eglSetBlobCacheFuncsANDROID(EGL_NO_DISPLAY, SetBlob, GetBlob);195EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);196197EGLDisplay display = getEGLWindow()->getDisplay();198199// Test bad arguments200eglSetBlobCacheFuncsANDROID(display, nullptr, nullptr);201EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);202203eglSetBlobCacheFuncsANDROID(display, SetBlob, nullptr);204EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);205206eglSetBlobCacheFuncsANDROID(display, nullptr, GetBlob);207EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);208209// Set the arguments once and test setting them again (which should fail)210eglSetBlobCacheFuncsANDROID(display, SetBlob, GetBlob);211ASSERT_EGL_SUCCESS();212213eglSetBlobCacheFuncsANDROID(display, SetBlob, GetBlob);214EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);215216// Try again with bad parameters217eglSetBlobCacheFuncsANDROID(EGL_NO_DISPLAY, nullptr, nullptr);218EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);219220eglSetBlobCacheFuncsANDROID(display, nullptr, nullptr);221EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);222223eglSetBlobCacheFuncsANDROID(display, SetBlob, nullptr);224EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);225226eglSetBlobCacheFuncsANDROID(display, nullptr, GetBlob);227EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);228}229230// Regression test for including the fragment output locatins in the program key.231// http://anglebug.com/4535232TEST_P(EGLBlobCacheTest, FragmentOutputLocationKey)233{234ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_blend_func_extended") ||235getClientMajorVersion() < 3);236237EGLDisplay display = getEGLWindow()->getDisplay();238239EXPECT_TRUE(mHasBlobCache);240eglSetBlobCacheFuncsANDROID(display, SetBlob, GetBlob);241ASSERT_EGL_SUCCESS();242243// Compile a shader so it puts something in the cache244if (programBinaryAvailable())245{246constexpr char kFragmentShaderSrc[] = R"(#version 300 es247#extension GL_EXT_blend_func_extended : require248precision mediump float;249uniform vec4 src;250uniform vec4 src1;251out vec4 FragData;252out vec4 SecondaryFragData;253void main() {254FragData = src;255SecondaryFragData = src1;256})";257258constexpr char kVertexShaderSrc[] = R"(#version 300 es259in vec4 position;260void main() {261gl_Position = position;262})";263264GLuint program = CompileProgram(kVertexShaderSrc, kFragmentShaderSrc, [](GLuint p) {265glBindFragDataLocationEXT(p, 0, "FragData[0]");266glBindFragDataLocationIndexedEXT(p, 0, 1, "SecondaryFragData[0]");267});268ASSERT_NE(0u, program);269EXPECT_EQ(CacheOpResult::SetSuccess, gLastCacheOpResult);270gLastCacheOpResult = CacheOpResult::ValueNotSet;271272// Re-link the program with different fragment output bindings273program = CompileProgram(kVertexShaderSrc, kFragmentShaderSrc, [](GLuint p) {274glBindFragDataLocationEXT(p, 0, "FragData");275glBindFragDataLocationIndexedEXT(p, 0, 1, "SecondaryFragData");276});277ASSERT_NE(0u, program);278EXPECT_EQ(CacheOpResult::SetSuccess, gLastCacheOpResult);279gLastCacheOpResult = CacheOpResult::ValueNotSet;280}281}282283ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(EGLBlobCacheTest);284285286