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