192 lines
5.1 KiB
Java
192 lines
5.1 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.opengl.GLES20;
|
|
import android.opengl.Matrix;
|
|
|
|
import com.serenegiant.utils.Time;
|
|
|
|
/**
|
|
* 同じ内容のクラスだったからEffectRendererHolder/RendererHolderのインナークラスを外に出した
|
|
*/
|
|
class RendererSurfaceRec {
|
|
|
|
/**
|
|
* ファクトリーメソッド
|
|
* @param egl
|
|
* @param surface
|
|
* @param maxFps 0以下なら最大描画フレームレート制限なし, あまり正確じゃない
|
|
* @return
|
|
*/
|
|
static RendererSurfaceRec newInstance(final EGLBase egl,
|
|
final Object surface, final int maxFps) {
|
|
|
|
return (maxFps > 0)
|
|
? new RendererSurfaceRecHasWait(egl, surface, maxFps)
|
|
: new RendererSurfaceRec(egl, surface); // no limitation of maxFps
|
|
}
|
|
|
|
/** 元々の分配描画用Surface */
|
|
private Object mSurface;
|
|
/** 分配描画用Surfaceを元に生成したOpenGL|ESで描画する為のEglSurface */
|
|
private EGLBase.IEglSurface mTargetSurface;
|
|
final float[] mMvpMatrix = new float[16];
|
|
protected volatile boolean mEnable = true;
|
|
|
|
/**
|
|
* コンストラクタ, ファクトリーメソッドの使用を強制するためprivate
|
|
* @param egl
|
|
* @param surface
|
|
*/
|
|
private RendererSurfaceRec(final EGLBase egl, final Object surface) {
|
|
mSurface = surface;
|
|
mTargetSurface = egl.createFromSurface(surface);
|
|
Matrix.setIdentityM(mMvpMatrix, 0);
|
|
}
|
|
|
|
/**
|
|
* 生成したEglSurfaceを破棄する
|
|
*/
|
|
public void release() {
|
|
if (mTargetSurface != null) {
|
|
mTargetSurface.release();
|
|
mTargetSurface = null;
|
|
}
|
|
mSurface = null;
|
|
}
|
|
|
|
/**
|
|
* Surfaceが有効かどうかを取得する
|
|
* @return
|
|
*/
|
|
public boolean isValid() {
|
|
return (mTargetSurface != null) && mTargetSurface.isValid();
|
|
}
|
|
|
|
private void check() throws IllegalStateException {
|
|
if (mTargetSurface == null) {
|
|
throw new IllegalStateException("already released");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Surfaceへの描画が有効かどうかを取得する
|
|
* @return
|
|
*/
|
|
public boolean isEnabled() {
|
|
return mEnable;
|
|
}
|
|
|
|
/**
|
|
* Surfaceへの描画を一時的に有効/無効にする
|
|
* @param enable
|
|
*/
|
|
public void setEnabled(final boolean enable) {
|
|
mEnable = enable;
|
|
}
|
|
|
|
public boolean canDraw() {
|
|
return mEnable;
|
|
}
|
|
|
|
public void draw(final GLDrawer2D drawer, final int textId, final float[] texMatrix) {
|
|
if (mTargetSurface != null) {
|
|
mTargetSurface.makeCurrent();
|
|
// 本来は映像が全面に描画されるので#glClearでクリアする必要はないけど
|
|
// ハングアップする機種があるのでクリアしとく
|
|
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
|
drawer.setMvpMatrix(mMvpMatrix, 0);
|
|
drawer.draw(textId, texMatrix, 0);
|
|
mTargetSurface.swap();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 指定した色で全面を塗りつぶす
|
|
* @param color
|
|
*/
|
|
public void clear(final int color) {
|
|
if (mTargetSurface != null) {
|
|
mTargetSurface.makeCurrent();
|
|
GLES20.glClearColor(
|
|
((color & 0x00ff0000) >>> 16) / 255.0f, // R
|
|
((color & 0x0000ff00) >>> 8) / 255.0f, // G
|
|
((color & 0x000000ff)) / 255.0f, // B
|
|
((color & 0xff000000) >>> 24) / 255.0f // A
|
|
);
|
|
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
|
mTargetSurface.swap();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* #drawの代わりにOpenGL|ES2を使って自前で描画する場合は
|
|
* #makeCurrentでレンダリングコンテキストを切り替えてから
|
|
* 描画後#swapを呼ぶ
|
|
*/
|
|
public void makeCurrent() throws IllegalStateException {
|
|
check();
|
|
mTargetSurface.makeCurrent();
|
|
}
|
|
|
|
/**
|
|
* #drawの代わりにOpenGL|ES2を使って自前で描画する場合は
|
|
* #makeCurrentでレンダリングコンテキストを切り替えてから
|
|
* 描画後#swapを呼ぶ
|
|
*/
|
|
public void swap() throws IllegalStateException {
|
|
check();
|
|
mTargetSurface.swap();
|
|
}
|
|
|
|
private static class RendererSurfaceRecHasWait extends RendererSurfaceRec {
|
|
private long mNextDraw;
|
|
private final long mIntervalsNs;
|
|
|
|
/**
|
|
* コンストラクタ, ファクトリーメソッドの使用を強制するためprivate
|
|
* @param egl
|
|
* @param surface
|
|
* @param maxFps 正数
|
|
*/
|
|
private RendererSurfaceRecHasWait(final EGLBase egl,
|
|
final Object surface, final int maxFps) {
|
|
|
|
super(egl, surface);
|
|
mIntervalsNs = 1000000000L / maxFps;
|
|
mNextDraw = Time.nanoTime() + mIntervalsNs;
|
|
}
|
|
|
|
@Override
|
|
public boolean canDraw() {
|
|
return mEnable && (Time.nanoTime() - mNextDraw > 0);
|
|
}
|
|
|
|
@Override
|
|
public void draw(final GLDrawer2D drawer,
|
|
final int textId, final float[] texMatrix) {
|
|
|
|
mNextDraw = Time.nanoTime() + mIntervalsNs;
|
|
super.draw(drawer, textId, texMatrix);
|
|
}
|
|
}
|
|
|
|
}
|