Files
platform-external-webrtc/sdk/android/api/org/webrtc/EglBase.java
Magnus Jedvert 98d85fe9a4 Android: Expose underlying EGL context in API
This CL adds a way to extract the underlying android.opengl.EGLContext
and javax.microedition.khronos.egl.EGLContext for EglBase14 and
EglBase10 respectively. The reason is that clients can't be expected to
use only WebRTC's OpenGL code and might need to integrate with their
own GL code.

Bug: None
Change-Id: Ie00a564de45a090683542a52005da7e43c586ced
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/127888
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27205}
2019-03-20 11:26:19 +00:00

203 lines
7.1 KiB
Java

/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
package org.webrtc;
import android.graphics.SurfaceTexture;
import android.support.annotation.Nullable;
import android.view.Surface;
import javax.microedition.khronos.egl.EGL10;
/**
* Holds EGL state and utility methods for handling an egl 1.0 EGLContext, an EGLDisplay,
* and an EGLSurface.
*/
public interface EglBase {
// EGL wrapper for an actual EGLContext.
public interface Context {
public final static long NO_CONTEXT = 0;
/**
* Returns an EGL context that can be used by native code. Returns NO_CONTEXT if the method is
* unsupported.
*
* @note This is currently only supported for EGL 1.4 and not for EGL 1.0.
*/
long getNativeEglContext();
}
// According to the documentation, EGL can be used from multiple threads at the same time if each
// thread has its own EGLContext, but in practice it deadlocks on some devices when doing this.
// Therefore, synchronize on this global lock before calling dangerous EGL functions that might
// deadlock. See https://bugs.chromium.org/p/webrtc/issues/detail?id=5702 for more info.
public static final Object lock = new Object();
// These constants are taken from EGL14.EGL_OPENGL_ES2_BIT and EGL14.EGL_CONTEXT_CLIENT_VERSION.
// https://android.googlesource.com/platform/frameworks/base/+/master/opengl/java/android/opengl/EGL14.java
// This is similar to how GlSurfaceView does:
// http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/opengl/GLSurfaceView.java#760
public static final int EGL_OPENGL_ES2_BIT = 4;
// Android-specific extension.
public static final int EGL_RECORDABLE_ANDROID = 0x3142;
// clang-format off
public static final int[] CONFIG_PLAIN = {
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE
};
public static final int[] CONFIG_RGBA = {
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_ALPHA_SIZE, 8,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE
};
public static final int[] CONFIG_PIXEL_BUFFER = {
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT,
EGL10.EGL_NONE
};
public static final int[] CONFIG_PIXEL_RGBA_BUFFER = {
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_ALPHA_SIZE, 8,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT,
EGL10.EGL_NONE
};
public static final int[] CONFIG_RECORDABLE = {
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RECORDABLE_ANDROID, 1,
EGL10.EGL_NONE
};
// clang-format on
/**
* Create a new context with the specified config attributes, sharing data with |sharedContext|.
* If |sharedContext| is null, a root context is created. This function will try to create an EGL
* 1.4 context if possible, and an EGL 1.0 context otherwise.
*/
public static EglBase create(@Nullable Context sharedContext, int[] configAttributes) {
if (sharedContext == null) {
return EglBase14Impl.isEGL14Supported() ? createEgl14(configAttributes)
: createEgl10(configAttributes);
} else if (sharedContext instanceof EglBase14.Context) {
return createEgl14((EglBase14.Context) sharedContext, configAttributes);
} else if (sharedContext instanceof EglBase10.Context) {
return createEgl10((EglBase10.Context) sharedContext, configAttributes);
}
throw new IllegalArgumentException("Unrecognized Context");
}
/**
* Helper function for creating a plain root context. This function will try to create an EGL 1.4
* context if possible, and an EGL 1.0 context otherwise.
*/
public static EglBase create() {
return create(null /* shaderContext */, CONFIG_PLAIN);
}
/**
* Helper function for creating a plain context, sharing data with |sharedContext|. This function
* will try to create an EGL 1.4 context if possible, and an EGL 1.0 context otherwise.
*/
public static EglBase create(Context sharedContext) {
return create(sharedContext, CONFIG_PLAIN);
}
/** Explicitly create a root EGl 1.0 context with the specified config attributes. */
public static EglBase10 createEgl10(int[] configAttributes) {
return new EglBase10Impl(/* sharedContext= */ null, configAttributes);
}
/**
* Explicitly create a root EGl 1.0 context with the specified config attributes and shared
* context.
*/
public static EglBase10 createEgl10(EglBase10.Context sharedContext, int[] configAttributes) {
return new EglBase10Impl(
sharedContext == null ? null : sharedContext.getRawContext(), configAttributes);
}
/**
* Explicitly create a root EGl 1.0 context with the specified config attributes
* and shared context.
*/
public static EglBase10 createEgl10(
javax.microedition.khronos.egl.EGLContext sharedContext, int[] configAttributes) {
return new EglBase10Impl(sharedContext, configAttributes);
}
/** Explicitly create a root EGl 1.4 context with the specified config attributes. */
public static EglBase14 createEgl14(int[] configAttributes) {
return new EglBase14Impl(/* sharedContext= */ null, configAttributes);
}
/**
* Explicitly create a root EGl 1.4 context with the specified config attributes and shared
* context.
*/
public static EglBase14 createEgl14(EglBase14.Context sharedContext, int[] configAttributes) {
return new EglBase14Impl(
sharedContext == null ? null : sharedContext.getRawContext(), configAttributes);
}
/**
* Explicitly create a root EGl 1.4 context with the specified config attributes
* and shared context.
*/
public static EglBase14 createEgl14(
android.opengl.EGLContext sharedContext, int[] configAttributes) {
return new EglBase14Impl(sharedContext, configAttributes);
}
void createSurface(Surface surface);
// Create EGLSurface from the Android SurfaceTexture.
void createSurface(SurfaceTexture surfaceTexture);
// Create dummy 1x1 pixel buffer surface so the context can be made current.
void createDummyPbufferSurface();
void createPbufferSurface(int width, int height);
Context getEglBaseContext();
boolean hasSurface();
int surfaceWidth();
int surfaceHeight();
void releaseSurface();
void release();
void makeCurrent();
// Detach the current EGL context, so that it can be made current on another thread.
void detachCurrent();
void swapBuffers();
void swapBuffers(long presentationTimeStampNs);
}