blob: 50ebe6cbf3c607c632bca0e9ef24e0af6f2972de [file] [log] [blame]
Magnus Jedvert80cf97c2015-06-11 10:08:59 +02001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
Magnus Jedvert80cf97c2015-06-11 10:08:59 +02003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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 Jedvert80cf97c2015-06-11 10:08:59 +02009 */
10
11package org.webrtc;
12
Magnus Jedvert1ab271c2015-09-28 11:05:44 +020013import android.graphics.SurfaceTexture;
magjed3e0f6022015-11-16 02:04:50 -080014import android.view.Surface;
Sami Kalliomäki8db246a2018-10-04 10:58:24 +020015import javax.annotation.Nullable;
magjed8c425aa2015-10-22 16:52:39 -070016import javax.microedition.khronos.egl.EGL10;
perkj96381432015-12-15 02:48:07 -080017
Magnus Jedvert80cf97c2015-06-11 10:08:59 +020018/**
perkj40455d62015-12-02 01:07:18 -080019 * Holds EGL state and utility methods for handling an egl 1.0 EGLContext, an EGLDisplay,
20 * and an EGLSurface.
Magnus Jedvert80cf97c2015-06-11 10:08:59 +020021 */
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +010022public interface EglBase {
perkj96381432015-12-15 02:48:07 -080023 // EGL wrapper for an actual EGLContext.
Sami Kalliomäki8db246a2018-10-04 10:58:24 +020024 public interface Context {
25 /**
26 * Returns an EGL context that can be used by native code. Returns 0 if the method is
27 * unsupported.
28 *
29 * @note This is currently only supported for EGL 1.4 and not for EGL 1.0.
30 */
31 long getNativeEglContext();
32 }
perkj96381432015-12-15 02:48:07 -080033
Magnus Jedvert3db6f9b2016-03-31 13:17:11 +020034 // According to the documentation, EGL can be used from multiple threads at the same time if each
35 // thread has its own EGLContext, but in practice it deadlocks on some devices when doing this.
36 // Therefore, synchronize on this global lock before calling dangerous EGL functions that might
37 // deadlock. See https://bugs.chromium.org/p/webrtc/issues/detail?id=5702 for more info.
38 public static final Object lock = new Object();
39
magjed8c425aa2015-10-22 16:52:39 -070040 // These constants are taken from EGL14.EGL_OPENGL_ES2_BIT and EGL14.EGL_CONTEXT_CLIENT_VERSION.
41 // https://android.googlesource.com/platform/frameworks/base/+/master/opengl/java/android/opengl/EGL14.java
42 // This is similar to how GlSurfaceView does:
43 // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/opengl/GLSurfaceView.java#760
magjed47815522017-08-25 06:28:00 -070044 public static final int EGL_OPENGL_ES2_BIT = 4;
Magnus Jedvert80cf97c2015-06-11 10:08:59 +020045 // Android-specific extension.
magjed47815522017-08-25 06:28:00 -070046 public static final int EGL_RECORDABLE_ANDROID = 0x3142;
Magnus Jedvert80cf97c2015-06-11 10:08:59 +020047
sakalb6760f92016-09-29 04:12:44 -070048 // clang-format off
nisse03f80eb2015-12-07 01:17:16 -080049 public static final int[] CONFIG_PLAIN = {
50 EGL10.EGL_RED_SIZE, 8,
51 EGL10.EGL_GREEN_SIZE, 8,
52 EGL10.EGL_BLUE_SIZE, 8,
53 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
54 EGL10.EGL_NONE
55 };
Magnus Jedvert51254332015-12-15 16:22:29 +010056 public static final int[] CONFIG_RGBA = {
57 EGL10.EGL_RED_SIZE, 8,
58 EGL10.EGL_GREEN_SIZE, 8,
59 EGL10.EGL_BLUE_SIZE, 8,
60 EGL10.EGL_ALPHA_SIZE, 8,
61 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
62 EGL10.EGL_NONE
63 };
nisse03f80eb2015-12-07 01:17:16 -080064 public static final int[] CONFIG_PIXEL_BUFFER = {
65 EGL10.EGL_RED_SIZE, 8,
66 EGL10.EGL_GREEN_SIZE, 8,
67 EGL10.EGL_BLUE_SIZE, 8,
68 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
69 EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT,
70 EGL10.EGL_NONE
71 };
nissec490e012015-12-10 06:23:33 -080072 public static final int[] CONFIG_PIXEL_RGBA_BUFFER = {
73 EGL10.EGL_RED_SIZE, 8,
74 EGL10.EGL_GREEN_SIZE, 8,
75 EGL10.EGL_BLUE_SIZE, 8,
76 EGL10.EGL_ALPHA_SIZE, 8,
77 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
78 EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT,
79 EGL10.EGL_NONE
80 };
nisse03f80eb2015-12-07 01:17:16 -080081 public static final int[] CONFIG_RECORDABLE = {
82 EGL10.EGL_RED_SIZE, 8,
83 EGL10.EGL_GREEN_SIZE, 8,
84 EGL10.EGL_BLUE_SIZE, 8,
85 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
86 EGL_RECORDABLE_ANDROID, 1,
87 EGL10.EGL_NONE
88 };
sakalb6760f92016-09-29 04:12:44 -070089 // clang-format on
Magnus Jedvert80cf97c2015-06-11 10:08:59 +020090
magjedb04646f2017-04-21 01:34:12 -070091 /**
92 * Create a new context with the specified config attributes, sharing data with |sharedContext|.
93 * If |sharedContext| is null, a root context is created. This function will try to create an EGL
94 * 1.4 context if possible, and an EGL 1.0 context otherwise.
95 */
Sami Kalliomäkie7592d82018-03-22 13:32:44 +010096 public static EglBase create(@Nullable Context sharedContext, int[] configAttributes) {
perkj40455d62015-12-02 01:07:18 -080097 return (EglBase14.isEGL14Supported()
sakalb6760f92016-09-29 04:12:44 -070098 && (sharedContext == null || sharedContext instanceof EglBase14.Context))
99 ? new EglBase14((EglBase14.Context) sharedContext, configAttributes)
100 : new EglBase10((EglBase10.Context) sharedContext, configAttributes);
perkj40455d62015-12-02 01:07:18 -0800101 }
102
magjedb04646f2017-04-21 01:34:12 -0700103 /**
104 * Helper function for creating a plain root context. This function will try to create an EGL 1.4
105 * context if possible, and an EGL 1.0 context otherwise.
106 */
perkj40455d62015-12-02 01:07:18 -0800107 public static EglBase create() {
magjedb04646f2017-04-21 01:34:12 -0700108 return create(null /* shaderContext */, CONFIG_PLAIN);
perkj40455d62015-12-02 01:07:18 -0800109 }
110
magjedb04646f2017-04-21 01:34:12 -0700111 /**
112 * Helper function for creating a plain context, sharing data with |sharedContext|. This function
113 * will try to create an EGL 1.4 context if possible, and an EGL 1.0 context otherwise.
114 */
Perec2922f2016-01-27 15:25:46 +0100115 public static EglBase create(Context sharedContext) {
116 return create(sharedContext, CONFIG_PLAIN);
117 }
118
magjedb04646f2017-04-21 01:34:12 -0700119 /**
120 * Explicitly create a root EGl 1.0 context with the specified config attributes.
121 */
122 public static EglBase createEgl10(int[] configAttributes) {
123 return new EglBase10(null /* shaderContext */, configAttributes);
124 }
125
126 /**
deadbeefa615e172017-05-25 10:11:25 -0700127 * Explicitly create a root EGl 1.0 context with the specified config attributes
128 * and shared context.
129 */
130 public static EglBase createEgl10(
131 javax.microedition.khronos.egl.EGLContext sharedContext, int[] configAttributes) {
132 return new EglBase10(new EglBase10.Context(sharedContext), configAttributes);
133 }
134
135 /**
magjedb04646f2017-04-21 01:34:12 -0700136 * Explicitly create a root EGl 1.4 context with the specified config attributes.
137 */
138 public static EglBase createEgl14(int[] configAttributes) {
139 return new EglBase14(null /* shaderContext */, configAttributes);
140 }
141
deadbeefa615e172017-05-25 10:11:25 -0700142 /**
143 * Explicitly create a root EGl 1.4 context with the specified config attributes
144 * and shared context.
145 */
146 public static EglBase createEgl14(
147 android.opengl.EGLContext sharedContext, int[] configAttributes) {
148 return new EglBase14(new EglBase14.Context(sharedContext), configAttributes);
149 }
150
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100151 void createSurface(Surface surface);
Magnus Jedvert1ab271c2015-09-28 11:05:44 +0200152
153 // Create EGLSurface from the Android SurfaceTexture.
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100154 void createSurface(SurfaceTexture surfaceTexture);
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200155
156 // Create dummy 1x1 pixel buffer surface so the context can be made current.
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100157 void createDummyPbufferSurface();
magjedb28678c2015-07-26 05:17:19 -0700158
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100159 void createPbufferSurface(int width, int height);
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200160
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100161 Context getEglBaseContext();
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200162
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100163 boolean hasSurface();
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200164
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100165 int surfaceWidth();
Magnus Jedvertd476b952015-08-20 09:58:31 +0200166
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100167 int surfaceHeight();
Magnus Jedvertd476b952015-08-20 09:58:31 +0200168
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100169 void releaseSurface();
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200170
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100171 void release();
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200172
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100173 void makeCurrent();
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200174
Magnus Jedvert4ae28a12015-09-15 09:44:07 +0200175 // Detach the current EGL context, so that it can be made current on another thread.
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100176 void detachCurrent();
Magnus Jedvert4ae28a12015-09-15 09:44:07 +0200177
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100178 void swapBuffers();
magjed47815522017-08-25 06:28:00 -0700179
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100180 void swapBuffers(long presentationTimeStampNs);
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200181}