xref: /aosp_15_r20/external/angle/src/tests/egl_tests/EGLProtectedContentTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // EGLProtectedContentTest.cpp:
7 //   EGL extension EGL_EXT_protected_content
8 //
9 
10 #include <gtest/gtest.h>
11 
12 #include <chrono>
13 #include <iostream>
14 #include <thread>
15 #include "test_utils/ANGLETest.h"
16 #include "util/EGLWindow.h"
17 #include "util/OSWindow.h"
18 
19 constexpr bool kSleepForVisualVerification = false;
20 
21 using namespace std::chrono_literals;
22 
23 using namespace angle;
24 
25 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLProtectedContentTest);
26 
27 class EGLProtectedContentTest : public ANGLETest<>
28 {
29   public:
EGLProtectedContentTest()30     EGLProtectedContentTest() : mDisplay(EGL_NO_DISPLAY) {}
31 
testSetUp()32     void testSetUp() override
33     {
34         EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
35         mDisplay           = eglGetPlatformDisplayEXT(
36             EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
37         EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
38         EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
39         mMajorVersion = GetParam().majorVersion;
40     }
41 
testTearDown()42     void testTearDown() override
43     {
44         if (mDisplay != EGL_NO_DISPLAY)
45         {
46             eglTerminate(mDisplay);
47             eglReleaseThread();
48             mDisplay = EGL_NO_DISPLAY;
49         }
50         ASSERT_EGL_SUCCESS() << "Error during test TearDown";
51     }
52 
chooseConfig(EGLConfig * config,bool mutableRenderBuffer=false)53     bool chooseConfig(EGLConfig *config, bool mutableRenderBuffer = false)
54     {
55         EGLint clientVersion = mMajorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
56         EGLint attribs[]     = {
57             EGL_RED_SIZE,
58             8,
59             EGL_GREEN_SIZE,
60             8,
61             EGL_BLUE_SIZE,
62             8,
63             EGL_ALPHA_SIZE,
64             8,
65             EGL_RENDERABLE_TYPE,
66             clientVersion,
67             EGL_SURFACE_TYPE,
68             EGL_WINDOW_BIT |
69                 (mutableRenderBuffer ? EGL_MUTABLE_RENDER_BUFFER_BIT_KHR : EGL_PBUFFER_BIT),
70             EGL_BIND_TO_TEXTURE_RGBA,
71             EGL_TRUE,
72             EGL_NONE};
73 
74         EGLint count = 0;
75         bool result  = eglChooseConfig(mDisplay, attribs, config, 1, &count);
76         EXPECT_EGL_TRUE(result);
77         EXPECT_EGL_TRUE(count > 0);
78         return result;
79     }
80 
createContext(EGLBoolean isProtected,EGLConfig config,EGLContext * context)81     bool createContext(EGLBoolean isProtected, EGLConfig config, EGLContext *context)
82     {
83         bool result                 = false;
84         EGLint attribsProtected[]   = {EGL_CONTEXT_MAJOR_VERSION, mMajorVersion,
85                                        EGL_PROTECTED_CONTENT_EXT, EGL_TRUE, EGL_NONE};
86         EGLint attribsUnProtected[] = {EGL_CONTEXT_MAJOR_VERSION, mMajorVersion, EGL_NONE};
87 
88         *context = eglCreateContext(mDisplay, config, nullptr,
89                                     (isProtected ? attribsProtected : attribsUnProtected));
90         result   = (*context != EGL_NO_CONTEXT);
91         EXPECT_TRUE(result);
92         return result;
93     }
94 
createPbufferSurface(EGLBoolean isProtected,EGLConfig config,EGLSurface * surface)95     bool createPbufferSurface(EGLBoolean isProtected, EGLConfig config, EGLSurface *surface)
96     {
97         bool result                 = false;
98         EGLint attribsProtected[]   = {EGL_WIDTH,
99                                        kWidth,
100                                        EGL_HEIGHT,
101                                        kHeight,
102                                        EGL_TEXTURE_FORMAT,
103                                        EGL_TEXTURE_RGBA,
104                                        EGL_TEXTURE_TARGET,
105                                        EGL_TEXTURE_2D,
106                                        EGL_PROTECTED_CONTENT_EXT,
107                                        EGL_TRUE,
108                                        EGL_NONE};
109         EGLint attribsUnProtected[] = {EGL_WIDTH,
110                                        kWidth,
111                                        EGL_HEIGHT,
112                                        kHeight,
113                                        EGL_TEXTURE_FORMAT,
114                                        EGL_TEXTURE_RGBA,
115                                        EGL_TEXTURE_TARGET,
116                                        EGL_TEXTURE_2D,
117                                        EGL_NONE};
118 
119         *surface = eglCreatePbufferSurface(mDisplay, config,
120                                            (isProtected ? attribsProtected : attribsUnProtected));
121         result   = (*surface != EGL_NO_SURFACE);
122         EXPECT_TRUE(result);
123         return result;
124     }
125 
createWindowSurface(EGLBoolean isProtected,EGLConfig config,EGLNativeWindowType win,EGLSurface * surface)126     bool createWindowSurface(EGLBoolean isProtected,
127                              EGLConfig config,
128                              EGLNativeWindowType win,
129                              EGLSurface *surface)
130     {
131         bool result                 = false;
132         EGLint attribsProtected[]   = {EGL_PROTECTED_CONTENT_EXT, EGL_TRUE, EGL_NONE};
133         EGLint attribsUnProtected[] = {EGL_NONE};
134 
135         *surface = eglCreateWindowSurface(mDisplay, config, win,
136                                           (isProtected ? attribsProtected : attribsUnProtected));
137         result   = (*surface != EGL_NO_SURFACE);
138         EXPECT_TRUE(result);
139         return result;
140     }
141 
createImage(EGLBoolean isProtected,EGLContext context,EGLenum target,EGLClientBuffer buffer,EGLImage * image)142     bool createImage(EGLBoolean isProtected,
143                      EGLContext context,
144                      EGLenum target,
145                      EGLClientBuffer buffer,
146                      EGLImage *image)
147     {
148         bool result                  = false;
149         EGLAttrib attribsProtected[] = {EGL_PROTECTED_CONTENT_EXT, EGL_TRUE, EGL_NONE};
150 
151         *image = eglCreateImage(mDisplay, context, target, buffer,
152                                 (isProtected ? attribsProtected : nullptr));
153         EXPECT_EGL_SUCCESS();
154         result = (*image != EGL_NO_SURFACE);
155         EXPECT_TRUE(result);
156         return result;
157     }
158 
createTexture(EGLBoolean isProtected,GLuint * textureId)159     bool createTexture(EGLBoolean isProtected, GLuint *textureId)
160     {
161         bool result    = false;
162         GLuint texture = 0;
163         glGenTextures(1, &texture);
164         glBindTexture(GL_TEXTURE_2D, texture);
165         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
166                      nullptr);
167         EXPECT_GL_NO_ERROR();
168         if (isProtected)
169         {
170             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_PROTECTED_EXT, GL_TRUE);
171             // GL_INVALID_OPERATION expected when context is not protected too.
172             GLenum error = glGetError();
173             if (error == GL_INVALID_OPERATION)
174             {
175                 return false;
176             }
177         }
178         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
179         EXPECT_GL_NO_ERROR();
180         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
181         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
182         result = (texture != 0);
183         EXPECT_TRUE(result);
184         *textureId = texture;
185         return result;
186     }
187 
createTextureFromImage(EGLImage image,GLuint * textureId)188     bool createTextureFromImage(EGLImage image, GLuint *textureId)
189     {
190         bool result    = false;
191         GLuint texture = 0;
192         glGenTextures(1, &texture);
193         glBindTexture(GL_TEXTURE_2D, texture);
194         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
195         EXPECT_GL_NO_ERROR();
196         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
197         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
198         result = (texture != 0);
199         EXPECT_TRUE(result);
200         *textureId = texture;
201         return result;
202     }
203 
createTextureFromPbuffer(EGLSurface pBuffer,GLuint * textureId)204     bool createTextureFromPbuffer(EGLSurface pBuffer, GLuint *textureId)
205     {
206         bool result    = false;
207         GLuint texture = 0;
208         glGenTextures(1, &texture);
209         glBindTexture(GL_TEXTURE_2D, texture);
210         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
211         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
212         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
213         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
214         EXPECT_GL_NO_ERROR();
215         EXPECT_TRUE(texture != 0);
216         result = eglBindTexImage(mDisplay, pBuffer, EGL_BACK_BUFFER);
217         glViewport(0, 0, kWidth, kHeight);
218         *textureId = texture;
219         return result;
220     }
221 
fillTexture(GLuint textureId,GLColor color)222     bool fillTexture(GLuint textureId, GLColor color)
223     {
224         GLuint pixels[kWidth * kHeight];
225         for (uint32_t i = 0; i < (kWidth * kHeight); i++)
226         {
227             pixels[i] = *(GLuint *)(color.data());
228         }
229         glBindTexture(GL_TEXTURE_2D, textureId);
230         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
231                         (void *)pixels);
232         EXPECT_GL_NO_ERROR();
233         return true;
234     }
235 
renderTexture(GLuint textureId)236     bool renderTexture(GLuint textureId)
237     {
238         const char *kVertexShader   = R"(
239             precision highp float;
240             attribute vec4 position;
241             varying vec2 texcoord;
242 
243             void main()
244             {
245                 gl_Position = vec4(position.xy, 0.0, 1.0);
246                 texcoord = (position.xy * 0.5) + 0.5;
247             }
248         )";
249         const char *kFragmentShader = R"(
250             precision highp float;
251             uniform sampler2D tex;
252             varying vec2 texcoord;
253 
254             void main()
255             {
256                 gl_FragColor = texture2D(tex, texcoord);
257             }
258         )";
259 
260         GLuint program = CompileProgram(kVertexShader, kFragmentShader);
261         glUseProgram(program);
262         glBindTexture(GL_TEXTURE_2D, textureId);
263         glActiveTexture(GL_TEXTURE0);
264         GLint texture2DUniformLocation = glGetUniformLocation(program, "tex");
265         glUniform1i(texture2DUniformLocation, 0);
266         drawQuad(program, "position", 0.5f);
267         glDeleteProgram(program);
268         EXPECT_GL_NO_ERROR();
269         return true;
270     }
271 
createRenderbuffer(GLuint * renderbuffer)272     bool createRenderbuffer(GLuint *renderbuffer)
273     {
274         bool result   = false;
275         *renderbuffer = 0;
276         glGenRenderbuffers(1, renderbuffer);
277         glBindRenderbuffer(GL_RENDERBUFFER, *renderbuffer);
278         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, kWidth, kHeight);
279         EXPECT_GL_NO_ERROR();
280         result = (*renderbuffer != 0);
281         EXPECT_TRUE(result);
282         return result;
283     }
284 
createRenderbufferFromImage(EGLImage image,GLuint * renderbuffer)285     bool createRenderbufferFromImage(EGLImage image, GLuint *renderbuffer)
286     {
287         bool result   = false;
288         *renderbuffer = 0;
289         glGenRenderbuffers(1, renderbuffer);
290         glBindRenderbuffer(GL_RENDERBUFFER, *renderbuffer);
291         glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image);
292         EXPECT_GL_NO_ERROR();
293         result = (*renderbuffer != 0);
294         EXPECT_TRUE(result);
295         return result;
296     }
297 
createAndroidClientBuffer(bool useProtected,bool useRenderbuffer,bool useTexture,EGLClientBuffer * clientBuffer)298     bool createAndroidClientBuffer(bool useProtected,
299                                    bool useRenderbuffer,
300                                    bool useTexture,
301                                    EGLClientBuffer *clientBuffer)
302     {
303         bool result = false;
304         EGLint nativeBufferUsage =
305             0 | (useProtected ? EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID : 0) |
306             (useRenderbuffer ? EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID : 0) |
307             (useTexture ? EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID : 0);
308 
309         EGLint attribs[] = {EGL_WIDTH,
310                             kWidth,
311                             EGL_HEIGHT,
312                             kHeight,
313                             EGL_RED_SIZE,
314                             8,
315                             EGL_GREEN_SIZE,
316                             8,
317                             EGL_BLUE_SIZE,
318                             8,
319                             EGL_ALPHA_SIZE,
320                             8,
321                             EGL_NATIVE_BUFFER_USAGE_ANDROID,
322                             nativeBufferUsage,
323                             EGL_NONE};
324 
325         *clientBuffer = eglCreateNativeClientBufferANDROID(attribs);
326         EXPECT_EGL_SUCCESS();
327         result = (*clientBuffer != nullptr);
328         EXPECT_TRUE(result);
329         return result;
330     }
331 
332     void pbufferTest(bool isProtectedContext, bool isProtectedSurface);
333     void windowTest(bool isProtectedContext,
334                     bool isProtectedSurface,
335                     bool mutableRenderBuffer = false);
336     void textureTest(bool isProtectedContext, bool isProtectedTexture);
337     void textureFromImageTest(bool isProtectedContext, bool isProtectedTexture);
338     void textureFromPbufferTest(bool isProtectedContext, bool isProtectedTexture);
339     void textureFromAndroidNativeBufferTest(bool isProtectedContext, bool isProtectedTexture);
340 
checkSwapBuffersResult(const std::string color,bool isProtectedContext,bool isProtectedSurface)341     void checkSwapBuffersResult(const std::string color,
342                                 bool isProtectedContext,
343                                 bool isProtectedSurface)
344     {
345         if (kSleepForVisualVerification)
346         {
347             std::this_thread::sleep_for(1s);
348         }
349         if (isProtectedContext)
350         {
351             if (isProtectedSurface)
352             {
353                 std::cout << "Operator should see color: " << color << std::endl;
354             }
355             else
356             {
357                 std::cout << "Operator should see color: BLACK" << std::endl;
358             }
359         }
360         else
361         {
362             if (isProtectedSurface)
363             {
364                 std::cout << "Operator should see color: BLACK" << std::endl;
365             }
366             else
367             {
368                 std::cout << "Operator should see color: " << color << std::endl;
369             }
370         }
371     }
372 
373     EGLDisplay mDisplay         = EGL_NO_DISPLAY;
374     EGLint mMajorVersion        = 0;
375     static const EGLint kWidth  = 16;
376     static const EGLint kHeight = 16;
377 };
378 
pbufferTest(bool isProtectedContext,bool isProtectedSurface)379 void EGLProtectedContentTest::pbufferTest(bool isProtectedContext, bool isProtectedSurface)
380 {
381     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
382 
383     EGLConfig config = EGL_NO_CONFIG_KHR;
384     EXPECT_TRUE(chooseConfig(&config));
385     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
386 
387     EGLContext context = EGL_NO_CONTEXT;
388     EXPECT_TRUE(createContext(isProtectedContext, config, &context));
389     ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
390 
391     EGLSurface pBufferSurface = EGL_NO_SURFACE;
392     EXPECT_TRUE(createPbufferSurface(isProtectedSurface, config, &pBufferSurface));
393     ASSERT_EGL_SUCCESS() << "eglCreatePbufferSurface failed.";
394 
395     EXPECT_TRUE(eglMakeCurrent(mDisplay, pBufferSurface, pBufferSurface, context));
396     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
397 
398     glClearColor(1.0, 0.0, 0.0, 1.0);
399     glClear(GL_COLOR_BUFFER_BIT);
400 
401     glFinish();
402     ASSERT_GL_NO_ERROR() << "glFinish failed";
403     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
404 
405     EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
406     ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
407 
408     eglDestroySurface(mDisplay, pBufferSurface);
409     pBufferSurface = EGL_NO_SURFACE;
410 
411     eglDestroyContext(mDisplay, context);
412     context = EGL_NO_CONTEXT;
413 }
414 
415 // Unprotected context with Unprotected PbufferSurface
TEST_P(EGLProtectedContentTest,UnprotectedContextWithUnprotectedPbufferSurface)416 TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedPbufferSurface)
417 {
418     pbufferTest(false, false);
419 }
420 
windowTest(bool isProtectedContext,bool isProtectedSurface,bool mutableRenderBuffer)421 void EGLProtectedContentTest::windowTest(bool isProtectedContext,
422                                          bool isProtectedSurface,
423                                          bool mutableRenderBuffer)
424 {
425     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
426     ANGLE_SKIP_TEST_IF(mutableRenderBuffer &&
427                        !IsEGLDisplayExtensionEnabled(mDisplay, "EGL_KHR_mutable_render_buffer"));
428 
429     EGLConfig config = EGL_NO_CONFIG_KHR;
430     EXPECT_TRUE(chooseConfig(&config, mutableRenderBuffer));
431     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
432 
433     EGLContext context = EGL_NO_CONTEXT;
434     EXPECT_TRUE(createContext(isProtectedContext, config, &context));
435     ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
436 
437     OSWindow *osWindow = OSWindow::New();
438     osWindow->initialize("ProtectedContentTest", kWidth, kHeight);
439     EGLSurface windowSurface          = EGL_NO_SURFACE;
440     EGLBoolean createWinSurfaceResult = createWindowSurface(
441         isProtectedSurface, config, osWindow->getNativeWindow(), &windowSurface);
442     EXPECT_TRUE(createWinSurfaceResult);
443     ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";
444 
445     EXPECT_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
446     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
447 
448     if (mutableRenderBuffer)
449     {
450         EXPECT_TRUE(
451             eglSurfaceAttrib(mDisplay, windowSurface, EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER));
452         ASSERT_EGL_SUCCESS() << "eglSurfaceAttrib failed.";
453         eglSwapBuffers(mDisplay, windowSurface);
454         ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
455     }
456 
457     // Red
458     glClearColor(1.0, 0.0, 0.0, 1.0);
459     glClear(GL_COLOR_BUFFER_BIT);
460     ASSERT_GL_NO_ERROR() << "glClear failed";
461     eglSwapBuffers(mDisplay, windowSurface);
462     ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
463     checkSwapBuffersResult("RED", isProtectedContext, isProtectedSurface);
464 
465     // Green
466     glClearColor(0.0, 1.0, 0.0, 1.0);
467     glClear(GL_COLOR_BUFFER_BIT);
468     ASSERT_GL_NO_ERROR() << "glClear failed";
469     eglSwapBuffers(mDisplay, windowSurface);
470     ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
471     checkSwapBuffersResult("GREEN", isProtectedContext, isProtectedSurface);
472 
473     // Blue
474     glClearColor(0.0, 0.0, 1.0, 1.0);
475     glClear(GL_COLOR_BUFFER_BIT);
476     ASSERT_GL_NO_ERROR() << "glClear failed";
477     eglSwapBuffers(mDisplay, windowSurface);
478     ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
479     checkSwapBuffersResult("BLUE", isProtectedContext, isProtectedSurface);
480 
481     EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
482     ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
483 
484     eglDestroySurface(mDisplay, windowSurface);
485     windowSurface = EGL_NO_SURFACE;
486     osWindow->destroy();
487     OSWindow::Delete(&osWindow);
488 
489     eglDestroyContext(mDisplay, context);
490     context = EGL_NO_CONTEXT;
491 }
492 
493 // Unprotected context with Unprotected WindowSurface
TEST_P(EGLProtectedContentTest,UnprotectedContextWithUnprotectedWindowSurface)494 TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedWindowSurface)
495 {
496     windowTest(false, false);
497 }
498 
499 // Protected context with Protected WindowSurface
TEST_P(EGLProtectedContentTest,ProtectedContextWithProtectedWindowSurface)500 TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedWindowSurface)
501 {
502     windowTest(true, true);
503 }
504 
505 // Protected context with Protected Mutable Render Buffer WindowSurface.
TEST_P(EGLProtectedContentTest,ProtectedContextWithProtectedMutableRenderBufferWindowSurface)506 TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedMutableRenderBufferWindowSurface)
507 {
508     windowTest(true, true, true);
509 }
510 
textureTest(bool isProtectedContext,bool isProtectedTexture)511 void EGLProtectedContentTest::textureTest(bool isProtectedContext, bool isProtectedTexture)
512 {
513     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
514 
515     bool isProtectedSurface = isProtectedTexture;
516 
517     EGLConfig config = EGL_NO_CONFIG_KHR;
518     EXPECT_TRUE(chooseConfig(&config));
519     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
520 
521     EGLContext context = EGL_NO_CONTEXT;
522     EXPECT_TRUE(createContext(isProtectedContext, config, &context));
523     ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
524 
525     OSWindow *osWindow = OSWindow::New();
526     osWindow->initialize("ProtectedContentTest", kWidth, kHeight);
527     EGLSurface windowSurface          = EGL_NO_SURFACE;
528     EGLBoolean createWinSurfaceResult = createWindowSurface(
529         isProtectedSurface, config, osWindow->getNativeWindow(), &windowSurface);
530     EXPECT_TRUE(createWinSurfaceResult);
531     ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";
532     glViewport(0, 0, kWidth, kHeight);
533 
534     EXPECT_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
535     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
536 
537     if (IsGLExtensionEnabled("GL_EXT_protected_textures"))
538     {
539         GLuint texture = 0;
540         bool result    = createTexture(isProtectedTexture, &texture);
541         if (isProtectedTexture && !isProtectedContext)
542         {
543             std::cout << "Can't create protected Texture for Unprotected Context" << std::endl;
544             ASSERT_FALSE(result);
545         }
546         else
547         {
548             ASSERT_TRUE(result);
549 
550             EXPECT_TRUE(fillTexture(texture, GLColor::red));
551             EXPECT_TRUE(renderTexture(texture));
552 
553             eglSwapBuffers(mDisplay, windowSurface);
554             ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
555             checkSwapBuffersResult("RED", isProtectedContext, isProtectedSurface);
556 
557             glBindTexture(GL_TEXTURE_2D, 0);
558             glDeleteTextures(1, &texture);
559         }
560     }
561     else
562     {
563         std::cout << "Skipping tests, GL_EXT_protected_textures not supported" << std::endl;
564     }
565 
566     EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
567     ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
568 
569     eglDestroySurface(mDisplay, windowSurface);
570     windowSurface = EGL_NO_SURFACE;
571     osWindow->destroy();
572     OSWindow::Delete(&osWindow);
573 
574     eglDestroyContext(mDisplay, context);
575     context = EGL_NO_CONTEXT;
576 }
577 
578 // Unprotected context with unprotected texture
TEST_P(EGLProtectedContentTest,UnprotectedContextWithUnprotectedTexture)579 TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedTexture)
580 {
581     textureTest(false, false);
582 }
583 
584 // Protected context with protected texture
TEST_P(EGLProtectedContentTest,ProtectedContextWithProtectedTexture)585 TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedTexture)
586 {
587     textureTest(true, true);
588 }
589 
textureFromImageTest(bool isProtectedContext,bool isProtectedTexture)590 void EGLProtectedContentTest::textureFromImageTest(bool isProtectedContext, bool isProtectedTexture)
591 {
592     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
593 
594     bool isProtectedSurface = isProtectedTexture;
595 
596     EGLConfig config = EGL_NO_CONFIG_KHR;
597     EXPECT_TRUE(chooseConfig(&config));
598     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
599 
600     EGLContext context = EGL_NO_CONTEXT;
601     EXPECT_TRUE(createContext(isProtectedContext, config, &context));
602     ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
603 
604     OSWindow *osWindow = OSWindow::New();
605     osWindow->initialize("ProtectedContentTest", kWidth, kHeight);
606     EGLSurface windowSurface          = EGL_NO_SURFACE;
607     EGLBoolean createWinSurfaceResult = createWindowSurface(
608         isProtectedSurface, config, osWindow->getNativeWindow(), &windowSurface);
609     EXPECT_TRUE(createWinSurfaceResult);
610     ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";
611 
612     EXPECT_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
613     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
614     glViewport(0, 0, kWidth, kHeight);
615 
616     if (IsGLExtensionEnabled("GL_OES_EGL_image") &&
617         IsGLExtensionEnabled("GL_EXT_protected_textures"))
618     {
619         GLuint srcTexture = 0;
620         if (isProtectedTexture && !isProtectedContext)
621         {
622             std::cout << "Can't create protected Texture for Unprotected Context, Skipping"
623                       << std::endl;
624             ASSERT_FALSE(createTexture(isProtectedTexture, &srcTexture));
625         }
626         else
627         {
628             ASSERT_TRUE(createTexture(isProtectedTexture, &srcTexture));
629             EXPECT_TRUE(fillTexture(srcTexture, GLColor::red));
630 
631             EGLImage image = EGL_NO_IMAGE;
632             EXPECT_TRUE(createImage(isProtectedTexture, context, EGL_GL_TEXTURE_2D,
633                                     (void *)(static_cast<intptr_t>(srcTexture)), &image));
634 
635             GLuint dstTexture = 0;
636             EXPECT_TRUE(createTextureFromImage(image, &dstTexture));
637             EXPECT_TRUE(renderTexture(dstTexture));
638 
639             eglSwapBuffers(mDisplay, windowSurface);
640             ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
641             checkSwapBuffersResult("RED", isProtectedContext, isProtectedSurface);
642 
643             glBindTexture(GL_TEXTURE_2D, 0);
644             glDeleteTextures(1, &dstTexture);
645             glDeleteTextures(1, &srcTexture);
646 
647             eglDestroyImage(mDisplay, image);
648             image = EGL_NO_IMAGE;
649         }
650     }
651     else
652     {
653         std::cout << "Skipping tests, GL_OES_EGL_image or GL_EXT_protected_textures not supported"
654                   << std::endl;
655     }
656 
657     EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
658     ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
659 
660     eglDestroySurface(mDisplay, windowSurface);
661     windowSurface = EGL_NO_SURFACE;
662     osWindow->destroy();
663     OSWindow::Delete(&osWindow);
664 
665     eglDestroyContext(mDisplay, context);
666     context = EGL_NO_CONTEXT;
667 }
668 
669 // Unprotected context with unprotected texture from EGL image
TEST_P(EGLProtectedContentTest,UnprotectedContextWithUnprotectedTextureFromImage)670 TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedTextureFromImage)
671 {
672     textureFromImageTest(false, false);
673 }
674 
675 // Protected context with protected texture from EGL image
TEST_P(EGLProtectedContentTest,ProtectedContextWithProtectedTextureFromImage)676 TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedTextureFromImage)
677 {
678     textureFromImageTest(true, true);
679 }
680 
textureFromPbufferTest(bool isProtectedContext,bool isProtectedTexture)681 void EGLProtectedContentTest::textureFromPbufferTest(bool isProtectedContext,
682                                                      bool isProtectedTexture)
683 {
684     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
685 
686     bool isProtectedSurface = isProtectedTexture;
687 
688     EGLConfig config = EGL_NO_CONFIG_KHR;
689     EXPECT_TRUE(chooseConfig(&config));
690     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
691 
692     EGLContext context = EGL_NO_CONTEXT;
693     EXPECT_TRUE(createContext(isProtectedContext, config, &context));
694     ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
695 
696     EGLSurface pBufferSurface = EGL_NO_SURFACE;
697     EXPECT_TRUE(createPbufferSurface(isProtectedSurface, config, &pBufferSurface));
698     ASSERT_EGL_SUCCESS() << "eglCreatePbufferSurface failed.";
699 
700     EXPECT_TRUE(eglMakeCurrent(mDisplay, pBufferSurface, pBufferSurface, context));
701     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
702 
703     glViewport(0, 0, kWidth, kHeight);
704     glClearColor(1.0, 0.0, 0.0, 1.0);
705     glClear(GL_COLOR_BUFFER_BIT);
706 
707     glFinish();
708     ASSERT_GL_NO_ERROR() << "glFinish failed";
709 
710     OSWindow *osWindow = OSWindow::New();
711     osWindow->initialize("ProtectedContentTest", kWidth, kHeight);
712     EGLSurface windowSurface          = EGL_NO_SURFACE;
713     EGLBoolean createWinSurfaceResult = createWindowSurface(
714         isProtectedSurface, config, osWindow->getNativeWindow(), &windowSurface);
715     EXPECT_TRUE(createWinSurfaceResult);
716     ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";
717 
718     EXPECT_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
719     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
720     glViewport(0, 0, kWidth, kHeight);
721 
722     if (IsGLExtensionEnabled("GL_EXT_protected_textures"))
723     {
724         GLuint texture = 0;
725         EXPECT_TRUE(createTextureFromPbuffer(pBufferSurface, &texture));
726         EXPECT_TRUE(renderTexture(texture));
727 
728         eglSwapBuffers(mDisplay, windowSurface);
729         ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
730         checkSwapBuffersResult("RED", isProtectedContext, isProtectedTexture);
731 
732         eglReleaseTexImage(mDisplay, pBufferSurface, EGL_BACK_BUFFER);
733         glDeleteTextures(1, &texture);
734     }
735     else
736     {
737         std::cout << "Skipping tests, GL_EXT_protected_textures not supported" << std::endl;
738     }
739 
740     EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
741     ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
742 
743     eglDestroySurface(mDisplay, windowSurface);
744     windowSurface = EGL_NO_SURFACE;
745     osWindow->destroy();
746     OSWindow::Delete(&osWindow);
747 
748     eglDestroySurface(mDisplay, pBufferSurface);
749     pBufferSurface = EGL_NO_SURFACE;
750 
751     eglDestroyContext(mDisplay, context);
752     context = EGL_NO_CONTEXT;
753 }
754 
755 // Unprotected context with unprotected texture from BindTex of PBufferSurface
TEST_P(EGLProtectedContentTest,UnprotectedContextWithUnprotectedTextureFromPBuffer)756 TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedTextureFromPBuffer)
757 {
758     textureFromPbufferTest(false, false);
759 }
760 
761 // Protected context with protected texture from BindTex of PBufferSurface
TEST_P(EGLProtectedContentTest,ProtectedContextWithProtectedTextureFromPbuffer)762 TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedTextureFromPbuffer)
763 {
764     textureFromPbufferTest(true, true);
765 }
766 
textureFromAndroidNativeBufferTest(bool isProtectedContext,bool isProtectedTexture)767 void EGLProtectedContentTest::textureFromAndroidNativeBufferTest(bool isProtectedContext,
768                                                                  bool isProtectedTexture)
769 {
770     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
771     ANGLE_SKIP_TEST_IF(
772         !IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANDROID_get_native_client_buffer"));
773     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANDROID_image_native_buffer"));
774 
775     bool isProtectedSurface = isProtectedTexture;
776 
777     EGLConfig config = EGL_NO_CONFIG_KHR;
778     EXPECT_TRUE(chooseConfig(&config));
779     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
780 
781     EGLContext context = EGL_NO_CONTEXT;
782     EXPECT_TRUE(createContext(isProtectedContext, config, &context));
783     ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
784 
785     OSWindow *osWindow = OSWindow::New();
786     osWindow->initialize("ProtectedContentTest", kWidth, kHeight);
787     EGLSurface windowSurface          = EGL_NO_SURFACE;
788     EGLBoolean createWinSurfaceResult = createWindowSurface(
789         isProtectedSurface, config, osWindow->getNativeWindow(), &windowSurface);
790     EXPECT_TRUE(createWinSurfaceResult);
791     ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";
792 
793     EXPECT_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
794     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
795     glViewport(0, 0, kWidth, kHeight);
796 
797     if (IsGLExtensionEnabled("GL_EXT_protected_textures"))
798     {
799         EGLClientBuffer clientBuffer = nullptr;
800         EXPECT_TRUE(createAndroidClientBuffer(isProtectedTexture, false, true, &clientBuffer));
801 
802         EGLImage image = EGL_NO_IMAGE;
803         EXPECT_TRUE(createImage(isProtectedTexture, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
804                                 clientBuffer, &image));
805 
806         GLuint texture = 0;
807         if (isProtectedTexture && !isProtectedContext)
808         {
809             std::cout << "Can't create protected Texture for Unprotected Context, Skipping"
810                       << std::endl;
811             ASSERT_FALSE(createTextureFromImage(image, &texture));
812         }
813         else
814         {
815             EXPECT_TRUE(createTextureFromImage(image, &texture));
816             EXPECT_TRUE(fillTexture(texture, GLColor::red));
817             EXPECT_TRUE(renderTexture(texture));
818 
819             eglSwapBuffers(mDisplay, windowSurface);
820             ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
821             checkSwapBuffersResult("RED", isProtectedContext, isProtectedTexture);
822 
823             glBindTexture(GL_TEXTURE_2D, 0);
824             glDeleteTextures(1, &texture);
825 
826             eglDestroyImage(mDisplay, image);
827             image = EGL_NO_IMAGE;
828         }
829     }
830     else
831     {
832         std::cout << "Skipping tests, GL_EXT_protected_textures not supported" << std::endl;
833     }
834 
835     EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
836     ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
837 
838     eglDestroySurface(mDisplay, windowSurface);
839     windowSurface = EGL_NO_SURFACE;
840     osWindow->destroy();
841     OSWindow::Delete(&osWindow);
842 
843     eglDestroyContext(mDisplay, context);
844     context = EGL_NO_CONTEXT;
845 }
846 
847 // Unprotected context with unprotected texture from EGL image from Android native buffer
TEST_P(EGLProtectedContentTest,UnprotectedContextWithUnprotectedTextureFromAndroidNativeBuffer)848 TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedTextureFromAndroidNativeBuffer)
849 {
850     textureFromAndroidNativeBufferTest(false, false);
851 }
852 
853 // Protected context with protected texture from EGL image from Android native buffer
TEST_P(EGLProtectedContentTest,ProtectedContextWithProtectedTextureFromAndroidNativeBuffer)854 TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedTextureFromAndroidNativeBuffer)
855 {
856     textureFromAndroidNativeBufferTest(true, true);
857 }
858 
859 // Retrieve the EGL_PROTECTED_CONTENT_EXT attribute via eglQueryContext
TEST_P(EGLProtectedContentTest,QueryContext)860 TEST_P(EGLProtectedContentTest, QueryContext)
861 {
862     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
863 
864     EGLConfig config = EGL_NO_CONFIG_KHR;
865     EXPECT_TRUE(chooseConfig(&config));
866     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
867 
868     bool isProtectedContext = true;
869     EGLContext context      = EGL_NO_CONTEXT;
870     EXPECT_TRUE(createContext(isProtectedContext, config, &context));
871     ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
872 
873     EGLint value = 0;
874     EXPECT_EGL_TRUE(eglQueryContext(mDisplay, context, EGL_PROTECTED_CONTENT_EXT, &value));
875     ASSERT_EGL_SUCCESS() << "eglQueryContext failed.";
876 
877     EXPECT_EQ(value, 1);
878 }
879 
880 ANGLE_INSTANTIATE_TEST(EGLProtectedContentTest,
881                        WithNoFixture(ES2_OPENGLES()),
882                        WithNoFixture(ES3_OPENGLES()),
883                        WithNoFixture(ES2_VULKAN()),
884                        WithNoFixture(ES3_VULKAN()));
885