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