Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 1 | /* |
kjellander | b24317b | 2016-02-10 07:54:43 -0800 | [diff] [blame] | 2 | * Copyright 2015 The WebRTC project authors. All Rights Reserved. |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 3 | * |
kjellander | b24317b | 2016-02-10 07:54:43 -0800 | [diff] [blame] | 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 9 | */ |
| 10 | |
| 11 | package org.webrtc; |
| 12 | |
Magnus Jedvert | 1ab271c | 2015-09-28 11:05:44 +0200 | [diff] [blame] | 13 | import android.graphics.SurfaceTexture; |
Artem Titarenko | 69540f4 | 2018-12-10 12:30:46 +0100 | [diff] [blame] | 14 | import android.support.annotation.Nullable; |
magjed | 3e0f602 | 2015-11-16 02:04:50 -0800 | [diff] [blame] | 15 | import android.view.Surface; |
magjed | 8c425aa | 2015-10-22 16:52:39 -0700 | [diff] [blame] | 16 | import javax.microedition.khronos.egl.EGL10; |
perkj | 9638143 | 2015-12-15 02:48:07 -0800 | [diff] [blame] | 17 | |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 18 | /** |
perkj | 40455d6 | 2015-12-02 01:07:18 -0800 | [diff] [blame] | 19 | * Holds EGL state and utility methods for handling an egl 1.0 EGLContext, an EGLDisplay, |
| 20 | * and an EGLSurface. |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 21 | */ |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 22 | public interface EglBase { |
perkj | 9638143 | 2015-12-15 02:48:07 -0800 | [diff] [blame] | 23 | // EGL wrapper for an actual EGLContext. |
Sami Kalliomäki | 8db246a | 2018-10-04 10:58:24 +0200 | [diff] [blame] | 24 | public interface Context { |
Magnus Jedvert | 7c6fbf2 | 2018-11-30 21:52:28 +0100 | [diff] [blame] | 25 | public final static long NO_CONTEXT = 0; |
| 26 | |
Sami Kalliomäki | 8db246a | 2018-10-04 10:58:24 +0200 | [diff] [blame] | 27 | /** |
Magnus Jedvert | 7c6fbf2 | 2018-11-30 21:52:28 +0100 | [diff] [blame] | 28 | * Returns an EGL context that can be used by native code. Returns NO_CONTEXT if the method is |
Sami Kalliomäki | 8db246a | 2018-10-04 10:58:24 +0200 | [diff] [blame] | 29 | * unsupported. |
| 30 | * |
| 31 | * @note This is currently only supported for EGL 1.4 and not for EGL 1.0. |
| 32 | */ |
| 33 | long getNativeEglContext(); |
| 34 | } |
perkj | 9638143 | 2015-12-15 02:48:07 -0800 | [diff] [blame] | 35 | |
Magnus Jedvert | 3db6f9b | 2016-03-31 13:17:11 +0200 | [diff] [blame] | 36 | // According to the documentation, EGL can be used from multiple threads at the same time if each |
| 37 | // thread has its own EGLContext, but in practice it deadlocks on some devices when doing this. |
| 38 | // Therefore, synchronize on this global lock before calling dangerous EGL functions that might |
| 39 | // deadlock. See https://bugs.chromium.org/p/webrtc/issues/detail?id=5702 for more info. |
| 40 | public static final Object lock = new Object(); |
| 41 | |
magjed | 8c425aa | 2015-10-22 16:52:39 -0700 | [diff] [blame] | 42 | // These constants are taken from EGL14.EGL_OPENGL_ES2_BIT and EGL14.EGL_CONTEXT_CLIENT_VERSION. |
| 43 | // https://android.googlesource.com/platform/frameworks/base/+/master/opengl/java/android/opengl/EGL14.java |
| 44 | // This is similar to how GlSurfaceView does: |
| 45 | // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/opengl/GLSurfaceView.java#760 |
magjed | 4781552 | 2017-08-25 06:28:00 -0700 | [diff] [blame] | 46 | public static final int EGL_OPENGL_ES2_BIT = 4; |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 47 | // Android-specific extension. |
magjed | 4781552 | 2017-08-25 06:28:00 -0700 | [diff] [blame] | 48 | public static final int EGL_RECORDABLE_ANDROID = 0x3142; |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 49 | |
sakal | b6760f9 | 2016-09-29 04:12:44 -0700 | [diff] [blame] | 50 | // clang-format off |
nisse | 03f80eb | 2015-12-07 01:17:16 -0800 | [diff] [blame] | 51 | public static final int[] CONFIG_PLAIN = { |
| 52 | EGL10.EGL_RED_SIZE, 8, |
| 53 | EGL10.EGL_GREEN_SIZE, 8, |
| 54 | EGL10.EGL_BLUE_SIZE, 8, |
| 55 | EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| 56 | EGL10.EGL_NONE |
| 57 | }; |
Magnus Jedvert | 5125433 | 2015-12-15 16:22:29 +0100 | [diff] [blame] | 58 | public static final int[] CONFIG_RGBA = { |
| 59 | EGL10.EGL_RED_SIZE, 8, |
| 60 | EGL10.EGL_GREEN_SIZE, 8, |
| 61 | EGL10.EGL_BLUE_SIZE, 8, |
| 62 | EGL10.EGL_ALPHA_SIZE, 8, |
| 63 | EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| 64 | EGL10.EGL_NONE |
| 65 | }; |
nisse | 03f80eb | 2015-12-07 01:17:16 -0800 | [diff] [blame] | 66 | public static final int[] CONFIG_PIXEL_BUFFER = { |
| 67 | EGL10.EGL_RED_SIZE, 8, |
| 68 | EGL10.EGL_GREEN_SIZE, 8, |
| 69 | EGL10.EGL_BLUE_SIZE, 8, |
| 70 | EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| 71 | EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT, |
| 72 | EGL10.EGL_NONE |
| 73 | }; |
nisse | c490e01 | 2015-12-10 06:23:33 -0800 | [diff] [blame] | 74 | public static final int[] CONFIG_PIXEL_RGBA_BUFFER = { |
| 75 | EGL10.EGL_RED_SIZE, 8, |
| 76 | EGL10.EGL_GREEN_SIZE, 8, |
| 77 | EGL10.EGL_BLUE_SIZE, 8, |
| 78 | EGL10.EGL_ALPHA_SIZE, 8, |
| 79 | EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| 80 | EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT, |
| 81 | EGL10.EGL_NONE |
| 82 | }; |
nisse | 03f80eb | 2015-12-07 01:17:16 -0800 | [diff] [blame] | 83 | public static final int[] CONFIG_RECORDABLE = { |
| 84 | EGL10.EGL_RED_SIZE, 8, |
| 85 | EGL10.EGL_GREEN_SIZE, 8, |
| 86 | EGL10.EGL_BLUE_SIZE, 8, |
| 87 | EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| 88 | EGL_RECORDABLE_ANDROID, 1, |
| 89 | EGL10.EGL_NONE |
| 90 | }; |
sakal | b6760f9 | 2016-09-29 04:12:44 -0700 | [diff] [blame] | 91 | // clang-format on |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 92 | |
magjed | b04646f | 2017-04-21 01:34:12 -0700 | [diff] [blame] | 93 | /** |
| 94 | * Create a new context with the specified config attributes, sharing data with |sharedContext|. |
| 95 | * If |sharedContext| is null, a root context is created. This function will try to create an EGL |
| 96 | * 1.4 context if possible, and an EGL 1.0 context otherwise. |
| 97 | */ |
Sami Kalliomäki | e7592d8 | 2018-03-22 13:32:44 +0100 | [diff] [blame] | 98 | public static EglBase create(@Nullable Context sharedContext, int[] configAttributes) { |
perkj | 40455d6 | 2015-12-02 01:07:18 -0800 | [diff] [blame] | 99 | return (EglBase14.isEGL14Supported() |
sakal | b6760f9 | 2016-09-29 04:12:44 -0700 | [diff] [blame] | 100 | && (sharedContext == null || sharedContext instanceof EglBase14.Context)) |
| 101 | ? new EglBase14((EglBase14.Context) sharedContext, configAttributes) |
| 102 | : new EglBase10((EglBase10.Context) sharedContext, configAttributes); |
perkj | 40455d6 | 2015-12-02 01:07:18 -0800 | [diff] [blame] | 103 | } |
| 104 | |
magjed | b04646f | 2017-04-21 01:34:12 -0700 | [diff] [blame] | 105 | /** |
| 106 | * Helper function for creating a plain root context. This function will try to create an EGL 1.4 |
| 107 | * context if possible, and an EGL 1.0 context otherwise. |
| 108 | */ |
perkj | 40455d6 | 2015-12-02 01:07:18 -0800 | [diff] [blame] | 109 | public static EglBase create() { |
magjed | b04646f | 2017-04-21 01:34:12 -0700 | [diff] [blame] | 110 | return create(null /* shaderContext */, CONFIG_PLAIN); |
perkj | 40455d6 | 2015-12-02 01:07:18 -0800 | [diff] [blame] | 111 | } |
| 112 | |
magjed | b04646f | 2017-04-21 01:34:12 -0700 | [diff] [blame] | 113 | /** |
| 114 | * Helper function for creating a plain context, sharing data with |sharedContext|. This function |
| 115 | * will try to create an EGL 1.4 context if possible, and an EGL 1.0 context otherwise. |
| 116 | */ |
Per | ec2922f | 2016-01-27 15:25:46 +0100 | [diff] [blame] | 117 | public static EglBase create(Context sharedContext) { |
| 118 | return create(sharedContext, CONFIG_PLAIN); |
| 119 | } |
| 120 | |
magjed | b04646f | 2017-04-21 01:34:12 -0700 | [diff] [blame] | 121 | /** |
| 122 | * Explicitly create a root EGl 1.0 context with the specified config attributes. |
| 123 | */ |
| 124 | public static EglBase createEgl10(int[] configAttributes) { |
| 125 | return new EglBase10(null /* shaderContext */, configAttributes); |
| 126 | } |
| 127 | |
| 128 | /** |
deadbeef | a615e17 | 2017-05-25 10:11:25 -0700 | [diff] [blame] | 129 | * Explicitly create a root EGl 1.0 context with the specified config attributes |
| 130 | * and shared context. |
| 131 | */ |
| 132 | public static EglBase createEgl10( |
| 133 | javax.microedition.khronos.egl.EGLContext sharedContext, int[] configAttributes) { |
| 134 | return new EglBase10(new EglBase10.Context(sharedContext), configAttributes); |
| 135 | } |
| 136 | |
| 137 | /** |
magjed | b04646f | 2017-04-21 01:34:12 -0700 | [diff] [blame] | 138 | * Explicitly create a root EGl 1.4 context with the specified config attributes. |
| 139 | */ |
| 140 | public static EglBase createEgl14(int[] configAttributes) { |
| 141 | return new EglBase14(null /* shaderContext */, configAttributes); |
| 142 | } |
| 143 | |
deadbeef | a615e17 | 2017-05-25 10:11:25 -0700 | [diff] [blame] | 144 | /** |
| 145 | * Explicitly create a root EGl 1.4 context with the specified config attributes |
| 146 | * and shared context. |
| 147 | */ |
| 148 | public static EglBase createEgl14( |
| 149 | android.opengl.EGLContext sharedContext, int[] configAttributes) { |
| 150 | return new EglBase14(new EglBase14.Context(sharedContext), configAttributes); |
| 151 | } |
| 152 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 153 | void createSurface(Surface surface); |
Magnus Jedvert | 1ab271c | 2015-09-28 11:05:44 +0200 | [diff] [blame] | 154 | |
| 155 | // Create EGLSurface from the Android SurfaceTexture. |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 156 | void createSurface(SurfaceTexture surfaceTexture); |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 157 | |
| 158 | // Create dummy 1x1 pixel buffer surface so the context can be made current. |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 159 | void createDummyPbufferSurface(); |
magjed | b28678c | 2015-07-26 05:17:19 -0700 | [diff] [blame] | 160 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 161 | void createPbufferSurface(int width, int height); |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 162 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 163 | Context getEglBaseContext(); |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 164 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 165 | boolean hasSurface(); |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 166 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 167 | int surfaceWidth(); |
Magnus Jedvert | d476b95 | 2015-08-20 09:58:31 +0200 | [diff] [blame] | 168 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 169 | int surfaceHeight(); |
Magnus Jedvert | d476b95 | 2015-08-20 09:58:31 +0200 | [diff] [blame] | 170 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 171 | void releaseSurface(); |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 172 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 173 | void release(); |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 174 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 175 | void makeCurrent(); |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 176 | |
Magnus Jedvert | 4ae28a1 | 2015-09-15 09:44:07 +0200 | [diff] [blame] | 177 | // Detach the current EGL context, so that it can be made current on another thread. |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 178 | void detachCurrent(); |
Magnus Jedvert | 4ae28a1 | 2015-09-15 09:44:07 +0200 | [diff] [blame] | 179 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 180 | void swapBuffers(); |
magjed | 4781552 | 2017-08-25 06:28:00 -0700 | [diff] [blame] | 181 | |
Sami Kalliomäki | b9f3f9b | 2017-11-30 11:23:33 +0100 | [diff] [blame] | 182 | void swapBuffers(long presentationTimeStampNs); |
Magnus Jedvert | 80cf97c | 2015-06-11 10:08:59 +0200 | [diff] [blame] | 183 | } |