Files
MoGoEagleEye/libraries/map-usbcamera/src/main/java/com/serenegiant/glutils/DumbRenderer.java
donghongyu cdee266805 [Change]
开始USB摄像头的功能集成,还无法获取usb连接广播需要调试

Signed-off-by: donghongyu <donghongyu@zhidaoauto.com>
(cherry picked from commit b10306fc45)
2022-02-15 14:26:43 +08:00

249 lines
6.2 KiB
Java

package com.serenegiant.glutils;
/*
* libcommon
* utility/helper classes for myself
*
* Copyright (c) 2014-2018 saki t_saki@serenegiant.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.graphics.SurfaceTexture;
import android.util.Log;
import android.view.Surface;
import androidx.annotation.NonNull;
/**
* OpenGL|ESでのSurfaceへの描画処理をDelegaterを介して行うためのIRenderer
*/
public class DumbRenderer implements IRenderer {
// private static final boolean DEBUG = BuildConfig.DEBUG && false;
private static final String TAG = DumbRenderer.class.getSimpleName();
public interface RendererDelegater {
public void onStart(final EGLBase eglBase);
public void onStop(final EGLBase eglBase);
public void onSetSurface(final EGLBase eglBase, final Object surface);
public void onResize(final EGLBase eglBase, final int width, final int height);
/**
* 描画実行
* @param eglBase
* @param args #requestRenderの引数
*/
public void onDraw(final EGLBase eglBase, final Object... args);
public void onMirror(final EGLBase eglBase, final int mirror);
}
/** レンダリングスレッドの排他制御用オブジェクト */
private final Object mSync = new Object();
private RendererTask mRendererTask;
@MirrorMode
private int mMirror = MIRROR_NORMAL;
public DumbRenderer(final EGLBase.IContext sharedContext,
final int flags, final RendererDelegater delegater) {
this(3, sharedContext, flags, delegater);
}
public DumbRenderer(final int maxClientVersion,
final EGLBase.IContext sharedContext,
final int flags, final RendererDelegater delegater) {
mRendererTask = new RendererTask(maxClientVersion, sharedContext, flags, delegater);
new Thread(mRendererTask, TAG).start();
if (!mRendererTask.waitReady()) {
// 初期化に失敗した時
throw new RuntimeException("failed to start renderer thread");
}
}
@Override
public void release() {
synchronized (mSync) {
if (mRendererTask != null) {
// 描画タスクを開放
mRendererTask.release();
mRendererTask = null;
}
}
}
@Override
public void setSurface(final Surface surface) {
synchronized (mSync) {
if (mRendererTask != null) {
mRendererTask.offer(REQUEST_SET_SURFACE, surface);
}
}
}
@Override
public void setSurface(final SurfaceTexture surface) {
synchronized (mSync) {
if (mRendererTask != null) {
mRendererTask.offer(REQUEST_SET_SURFACE, surface);
}
}
}
@Override
public void setMirror(@MirrorMode final int mirror) {
synchronized (mSync) {
if (mMirror != mirror) {
mMirror = mirror;
if (mRendererTask != null) {
mRendererTask.offer(REQUEST_MIRROR, mirror % 4);
}
}
}
}
@Override
@MirrorMode
public int getMirror() {
return mMirror;
}
@Override
public void resize(final int width, final int height) {
synchronized (mSync) {
if (mRendererTask != null) {
mRendererTask.offer(REQUEST_RESIZE, width, height);
}
}
}
@Override
public void requestRender(final Object... args) {
synchronized (mSync) {
if (mRendererTask != null) {
mRendererTask.offer(REQUEST_DRAW, args);
}
}
}
private static final int REQUEST_SET_SURFACE = 1;
private static final int REQUEST_DRAW = 2;
private static final int REQUEST_RESIZE = 3;
private static final int REQUEST_MIRROR = 4;
private static class RendererTask extends EglTask {
private final RendererDelegater mDelegater;
/** 最後にレンダリングしたフレームサイズ, 0ならまで一度も描画されていない */
private int frameWidth, frameHeight, frameRotation;
/** 描画先Surfaceのサイズ */
private int surfaceWidth, surfaceHeight;
/** 映像を左右反転させるかどうか */
private boolean mirror;
public RendererTask(final EGLBase.IContext sharedContext,
final int flags, @NonNull final RendererDelegater delegater) {
this(3, sharedContext, flags, delegater);
}
public RendererTask(final int maxClientVersion,
final EGLBase.IContext sharedContext,
final int flags, @NonNull final RendererDelegater delegater) {
super(maxClientVersion, sharedContext, flags);
mDelegater = delegater;
}
@Override
protected void onStart() {
makeCurrent();
try {
mDelegater.onStart(getEgl());
} catch (final Exception e) {
Log.w(TAG, e);
}
}
@Override
protected void onStop() {
makeCurrent();
try {
mDelegater.onStop(getEgl());
} catch (final Exception e) {
Log.w(TAG, e);
}
}
@Override
protected Object processRequest(final int request,
final int arg1, final int arg2, final Object obj) throws TaskBreak {
switch (request) {
case REQUEST_SET_SURFACE:
handleSetSurface(obj);
break;
case REQUEST_DRAW:
handleDraw(obj);
break;
case REQUEST_RESIZE:
handleResize(arg1, arg2);
break;
case REQUEST_MIRROR:
handleMirror(arg1);
break;
}
return null;
}
private void handleSetSurface(final Object surface) {
makeCurrent();
try {
mDelegater.onSetSurface(getEgl(), surface);
} catch (final Exception e) {
Log.w(TAG, e);
}
}
private void handleResize(final int width, final int height) {
if ((surfaceWidth != width) || (surfaceHeight != height)) {
surfaceWidth = width;
surfaceHeight = height;
makeCurrent();
try {
mDelegater.onResize(getEgl(), width, height);
} catch (final Exception e) {
Log.w(TAG, e);
}
handleDraw();
}
}
private void handleDraw(final Object... args) {
makeCurrent();
try {
mDelegater.onDraw(getEgl(), args);
} catch (final Exception e) {
Log.w(TAG, e);
}
}
private void handleMirror(final int mirror) {
makeCurrent();
try {
mDelegater.onMirror(getEgl(), mirror);
} catch (final Exception e) {
Log.w(TAG, e);
}
}
}
}