OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 // https://android.googlesource.com/platform/frameworks/base/+/master/opengl/j
ava/android/opengl/EGL14.java | 50 // https://android.googlesource.com/platform/frameworks/base/+/master/opengl/j
ava/android/opengl/EGL14.java |
51 // This is similar to how GlSurfaceView does: | 51 // This is similar to how GlSurfaceView does: |
52 // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.androi
d/android/5.1.1_r1/android/opengl/GLSurfaceView.java#760 | 52 // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.androi
d/android/5.1.1_r1/android/opengl/GLSurfaceView.java#760 |
53 private static final int EGL_OPENGL_ES2_BIT = 4; | 53 private static final int EGL_OPENGL_ES2_BIT = 4; |
54 private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; | 54 private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; |
55 // Android-specific extension. | 55 // Android-specific extension. |
56 private static final int EGL_RECORDABLE_ANDROID = 0x3142; | 56 private static final int EGL_RECORDABLE_ANDROID = 0x3142; |
57 | 57 |
58 private final EGL10 egl; | 58 private final EGL10 egl; |
59 private EGLContext eglContext; | 59 private EGLContext eglContext; |
60 private ConfigType configType; | |
61 private EGLConfig eglConfig; | 60 private EGLConfig eglConfig; |
62 private EGLDisplay eglDisplay; | 61 private EGLDisplay eglDisplay; |
63 private EGLSurface eglSurface = EGL10.EGL_NO_SURFACE; | 62 private EGLSurface eglSurface = EGL10.EGL_NO_SURFACE; |
64 | 63 |
65 // EGLConfig constructor type. Influences eglChooseConfig arguments. | 64 public static final int[] CONFIG_PLAIN = { |
66 public static enum ConfigType { | 65 EGL10.EGL_RED_SIZE, 8, |
67 // No special parameters. | 66 EGL10.EGL_GREEN_SIZE, 8, |
68 PLAIN, | 67 EGL10.EGL_BLUE_SIZE, 8, |
69 // Configures with EGL_SURFACE_TYPE = EGL_PBUFFER_BIT. | 68 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
70 PIXEL_BUFFER, | 69 EGL10.EGL_NONE |
71 // Configures with EGL_RECORDABLE_ANDROID = 1. | 70 }; |
72 // Discourages EGL from using pixel formats that cannot efficiently be | 71 public static final int[] CONFIG_PIXEL_BUFFER = { |
73 // converted to something usable by the video encoder. | 72 EGL10.EGL_RED_SIZE, 8, |
74 RECORDABLE | 73 EGL10.EGL_GREEN_SIZE, 8, |
75 } | 74 EGL10.EGL_BLUE_SIZE, 8, |
76 | 75 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| 76 EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT, |
| 77 EGL10.EGL_NONE |
| 78 }; |
| 79 public static final int[] CONFIG_PIXEL_RGBA_BUFFER = { |
| 80 EGL10.EGL_RED_SIZE, 8, |
| 81 EGL10.EGL_GREEN_SIZE, 8, |
| 82 EGL10.EGL_BLUE_SIZE, 8, |
| 83 EGL10.EGL_ALPHA_SIZE, 8, |
| 84 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| 85 EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT, |
| 86 EGL10.EGL_NONE |
| 87 }; |
| 88 public static final int[] CONFIG_RECORDABLE = { |
| 89 EGL10.EGL_RED_SIZE, 8, |
| 90 EGL10.EGL_GREEN_SIZE, 8, |
| 91 EGL10.EGL_BLUE_SIZE, 8, |
| 92 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| 93 EGL_RECORDABLE_ANDROID, 1, |
| 94 EGL10.EGL_NONE |
| 95 }; |
77 // Create root context without any EGLSurface or parent EGLContext. This can b
e used for branching | 96 // Create root context without any EGLSurface or parent EGLContext. This can b
e used for branching |
78 // new contexts that share data. | 97 // new contexts that share data. |
79 public EglBase() { | 98 public EglBase() { |
80 this(EGL10.EGL_NO_CONTEXT, ConfigType.PLAIN); | 99 this(EGL10.EGL_NO_CONTEXT, CONFIG_PLAIN); |
81 } | 100 } |
82 | 101 |
83 // Create a new context with the specified config type, sharing data with shar
edContext. | 102 // Create a new context with the specified config type, sharing data with shar
edContext. |
84 public EglBase(EGLContext sharedContext, ConfigType configType) { | 103 public EglBase(EGLContext sharedContext, int[] configAttributes) { |
85 this.egl = (EGL10) EGLContext.getEGL(); | 104 this.egl = (EGL10) EGLContext.getEGL(); |
86 this.configType = configType; | |
87 eglDisplay = getEglDisplay(); | 105 eglDisplay = getEglDisplay(); |
88 eglConfig = getEglConfig(eglDisplay, configType); | 106 eglConfig = getEglConfig(eglDisplay, configAttributes); |
89 eglContext = createEglContext(sharedContext, eglDisplay, eglConfig); | 107 eglContext = createEglContext(sharedContext, eglDisplay, eglConfig); |
90 } | 108 } |
91 | 109 |
92 // Create EGLSurface from the Android Surface. | 110 // Create EGLSurface from the Android Surface. |
93 public void createSurface(Surface surface) { | 111 public void createSurface(Surface surface) { |
94 /** | 112 /** |
95 * We have to wrap Surface in a SurfaceHolder because for some reason eglCre
ateWindowSurface | 113 * We have to wrap Surface in a SurfaceHolder because for some reason eglCre
ateWindowSurface |
96 * couldn't actually take a Surface object until API 17. Older versions fort
unately just call | 114 * couldn't actually take a Surface object until API 17. Older versions fort
unately just call |
97 * SurfaceHolder.getSurface(), so we'll do that. No other methods are releva
nt. | 115 * SurfaceHolder.getSurface(), so we'll do that. No other methods are releva
nt. |
98 */ | 116 */ |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 public void createSurface(SurfaceTexture surfaceTexture) { | 178 public void createSurface(SurfaceTexture surfaceTexture) { |
161 createSurfaceInternal(surfaceTexture); | 179 createSurfaceInternal(surfaceTexture); |
162 } | 180 } |
163 | 181 |
164 // Create EGLSurface from either a SurfaceHolder or a SurfaceTexture. | 182 // Create EGLSurface from either a SurfaceHolder or a SurfaceTexture. |
165 private void createSurfaceInternal(Object nativeWindow) { | 183 private void createSurfaceInternal(Object nativeWindow) { |
166 if (!(nativeWindow instanceof SurfaceHolder) && !(nativeWindow instanceof Su
rfaceTexture)) { | 184 if (!(nativeWindow instanceof SurfaceHolder) && !(nativeWindow instanceof Su
rfaceTexture)) { |
167 throw new IllegalStateException("Input must be either a SurfaceHolder or S
urfaceTexture"); | 185 throw new IllegalStateException("Input must be either a SurfaceHolder or S
urfaceTexture"); |
168 } | 186 } |
169 checkIsNotReleased(); | 187 checkIsNotReleased(); |
170 if (configType == ConfigType.PIXEL_BUFFER) { | |
171 Logging.w(TAG, "This EGL context is configured for PIXEL_BUFFER, but uses
regular Surface"); | |
172 } | |
173 if (eglSurface != EGL10.EGL_NO_SURFACE) { | 188 if (eglSurface != EGL10.EGL_NO_SURFACE) { |
174 throw new RuntimeException("Already has an EGLSurface"); | 189 throw new RuntimeException("Already has an EGLSurface"); |
175 } | 190 } |
176 int[] surfaceAttribs = {EGL10.EGL_NONE}; | 191 int[] surfaceAttribs = {EGL10.EGL_NONE}; |
177 eglSurface = egl.eglCreateWindowSurface(eglDisplay, eglConfig, nativeWindow,
surfaceAttribs); | 192 eglSurface = egl.eglCreateWindowSurface(eglDisplay, eglConfig, nativeWindow,
surfaceAttribs); |
178 if (eglSurface == EGL10.EGL_NO_SURFACE) { | 193 if (eglSurface == EGL10.EGL_NO_SURFACE) { |
179 throw new RuntimeException("Failed to create window surface"); | 194 throw new RuntimeException("Failed to create window surface"); |
180 } | 195 } |
181 } | 196 } |
182 | 197 |
183 // Create dummy 1x1 pixel buffer surface so the context can be made current. | 198 // Create dummy 1x1 pixel buffer surface so the context can be made current. |
184 public void createDummyPbufferSurface() { | 199 public void createDummyPbufferSurface() { |
185 createPbufferSurface(1, 1); | 200 createPbufferSurface(1, 1); |
186 } | 201 } |
187 | 202 |
188 public void createPbufferSurface(int width, int height) { | 203 public void createPbufferSurface(int width, int height) { |
189 checkIsNotReleased(); | 204 checkIsNotReleased(); |
190 if (configType != ConfigType.PIXEL_BUFFER) { | |
191 throw new RuntimeException( | |
192 "This EGL context is not configured to use a pixel buffer: " + configT
ype); | |
193 } | |
194 if (eglSurface != EGL10.EGL_NO_SURFACE) { | 205 if (eglSurface != EGL10.EGL_NO_SURFACE) { |
195 throw new RuntimeException("Already has an EGLSurface"); | 206 throw new RuntimeException("Already has an EGLSurface"); |
196 } | 207 } |
197 int[] surfaceAttribs = {EGL10.EGL_WIDTH, width, EGL10.EGL_HEIGHT, height, EG
L10.EGL_NONE}; | 208 int[] surfaceAttribs = {EGL10.EGL_WIDTH, width, EGL10.EGL_HEIGHT, height, EG
L10.EGL_NONE}; |
198 eglSurface = egl.eglCreatePbufferSurface(eglDisplay, eglConfig, surfaceAttri
bs); | 209 eglSurface = egl.eglCreatePbufferSurface(eglDisplay, eglConfig, surfaceAttri
bs); |
199 if (eglSurface == EGL10.EGL_NO_SURFACE) { | 210 if (eglSurface == EGL10.EGL_NO_SURFACE) { |
200 throw new RuntimeException("Failed to create pixel buffer surface"); | 211 throw new RuntimeException("Failed to create pixel buffer surface"); |
201 } | 212 } |
202 } | 213 } |
203 | 214 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 throw new RuntimeException("Unable to get EGL10 display"); | 290 throw new RuntimeException("Unable to get EGL10 display"); |
280 } | 291 } |
281 int[] version = new int[2]; | 292 int[] version = new int[2]; |
282 if (!egl.eglInitialize(eglDisplay, version)) { | 293 if (!egl.eglInitialize(eglDisplay, version)) { |
283 throw new RuntimeException("Unable to initialize EGL10"); | 294 throw new RuntimeException("Unable to initialize EGL10"); |
284 } | 295 } |
285 return eglDisplay; | 296 return eglDisplay; |
286 } | 297 } |
287 | 298 |
288 // Return an EGLConfig, or die trying. | 299 // Return an EGLConfig, or die trying. |
289 private EGLConfig getEglConfig(EGLDisplay eglDisplay, ConfigType configType) { | 300 private EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] configAttributes)
{ |
290 // Always RGB888, GLES2. | |
291 int[] configAttributes = { | |
292 EGL10.EGL_RED_SIZE, 8, | |
293 EGL10.EGL_GREEN_SIZE, 8, | |
294 EGL10.EGL_BLUE_SIZE, 8, | |
295 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | |
296 EGL10.EGL_NONE, 0, // Allocate dummy fields for specific options. | |
297 EGL10.EGL_NONE | |
298 }; | |
299 | |
300 // Fill in dummy fields based on configType. | |
301 switch (configType) { | |
302 case PLAIN: | |
303 break; | |
304 case PIXEL_BUFFER: | |
305 configAttributes[configAttributes.length - 3] = EGL10.EGL_SURFACE_TYPE; | |
306 configAttributes[configAttributes.length - 2] = EGL10.EGL_PBUFFER_BIT; | |
307 break; | |
308 case RECORDABLE: | |
309 configAttributes[configAttributes.length - 3] = EGL_RECORDABLE_ANDROID; | |
310 configAttributes[configAttributes.length - 2] = 1; | |
311 break; | |
312 default: | |
313 throw new IllegalArgumentException(); | |
314 } | |
315 | |
316 EGLConfig[] configs = new EGLConfig[1]; | 301 EGLConfig[] configs = new EGLConfig[1]; |
317 int[] numConfigs = new int[1]; | 302 int[] numConfigs = new int[1]; |
318 if (!egl.eglChooseConfig( | 303 if (!egl.eglChooseConfig( |
319 eglDisplay, configAttributes, configs, configs.length, numConfigs)) { | 304 eglDisplay, configAttributes, configs, configs.length, numConfigs)) { |
320 throw new RuntimeException("Unable to find RGB888 " + configType + " EGL c
onfig"); | 305 throw new RuntimeException("Unable to find any matching EGL config"); |
321 } | 306 } |
322 return configs[0]; | 307 return configs[0]; |
323 } | 308 } |
324 | 309 |
325 // Return an EGLConfig, or die trying. | 310 // Return an EGLConfig, or die trying. |
326 private EGLContext createEglContext( | 311 private EGLContext createEglContext( |
327 EGLContext sharedContext, EGLDisplay eglDisplay, EGLConfig eglConfig) { | 312 EGLContext sharedContext, EGLDisplay eglDisplay, EGLConfig eglConfig) { |
328 int[] contextAttributes = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE}; | 313 int[] contextAttributes = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE}; |
329 EGLContext eglContext = | 314 EGLContext eglContext = |
330 egl.eglCreateContext(eglDisplay, eglConfig, sharedContext, contextAttrib
utes); | 315 egl.eglCreateContext(eglDisplay, eglConfig, sharedContext, contextAttrib
utes); |
331 if (eglContext == EGL10.EGL_NO_CONTEXT) { | 316 if (eglContext == EGL10.EGL_NO_CONTEXT) { |
332 throw new RuntimeException("Failed to create EGL context"); | 317 throw new RuntimeException("Failed to create EGL context"); |
333 } | 318 } |
334 return eglContext; | 319 return eglContext; |
335 } | 320 } |
336 } | 321 } |
OLD | NEW |