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