xref: /aosp_15_r20/external/angle/src/tests/egl_tests/EGLProgramCacheControlTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2017 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // EGLProgramCacheControlTest:
7*8975f5c5SAndroid Build Coastguard Worker //   Unit tests for the EGL_ANGLE_program_cache_control extension.
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "common/angleutils.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "util/EGLWindow.h"
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker constexpr EGLint kEnabledCacheSize = 0x10000;
17*8975f5c5SAndroid Build Coastguard Worker constexpr char kEGLExtName[]       = "EGL_ANGLE_program_cache_control";
18*8975f5c5SAndroid Build Coastguard Worker 
19*8975f5c5SAndroid Build Coastguard Worker void TestCacheProgram(PlatformMethods *platform,
20*8975f5c5SAndroid Build Coastguard Worker                       const ProgramKeyType &key,
21*8975f5c5SAndroid Build Coastguard Worker                       size_t programSize,
22*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t *programBytes);
23*8975f5c5SAndroid Build Coastguard Worker 
24*8975f5c5SAndroid Build Coastguard Worker class EGLProgramCacheControlTest : public ANGLETest<>
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker   public:
onCache(const ProgramKeyType & key,size_t programSize,const uint8_t * programBytes)27*8975f5c5SAndroid Build Coastguard Worker     void onCache(const ProgramKeyType &key, size_t programSize, const uint8_t *programBytes)
28*8975f5c5SAndroid Build Coastguard Worker     {
29*8975f5c5SAndroid Build Coastguard Worker         mCachedKey = key;
30*8975f5c5SAndroid Build Coastguard Worker         mCachedBinary.assign(&programBytes[0], &programBytes[programSize]);
31*8975f5c5SAndroid Build Coastguard Worker     }
32*8975f5c5SAndroid Build Coastguard Worker 
33*8975f5c5SAndroid Build Coastguard Worker   protected:
EGLProgramCacheControlTest()34*8975f5c5SAndroid Build Coastguard Worker     EGLProgramCacheControlTest()
35*8975f5c5SAndroid Build Coastguard Worker     {
36*8975f5c5SAndroid Build Coastguard Worker         // Test flakiness was noticed when reusing displays.
37*8975f5c5SAndroid Build Coastguard Worker         forceNewDisplay();
38*8975f5c5SAndroid Build Coastguard Worker         setDeferContextInit(true);
39*8975f5c5SAndroid Build Coastguard Worker         setContextProgramCacheEnabled(true);
40*8975f5c5SAndroid Build Coastguard Worker         gDefaultPlatformMethods.cacheProgram = TestCacheProgram;
41*8975f5c5SAndroid Build Coastguard Worker     }
42*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()43*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
44*8975f5c5SAndroid Build Coastguard Worker     {
45*8975f5c5SAndroid Build Coastguard Worker         if (extensionAvailable())
46*8975f5c5SAndroid Build Coastguard Worker         {
47*8975f5c5SAndroid Build Coastguard Worker             EGLDisplay display = getEGLWindow()->getDisplay();
48*8975f5c5SAndroid Build Coastguard Worker             eglProgramCacheResizeANGLE(display, kEnabledCacheSize, EGL_PROGRAM_CACHE_RESIZE_ANGLE);
49*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EGL_SUCCESS();
50*8975f5c5SAndroid Build Coastguard Worker         }
51*8975f5c5SAndroid Build Coastguard Worker 
52*8975f5c5SAndroid Build Coastguard Worker         ASSERT_TRUE(getEGLWindow()->initializeContext());
53*8975f5c5SAndroid Build Coastguard Worker     }
54*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()55*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override { gDefaultPlatformMethods.cacheProgram = DefaultCacheProgram; }
56*8975f5c5SAndroid Build Coastguard Worker 
extensionAvailable()57*8975f5c5SAndroid Build Coastguard Worker     bool extensionAvailable()
58*8975f5c5SAndroid Build Coastguard Worker     {
59*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display = getEGLWindow()->getDisplay();
60*8975f5c5SAndroid Build Coastguard Worker         return IsEGLDisplayExtensionEnabled(display, kEGLExtName);
61*8975f5c5SAndroid Build Coastguard Worker     }
62*8975f5c5SAndroid Build Coastguard Worker 
programBinaryAvailable()63*8975f5c5SAndroid Build Coastguard Worker     bool programBinaryAvailable()
64*8975f5c5SAndroid Build Coastguard Worker     {
65*8975f5c5SAndroid Build Coastguard Worker         return (getClientMajorVersion() >= 3 || IsGLExtensionEnabled("GL_OES_get_program_binary"));
66*8975f5c5SAndroid Build Coastguard Worker     }
67*8975f5c5SAndroid Build Coastguard Worker 
68*8975f5c5SAndroid Build Coastguard Worker     ProgramKeyType mCachedKey;
69*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint8_t> mCachedBinary;
70*8975f5c5SAndroid Build Coastguard Worker };
71*8975f5c5SAndroid Build Coastguard Worker 
TestCacheProgram(PlatformMethods * platform,const ProgramKeyType & key,size_t programSize,const uint8_t * programBytes)72*8975f5c5SAndroid Build Coastguard Worker void TestCacheProgram(PlatformMethods *platform,
73*8975f5c5SAndroid Build Coastguard Worker                       const ProgramKeyType &key,
74*8975f5c5SAndroid Build Coastguard Worker                       size_t programSize,
75*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t *programBytes)
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker     auto *testPlatformContext = static_cast<TestPlatformContext *>(platform->context);
78*8975f5c5SAndroid Build Coastguard Worker     auto *testCase =
79*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<EGLProgramCacheControlTest *>(testPlatformContext->currentTest);
80*8975f5c5SAndroid Build Coastguard Worker     testCase->onCache(key, programSize, programBytes);
81*8975f5c5SAndroid Build Coastguard Worker }
82*8975f5c5SAndroid Build Coastguard Worker 
83*8975f5c5SAndroid Build Coastguard Worker // Tests error conditions of the APIs.
TEST_P(EGLProgramCacheControlTest,NegativeAPI)84*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLProgramCacheControlTest, NegativeAPI)
85*8975f5c5SAndroid Build Coastguard Worker {
86*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!extensionAvailable());
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker     constexpr char kDefaultKey[]        = "defaultMakeItLongEnough";
89*8975f5c5SAndroid Build Coastguard Worker     constexpr char kDefaultBinary[]     = "defaultMakeItLongEnough";
90*8975f5c5SAndroid Build Coastguard Worker     constexpr EGLint kDefaultKeySize    = static_cast<EGLint>(ArraySize(kDefaultKey));
91*8975f5c5SAndroid Build Coastguard Worker     constexpr EGLint kDefaultBinarySize = static_cast<EGLint>(ArraySize(kDefaultBinary));
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker     // Test that passing an invalid display to the entry point methods fails.
94*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheGetAttribANGLE(EGL_NO_DISPLAY, EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE);
95*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
96*8975f5c5SAndroid Build Coastguard Worker 
97*8975f5c5SAndroid Build Coastguard Worker     eglProgramCachePopulateANGLE(EGL_NO_DISPLAY, kDefaultKey, kDefaultKeySize, kDefaultBinary,
98*8975f5c5SAndroid Build Coastguard Worker                                  kDefaultBinarySize);
99*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
100*8975f5c5SAndroid Build Coastguard Worker 
101*8975f5c5SAndroid Build Coastguard Worker     EGLint tempKeySize    = 0;
102*8975f5c5SAndroid Build Coastguard Worker     EGLint tempBinarySize = 0;
103*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheQueryANGLE(EGL_NO_DISPLAY, 0, nullptr, &tempKeySize, nullptr, &tempBinarySize);
104*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
105*8975f5c5SAndroid Build Coastguard Worker 
106*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheResizeANGLE(EGL_NO_DISPLAY, 0, EGL_PROGRAM_CACHE_TRIM_ANGLE);
107*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker     // Test querying properties with bad parameters.
110*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = getEGLWindow()->getDisplay();
111*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_RESIZE_ANGLE);
112*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
113*8975f5c5SAndroid Build Coastguard Worker 
114*8975f5c5SAndroid Build Coastguard Worker     // Test populating with invalid parameters.
115*8975f5c5SAndroid Build Coastguard Worker     EGLint keySize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE);
116*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GT(kDefaultKeySize, keySize);
117*8975f5c5SAndroid Build Coastguard Worker     eglProgramCachePopulateANGLE(display, kDefaultKey, keySize + 1, kDefaultBinary,
118*8975f5c5SAndroid Build Coastguard Worker                                  kDefaultBinarySize);
119*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
120*8975f5c5SAndroid Build Coastguard Worker 
121*8975f5c5SAndroid Build Coastguard Worker     eglProgramCachePopulateANGLE(display, kDefaultKey, keySize, kDefaultBinary, -1);
122*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
123*8975f5c5SAndroid Build Coastguard Worker 
124*8975f5c5SAndroid Build Coastguard Worker     eglProgramCachePopulateANGLE(display, nullptr, keySize, kDefaultBinary, kDefaultBinarySize);
125*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker     eglProgramCachePopulateANGLE(display, kDefaultKey, keySize, nullptr, kDefaultBinarySize);
128*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker     // Test querying cache entries with invalid parameters.
131*8975f5c5SAndroid Build Coastguard Worker     eglProgramCachePopulateANGLE(display, kDefaultKey, keySize, kDefaultBinary, kDefaultBinarySize);
132*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
133*8975f5c5SAndroid Build Coastguard Worker 
134*8975f5c5SAndroid Build Coastguard Worker     EGLint cacheSize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_SIZE_ANGLE);
135*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(1, cacheSize);
136*8975f5c5SAndroid Build Coastguard Worker 
137*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheQueryANGLE(display, -1, nullptr, &tempKeySize, nullptr, &tempBinarySize);
138*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
139*8975f5c5SAndroid Build Coastguard Worker 
140*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheQueryANGLE(display, 1, nullptr, &tempKeySize, nullptr, &tempBinarySize);
141*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheQueryANGLE(display, 0, nullptr, nullptr, nullptr, &tempBinarySize);
144*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
145*8975f5c5SAndroid Build Coastguard Worker 
146*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheQueryANGLE(display, 0, nullptr, &tempKeySize, nullptr, nullptr);
147*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheQueryANGLE(display, 0, nullptr, &tempKeySize, nullptr, &tempBinarySize);
150*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
151*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(keySize, tempKeySize);
152*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(kDefaultBinarySize, tempBinarySize);
153*8975f5c5SAndroid Build Coastguard Worker 
154*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint8_t> tempKey(tempKeySize + 5);
155*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint8_t> tempBinary(tempBinarySize + 5);
156*8975f5c5SAndroid Build Coastguard Worker 
157*8975f5c5SAndroid Build Coastguard Worker     tempKeySize--;
158*8975f5c5SAndroid Build Coastguard Worker 
159*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheQueryANGLE(display, 0, tempKey.data(), &tempKeySize, tempBinary.data(),
160*8975f5c5SAndroid Build Coastguard Worker                               &tempBinarySize);
161*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
162*8975f5c5SAndroid Build Coastguard Worker 
163*8975f5c5SAndroid Build Coastguard Worker     tempKeySize++;
164*8975f5c5SAndroid Build Coastguard Worker     tempBinarySize--;
165*8975f5c5SAndroid Build Coastguard Worker 
166*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheQueryANGLE(display, 0, tempKey.data(), &tempKeySize, tempBinary.data(),
167*8975f5c5SAndroid Build Coastguard Worker                               &tempBinarySize);
168*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_ACCESS);
169*8975f5c5SAndroid Build Coastguard Worker 
170*8975f5c5SAndroid Build Coastguard Worker     // Test resizing with invalid parameters.
171*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheResizeANGLE(display, -1, EGL_PROGRAM_CACHE_TRIM_ANGLE);
172*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
173*8975f5c5SAndroid Build Coastguard Worker 
174*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheResizeANGLE(display, 0, EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE);
175*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
176*8975f5c5SAndroid Build Coastguard Worker }
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker // Tests a basic use case.
TEST_P(EGLProgramCacheControlTest,SaveAndReload)179*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLProgramCacheControlTest, SaveAndReload)
180*8975f5c5SAndroid Build Coastguard Worker {
181*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!extensionAvailable() || !programBinaryAvailable());
182*8975f5c5SAndroid Build Coastguard Worker 
183*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = "attribute vec4 position; void main() { gl_Position = position; }";
184*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
185*8975f5c5SAndroid Build Coastguard Worker 
186*8975f5c5SAndroid Build Coastguard Worker     mCachedBinary.clear();
187*8975f5c5SAndroid Build Coastguard Worker     // Link a program, which will miss the cache.
188*8975f5c5SAndroid Build Coastguard Worker     {
189*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
190*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
191*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
192*8975f5c5SAndroid Build Coastguard Worker 
193*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(program, kVS, kFS);
194*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, "position", 0.5f);
195*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
196*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
197*8975f5c5SAndroid Build Coastguard Worker     }
198*8975f5c5SAndroid Build Coastguard Worker     // Assert that the cache insertion added a program to the cache.
199*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(!mCachedBinary.empty());
200*8975f5c5SAndroid Build Coastguard Worker 
201*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = getEGLWindow()->getDisplay();
202*8975f5c5SAndroid Build Coastguard Worker 
203*8975f5c5SAndroid Build Coastguard Worker     EGLint keySize    = 0;
204*8975f5c5SAndroid Build Coastguard Worker     EGLint binarySize = 0;
205*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheQueryANGLE(display, 0, nullptr, &keySize, nullptr, &binarySize);
206*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<EGLint>(mCachedKey.size()), keySize);
207*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker     ProgramKeyType keyBuffer;
210*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint8_t> binaryBuffer(binarySize);
211*8975f5c5SAndroid Build Coastguard Worker     eglProgramCacheQueryANGLE(display, 0, keyBuffer.data(), &keySize, binaryBuffer.data(),
212*8975f5c5SAndroid Build Coastguard Worker                               &binarySize);
213*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(mCachedKey, keyBuffer);
216*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(mCachedBinary, binaryBuffer);
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker     // Restart EGL and GL.
219*8975f5c5SAndroid Build Coastguard Worker     recreateTestFixture();
220*8975f5c5SAndroid Build Coastguard Worker 
221*8975f5c5SAndroid Build Coastguard Worker     // Warm up the cache.
222*8975f5c5SAndroid Build Coastguard Worker     EGLint newCacheSize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_SIZE_ANGLE);
223*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, newCacheSize);
224*8975f5c5SAndroid Build Coastguard Worker     eglProgramCachePopulateANGLE(display, keyBuffer.data(), keySize, binaryBuffer.data(),
225*8975f5c5SAndroid Build Coastguard Worker                                  binarySize);
226*8975f5c5SAndroid Build Coastguard Worker 
227*8975f5c5SAndroid Build Coastguard Worker     mCachedBinary.clear();
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker     // Link a program, which will hit the cache.
230*8975f5c5SAndroid Build Coastguard Worker     {
231*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
232*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
233*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
234*8975f5c5SAndroid Build Coastguard Worker 
235*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(program, kVS, kFS);
236*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, "position", 0.5f);
237*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
238*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
239*8975f5c5SAndroid Build Coastguard Worker     }
240*8975f5c5SAndroid Build Coastguard Worker 
241*8975f5c5SAndroid Build Coastguard Worker     // Verify no new shader was compiled.
242*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(mCachedBinary.empty());
243*8975f5c5SAndroid Build Coastguard Worker }
244*8975f5c5SAndroid Build Coastguard Worker 
245*8975f5c5SAndroid Build Coastguard Worker // Tests that trying to link a program without correct shaders doesn't buggily call the cache.
TEST_P(EGLProgramCacheControlTest,LinkProgramWithBadShaders)246*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLProgramCacheControlTest, LinkProgramWithBadShaders)
247*8975f5c5SAndroid Build Coastguard Worker {
248*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!extensionAvailable());
249*8975f5c5SAndroid Build Coastguard Worker 
250*8975f5c5SAndroid Build Coastguard Worker     GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
251*8975f5c5SAndroid Build Coastguard Worker 
252*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
253*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, shader);
254*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker     GLint linkStatus = 0;
257*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
258*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(linkStatus);
259*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
260*8975f5c5SAndroid Build Coastguard Worker 
261*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(shader);
262*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
263*8975f5c5SAndroid Build Coastguard Worker }
264*8975f5c5SAndroid Build Coastguard Worker 
265*8975f5c5SAndroid Build Coastguard Worker // Tests the program cache can be disabled.
TEST_P(EGLProgramCacheControlTest,DisableProgramCache)266*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLProgramCacheControlTest, DisableProgramCache)
267*8975f5c5SAndroid Build Coastguard Worker {
268*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!extensionAvailable() || !programBinaryAvailable());
269*8975f5c5SAndroid Build Coastguard Worker 
270*8975f5c5SAndroid Build Coastguard Worker     // Disable context program cache, and recreate context.
271*8975f5c5SAndroid Build Coastguard Worker     setContextProgramCacheEnabled(false);
272*8975f5c5SAndroid Build Coastguard Worker     recreateTestFixture();
273*8975f5c5SAndroid Build Coastguard Worker 
274*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = "attribute vec4 position; void main() { gl_Position = position; }";
275*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
276*8975f5c5SAndroid Build Coastguard Worker 
277*8975f5c5SAndroid Build Coastguard Worker     mCachedBinary.clear();
278*8975f5c5SAndroid Build Coastguard Worker     // Link a program, which will miss the cache.
279*8975f5c5SAndroid Build Coastguard Worker     {
280*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
281*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
282*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
283*8975f5c5SAndroid Build Coastguard Worker 
284*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(program, kVS, kFS);
285*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, "position", 0.5f);
286*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
287*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
288*8975f5c5SAndroid Build Coastguard Worker     }
289*8975f5c5SAndroid Build Coastguard Worker 
290*8975f5c5SAndroid Build Coastguard Worker     // Expect that no program binary was inserted into the cache.
291*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(mCachedBinary.empty());
292*8975f5c5SAndroid Build Coastguard Worker }
293*8975f5c5SAndroid Build Coastguard Worker 
294*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLProgramCacheControlTest);
295*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(EGLProgramCacheControlTest,
296*8975f5c5SAndroid Build Coastguard Worker                        ES2_D3D9(),
297*8975f5c5SAndroid Build Coastguard Worker                        ES2_D3D11(),
298*8975f5c5SAndroid Build Coastguard Worker                        ES2_OPENGL(),
299*8975f5c5SAndroid Build Coastguard Worker                        ES2_VULKAN());
300