package com.glview.hwui;
import java.nio.IntBuffer;
import android.util.Log;
import com.glview.App;
import com.glview.hwui.cache.FboCache;
import com.glview.hwui.cache.MeshCache;
import com.glview.hwui.cache.PatchCache;
import com.glview.hwui.cache.ProgramCache;
import com.glview.hwui.cache.Stencil;
import com.glview.hwui.cache.TextureCache;
import com.glview.libgdx.graphics.glutils.ShaderProgram;
import com.glview.libgdx.graphics.opengl.GL20;
import com.glview.thread.Looper;
import com.glview.utils.BufferUtils;
/**
* @hide
* @author lijing.lj
*/
public final class Caches {
static ThreadLocal<Caches> sThreadLocal = new ThreadLocal<Caches>() {
@Override
protected Caches initialValue() {
return new Caches();
}
};
// Must define as many texture units as specified by REQUIRED_TEXTURE_UNITS_COUNT
static final int gTextureUnits[] = {
GL20.GL_TEXTURE0,
GL20.GL_TEXTURE1,
GL20.GL_TEXTURE2
};
final GL20 mGL;
int maxTextureSize;
private Caches() {
mGL = App.getGL20();
scissorEnabled = mGL.glIsEnabled(GL20.GL_SCISSOR_TEST);
IntBuffer intbuf = BufferUtils.newIntBuffer(1);
mGL.glGetIntegerv(GL20.GL_MAX_TEXTURE_SIZE, intbuf);
maxTextureSize = intbuf.get(0);
}
public FboCache fboCache = new FboCache();
public TextureCache textureCache = new TextureCache();
public PatchCache patchCache = new PatchCache();
public MeshCache meshCache = new MeshCache();
public ProgramCache programCache = new ProgramCache();
public Stencil stencil = new Stencil();
public Extensions extensions = new Extensions();
IntBuffer mBuffer = BufferUtils.newIntBuffer(1);
public static Caches getInstance() {
if (Looper.myLooper() == RenderThread.getRenderThreadLooper()) {
CanvasContext.ensureEglManager();
return sThreadLocal.get();
} else {
throw new IllegalStateException("Only call from RenderThread.");
}
}
Texture mBindedTexture = null;
public void bindTexture(Texture texture) {
if (mBindedTexture != texture) {
mBindedTexture = texture;
mGL.glBindTexture(GL20.GL_TEXTURE_2D, texture.mId);
}
}
public void unbindTexture(Texture texture) {
if (mBindedTexture == texture) {
mBindedTexture = null;
mGL.glBindTexture(GL20.GL_TEXTURE_2D, 0);
}
}
public void deleteTexture(Texture texture) {
unbindTexture(texture);
if (texture.mId <= 0) return;
mBuffer.put(0, texture.mId);
mBuffer.position(0);
mGL.glDeleteTextures(1, mBuffer);
texture.mId = 0;
}
ShaderProgram mCurrentProgram = null;
public void useProgram(ShaderProgram program) {
if (mCurrentProgram != program) {
if (program != null) {
mGL.glUseProgram(program.getProgram());
} else {
mGL.glUseProgram(0);
}
mCurrentProgram = program;
} else if (mCurrentProgram != null && !mCurrentProgram.isCompiled()) {
mGL.glUseProgram(mCurrentProgram.getProgram());
}
}
public void clear() {
meshCache.clear();
textureCache.clear();
patchCache.clear();
programCache.clear();
}
///////////////////////////////////////////////////////////////////////////////
//Scissor
///////////////////////////////////////////////////////////////////////////////
boolean scissorEnabled;
int mScissorX;
int mScissorY;
int mScissorWidth;
int mScissorHeight;
boolean setScissor(int x, int y, int width, int height) {
if (scissorEnabled && (x != mScissorX || y != mScissorY ||
width != mScissorWidth || height != mScissorHeight)) {
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}
if (width < 0) {
width = 0;
}
if (height < 0) {
height = 0;
}
mGL.glScissor(x, y, width, height);
mScissorX = x;
mScissorY = y;
mScissorWidth = width;
mScissorHeight = height;
return true;
}
return false;
}
boolean enableScissor() {
if (!scissorEnabled) {
mGL.glEnable(GL20.GL_SCISSOR_TEST);
scissorEnabled = true;
resetScissor();
return true;
}
return false;
}
boolean disableScissor() {
if (scissorEnabled) {
mGL.glDisable(GL20.GL_SCISSOR_TEST);
scissorEnabled = false;
return true;
}
return false;
}
void setScissorEnabled(boolean enabled) {
if (scissorEnabled != enabled) {
if (enabled) mGL.glEnable(GL20.GL_SCISSOR_TEST);
else mGL.glDisable(GL20.GL_SCISSOR_TEST);
scissorEnabled = enabled;
}
}
void resetScissor() {
mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
}
}