blob: 3d0238de258197314a50c5ae5e75aeea1c65e416 [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;
Artem Titarenko69540f42018-12-10 12:30:46 +010014import android.support.annotation.Nullable;
magjed3e0f6022015-11-16 02:04:50 -080015import android.view.Surface;
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 {
Magnus Jedvert7c6fbf22018-11-30 21:52:28 +010025 public final static long NO_CONTEXT = 0;
26
Sami Kalliomäki8db246a2018-10-04 10:58:24 +020027 /**
Magnus Jedvert7c6fbf22018-11-30 21:52:28 +010028 * Returns an EGL context that can be used by native code. Returns NO_CONTEXT if the method is
Sami Kalliomäki8db246a2018-10-04 10:58:24 +020029 * unsupported.
30 *
31 * @note This is currently only supported for EGL 1.4 and not for EGL 1.0.
32 */
33 long getNativeEglContext();
34 }
perkj96381432015-12-15 02:48:07 -080035
Magnus Jedvert3db6f9b2016-03-31 13:17:11 +020036 // 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
magjed8c425aa2015-10-22 16:52:39 -070042 // 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
magjed47815522017-08-25 06:28:00 -070046 public static final int EGL_OPENGL_ES2_BIT = 4;
Magnus Jedvert80cf97c2015-06-11 10:08:59 +020047 // Android-specific extension.
magjed47815522017-08-25 06:28:00 -070048 public static final int EGL_RECORDABLE_ANDROID = 0x3142;
Magnus Jedvert80cf97c2015-06-11 10:08:59 +020049
sakalb6760f92016-09-29 04:12:44 -070050 // clang-format off
nisse03f80eb2015-12-07 01:17:16 -080051 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 Jedvert51254332015-12-15 16:22:29 +010058 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 };
nisse03f80eb2015-12-07 01:17:16 -080066 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 };
nissec490e012015-12-10 06:23:33 -080074 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 };
nisse03f80eb2015-12-07 01:17:16 -080083 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 };
sakalb6760f92016-09-29 04:12:44 -070091 // clang-format on
Magnus Jedvert80cf97c2015-06-11 10:08:59 +020092
magjedb04646f2017-04-21 01:34:12 -070093 /**
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äkie7592d82018-03-22 13:32:44 +010098 public static EglBase create(@Nullable Context sharedContext, int[] configAttributes) {
Magnus Jedvert98d85fe2019-03-20 11:17:02 +010099 if (sharedContext == null) {
100 return EglBase14Impl.isEGL14Supported() ? createEgl14(configAttributes)
101 : createEgl10(configAttributes);
102 } else if (sharedContext instanceof EglBase14.Context) {
103 return createEgl14((EglBase14.Context) sharedContext, configAttributes);
104 } else if (sharedContext instanceof EglBase10.Context) {
105 return createEgl10((EglBase10.Context) sharedContext, configAttributes);
106 }
107 throw new IllegalArgumentException("Unrecognized Context");
perkj40455d62015-12-02 01:07:18 -0800108 }
109
magjedb04646f2017-04-21 01:34:12 -0700110 /**
111 * Helper function for creating a plain root context. This function will try to create an EGL 1.4
112 * context if possible, and an EGL 1.0 context otherwise.
113 */
perkj40455d62015-12-02 01:07:18 -0800114 public static EglBase create() {
magjedb04646f2017-04-21 01:34:12 -0700115 return create(null /* shaderContext */, CONFIG_PLAIN);
perkj40455d62015-12-02 01:07:18 -0800116 }
117
magjedb04646f2017-04-21 01:34:12 -0700118 /**
119 * Helper function for creating a plain context, sharing data with |sharedContext|. This function
120 * will try to create an EGL 1.4 context if possible, and an EGL 1.0 context otherwise.
121 */
Perec2922f2016-01-27 15:25:46 +0100122 public static EglBase create(Context sharedContext) {
123 return create(sharedContext, CONFIG_PLAIN);
124 }
125
Magnus Jedvert98d85fe2019-03-20 11:17:02 +0100126 /** Explicitly create a root EGl 1.0 context with the specified config attributes. */
127 public static EglBase10 createEgl10(int[] configAttributes) {
128 return new EglBase10Impl(/* sharedContext= */ null, configAttributes);
129 }
130
magjedb04646f2017-04-21 01:34:12 -0700131 /**
Magnus Jedvert98d85fe2019-03-20 11:17:02 +0100132 * Explicitly create a root EGl 1.0 context with the specified config attributes and shared
133 * context.
magjedb04646f2017-04-21 01:34:12 -0700134 */
Magnus Jedvert98d85fe2019-03-20 11:17:02 +0100135 public static EglBase10 createEgl10(EglBase10.Context sharedContext, int[] configAttributes) {
136 return new EglBase10Impl(
137 sharedContext == null ? null : sharedContext.getRawContext(), configAttributes);
magjedb04646f2017-04-21 01:34:12 -0700138 }
139
140 /**
deadbeefa615e172017-05-25 10:11:25 -0700141 * Explicitly create a root EGl 1.0 context with the specified config attributes
142 * and shared context.
143 */
Magnus Jedvert98d85fe2019-03-20 11:17:02 +0100144 public static EglBase10 createEgl10(
deadbeefa615e172017-05-25 10:11:25 -0700145 javax.microedition.khronos.egl.EGLContext sharedContext, int[] configAttributes) {
Magnus Jedvert98d85fe2019-03-20 11:17:02 +0100146 return new EglBase10Impl(sharedContext, configAttributes);
147 }
148
149 /** Explicitly create a root EGl 1.4 context with the specified config attributes. */
150 public static EglBase14 createEgl14(int[] configAttributes) {
151 return new EglBase14Impl(/* sharedContext= */ null, configAttributes);
deadbeefa615e172017-05-25 10:11:25 -0700152 }
153
154 /**
Magnus Jedvert98d85fe2019-03-20 11:17:02 +0100155 * Explicitly create a root EGl 1.4 context with the specified config attributes and shared
156 * context.
magjedb04646f2017-04-21 01:34:12 -0700157 */
Magnus Jedvert98d85fe2019-03-20 11:17:02 +0100158 public static EglBase14 createEgl14(EglBase14.Context sharedContext, int[] configAttributes) {
159 return new EglBase14Impl(
160 sharedContext == null ? null : sharedContext.getRawContext(), configAttributes);
magjedb04646f2017-04-21 01:34:12 -0700161 }
162
deadbeefa615e172017-05-25 10:11:25 -0700163 /**
164 * Explicitly create a root EGl 1.4 context with the specified config attributes
165 * and shared context.
166 */
Magnus Jedvert98d85fe2019-03-20 11:17:02 +0100167 public static EglBase14 createEgl14(
deadbeefa615e172017-05-25 10:11:25 -0700168 android.opengl.EGLContext sharedContext, int[] configAttributes) {
Magnus Jedvert98d85fe2019-03-20 11:17:02 +0100169 return new EglBase14Impl(sharedContext, configAttributes);
deadbeefa615e172017-05-25 10:11:25 -0700170 }
171
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100172 void createSurface(Surface surface);
Magnus Jedvert1ab271c2015-09-28 11:05:44 +0200173
174 // Create EGLSurface from the Android SurfaceTexture.
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100175 void createSurface(SurfaceTexture surfaceTexture);
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200176
177 // Create dummy 1x1 pixel buffer surface so the context can be made current.
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100178 void createDummyPbufferSurface();
magjedb28678c2015-07-26 05:17:19 -0700179
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100180 void createPbufferSurface(int width, int height);
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200181
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100182 Context getEglBaseContext();
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200183
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100184 boolean hasSurface();
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200185
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100186 int surfaceWidth();
Magnus Jedvertd476b952015-08-20 09:58:31 +0200187
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100188 int surfaceHeight();
Magnus Jedvertd476b952015-08-20 09:58:31 +0200189
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100190 void releaseSurface();
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200191
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100192 void release();
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200193
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100194 void makeCurrent();
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200195
Magnus Jedvert4ae28a12015-09-15 09:44:07 +0200196 // Detach the current EGL context, so that it can be made current on another thread.
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100197 void detachCurrent();
Magnus Jedvert4ae28a12015-09-15 09:44:07 +0200198
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100199 void swapBuffers();
magjed47815522017-08-25 06:28:00 -0700200
Sami Kalliomäkib9f3f9b2017-11-30 11:23:33 +0100201 void swapBuffers(long presentationTimeStampNs);
Magnus Jedvert80cf97c2015-06-11 10:08:59 +0200202}