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