我有一部带有 type-c 端口的安卓手机,它可以连接到外部显示器。我想使用 Opengles 将一些 drm 内容渲染到外部显示器,所以我使用“EGL_PROTECTED_CONTENT_EXT”标志创建受保护的 EGLContext 和 EGLSurface。它在手机屏幕上运行良好,但在连接的外部显示器上无法运行。
添加 logcat 文件:
没有受保护的表面: https ://drive.google.com/file/d/14Dmj1flVXqb8tCqUgS8hcwz58pTbmDqv/view?usp=sharing
受保护的表面:https ://drive.google.com/file/d/15p3lmy1siZ5uSVUcDzu7trX7u5a7E8ti/view?usp=sharing
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Presentation;
import android.hardware.display.DisplayManager;
import android.opengl.EGL14;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.text.Layout;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL10;
public class MainActivity extends AppCompatActivity {
private static String TAG = "MainActivity";
Presentation presentation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showPresentation(true);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
}
private static final int EGL_PROTECTED_CONTENT_EXT = 0x32C0;
private void showPresentation(boolean requireSecureContext){
Log.d(TAG, "begin showPresentation " + requireSecureContext);
DisplayManager displayManager = (DisplayManager) getSystemService(DISPLAY_SERVICE);
Display displays[] = displayManager.getDisplays();
if(displays.length == 1){
Toast.makeText(this, "can not find external display", Toast.LENGTH_LONG);
return;
}
Log.d(TAG, "showPresentation at displayID:" + displays[displays.length-1].getDisplayId());
presentation = new Presentation(this, displays[displays.length-1]);
GLSurfaceView surfaceView = new GLSurfaceView(this);
surfaceView.setSecure(true);
surfaceView.setEGLContextClientVersion(2);
surfaceView.setEGLConfigChooser(8, 8, 8, 8, 8, 0);
surfaceView.setEGLContextClientVersion(3);
surfaceView.setKeepScreenOn(true);
surfaceView.setEGLContextFactory(
new GLSurfaceView.EGLContextFactory() {
@Override
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
int[] glAttributes;
if (requireSecureContext) {
glAttributes =
new int[] {
EGL14.EGL_CONTEXT_CLIENT_VERSION,
3,
EGL_PROTECTED_CONTENT_EXT,
EGL14.EGL_TRUE,
EGL10.EGL_NONE
};
} else {
glAttributes = new int[] {EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE};
}
return egl.eglCreateContext(
display, eglConfig, /* share_context= */ EGL10.EGL_NO_CONTEXT, glAttributes);
}
@Override
public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
egl.eglDestroyContext(display, context);
}
});
surfaceView.setEGLWindowSurfaceFactory(
new GLSurfaceView.EGLWindowSurfaceFactory() {
@Override
public EGLSurface createWindowSurface(
EGL10 egl, EGLDisplay display, EGLConfig config, Object nativeWindow) {
int[] attribsList =
requireSecureContext
? new int[] {EGL_PROTECTED_CONTENT_EXT, EGL14.EGL_TRUE, EGL10.EGL_NONE}
: new int[] {EGL10.EGL_NONE};
return egl.eglCreateWindowSurface(display, config, nativeWindow, attribsList);
}
@Override
public void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface) {
egl.eglDestroySurface(display, surface);
}
});
surfaceView.setRenderer(new GLSurfaceView.Renderer() {
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
}
@Override
public void onSurfaceChanged(GL10 gl10, int i, int i1) {
}
@Override
public void onDrawFrame(GL10 gl10) {
GLES20.glClearColor(1.f, 0.f,0.f,1.f);
GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
}
});
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
}
});
presentation.setContentView(surfaceView);
presentation.show();
presentation.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
Log.d(TAG, "showPresentation end");
}
}