• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.cts.hardware;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotEquals;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertTrue;
23 
24 import android.hardware.SyncFence;
25 import android.opengl.EGL14;
26 import android.opengl.EGL15;
27 import android.opengl.EGLConfig;
28 import android.opengl.EGLContext;
29 import android.opengl.EGLDisplay;
30 import android.opengl.EGLExt;
31 import android.opengl.EGLSurface;
32 import android.opengl.EGLSync;
33 import android.opengl.GLES20;
34 
35 public class SyncFenceUtil {
createUselessFence()36     public static SyncFence createUselessFence() {
37         EGLDisplay eglDisplay = EGL15.EGL_NO_DISPLAY;
38         EGLConfig eglConfig = null;
39         EGLSurface eglPbuffer = EGL15.EGL_NO_SURFACE;
40         EGLContext eglContext = EGL15.EGL_NO_CONTEXT;
41         int error;
42 
43         eglDisplay = EGL15.eglGetPlatformDisplay(EGL15.EGL_PLATFORM_ANDROID_KHR,
44             EGL14.EGL_DEFAULT_DISPLAY,
45             new long[] {
46                 EGL14.EGL_NONE },
47             0);
48         if (eglDisplay == EGL15.EGL_NO_DISPLAY) {
49             throw new RuntimeException("no EGL display");
50         }
51         error = EGL14.eglGetError();
52         if (error != EGL14.EGL_SUCCESS) {
53             throw new RuntimeException("eglGetPlatformDisplay failed");
54         }
55 
56         int[] major = new int[1];
57         int[] minor = new int[1];
58         if (!EGL14.eglInitialize(eglDisplay, major, 0, minor, 0)) {
59             throw new RuntimeException("error in eglInitialize");
60         }
61         error = EGL14.eglGetError();
62         if (error != EGL14.EGL_SUCCESS) {
63             throw new RuntimeException("eglInitialize failed");
64         }
65 
66         // If we could rely on having EGL_KHR_surfaceless_context and EGL_KHR_context_no_config, we
67         // wouldn't have to create a config or pbuffer at all.
68 
69         int[] numConfigs = new int[1];
70         EGLConfig[] configs = new EGLConfig[1];
71         if (!EGL14.eglChooseConfig(eglDisplay,
72                 new int[] {
73                     EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
74                     EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT,
75                     EGL14.EGL_NONE},
76                 0, configs, 0, 1, numConfigs, 0)) {
77             throw new RuntimeException("eglChooseConfig failed");
78         }
79         error = EGL14.eglGetError();
80         if (error != EGL14.EGL_SUCCESS) {
81             throw new RuntimeException("eglChooseConfig failed");
82         }
83 
84         eglConfig = configs[0];
85 
86         eglPbuffer = EGL14.eglCreatePbufferSurface(eglDisplay, eglConfig,
87               new int[] {EGL14.EGL_WIDTH, 1, EGL14.EGL_HEIGHT, 1, EGL14.EGL_NONE}, 0);
88         if (eglPbuffer == EGL15.EGL_NO_SURFACE) {
89             throw new RuntimeException("eglCreatePbufferSurface failed");
90         }
91         error = EGL14.eglGetError();
92         if (error != EGL14.EGL_SUCCESS) {
93             throw new RuntimeException("eglCreatePbufferSurface failed");
94         }
95 
96         eglContext = EGL14.eglCreateContext(eglDisplay, eglConfig, EGL14.EGL_NO_CONTEXT,
97               new int[] {EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE}, 0);
98         if (eglContext == EGL15.EGL_NO_CONTEXT) {
99             throw new RuntimeException("eglCreateContext failed");
100         }
101         error = EGL14.eglGetError();
102         if (error != EGL14.EGL_SUCCESS) {
103             throw new RuntimeException("eglCreateContext failed");
104         }
105 
106         if (!EGL14.eglMakeCurrent(eglDisplay, eglPbuffer, eglPbuffer, eglContext)) {
107             throw new RuntimeException("eglMakeCurrent failed");
108         }
109         error = EGL14.eglGetError();
110         if (error != EGL14.EGL_SUCCESS) {
111             throw new RuntimeException("eglMakeCurrent failed");
112         }
113 
114         SyncFence nativeFence = null;
115 
116         String eglExtensions = EGL14.eglQueryString(eglDisplay, EGL14.EGL_EXTENSIONS);
117         if (eglExtensions.contains("EGL_ANDROID_native_fence_sync")) {
118             EGLSync sync = EGL15.eglCreateSync(eglDisplay, EGLExt.EGL_SYNC_NATIVE_FENCE_ANDROID,
119                     new long[] {
120                         EGL14.EGL_NONE },
121                     0);
122             assertNotEquals(sync, EGL15.EGL_NO_SYNC);
123             assertEquals(EGL14.EGL_SUCCESS, EGL14.eglGetError());
124 
125             nativeFence = EGLExt.eglDupNativeFenceFDANDROID(eglDisplay, sync);
126             assertNotNull(nativeFence);
127             assertEquals(EGL14.EGL_SUCCESS, EGL14.eglGetError());
128             // If the fence isn't valid, trigger a flush & try again
129             if (!nativeFence.isValid()) {
130                 GLES20.glFlush();
131                 assertEquals(GLES20.GL_NO_ERROR, GLES20.glGetError());
132 
133                 // Have flushed, native fence should be populated
134                 nativeFence = EGLExt.eglDupNativeFenceFDANDROID(eglDisplay, sync);
135                 assertNotNull(nativeFence);
136                 assertTrue(nativeFence.isValid());
137                 assertEquals(EGL14.EGL_SUCCESS, EGL14.eglGetError());
138             }
139 
140             assertTrue(EGL15.eglDestroySync(eglDisplay, sync));
141         }
142 
143         EGL14.eglTerminate(eglDisplay);
144 
145         return nativeFence;
146     }
147 }
148