package com.glview.hwui;
import java.nio.IntBuffer;
import android.graphics.Bitmap.Config;
import android.graphics.Color;
import android.opengl.Matrix;
import com.glview.graphics.Bitmap;
import com.glview.libgdx.graphics.opengl.GL20;
import com.glview.utils.BufferUtils;
public class LayerRenderer extends GL20Canvas {
private static int MAX_LAYER_SIZE = (1024 * 1024);
static ThreadLocal<IntBuffer> sThreadLocal = new ThreadLocal<IntBuffer>() {
@Override
protected IntBuffer initialValue() {
return BufferUtils.newIntBuffer(1);
}
};
public LayerRenderer(GL20Canvas canvas) {
super(canvas.mRenderState);
}
@Override
public void setSize(int width, int height) {
super.setSize(width, height);
final float matrix[] = currentSnapshot().transform;
Matrix.setIdentityM(matrix, 0);
}
public boolean updateTextureLayer(Layer layer, Texture texture, RenderNode renderNode) {
final int size = texture.getWidth() * texture.getHeight();
if (size > MAX_LAYER_SIZE) return false;
final GL20 gl = mGL;
final IntBuffer handle = sThreadLocal.get();
handle.position(0);
gl.glGenFramebuffers(1, handle);
int framebufferHandle = handle.get(0);
gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, framebufferHandle);
gl.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER, GL20.GL_COLOR_ATTACHMENT0, GL20.GL_TEXTURE_2D,
texture.mId, 0);
int result = gl.glCheckFramebufferStatus(GL20.GL_FRAMEBUFFER);
if (result != GL20.GL_FRAMEBUFFER_COMPLETE) {
deleteFrameBuffer(framebufferHandle);
return false;
}
int preFrameBuffer = mRenderState.getFrameBuffer();
mRenderState.bindFrameBuffer(framebufferHandle);
beginFrame();
renderNode.renderWithoutLayer(this);
endFrame();
mRenderState.bindFrameBuffer(preFrameBuffer);
deleteFrameBuffer(framebufferHandle);
return true;
}
public Bitmap buildDrawingCache(Layer layer, Texture texture, RenderNode renderNode) {
final int size = texture.getWidth() * texture.getHeight();
if (size > MAX_LAYER_SIZE) return null;
final GL20 gl = mGL;
final IntBuffer handle = sThreadLocal.get();
handle.position(0);
gl.glGenFramebuffers(1, handle);
int framebufferHandle = handle.get(0);
gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, framebufferHandle);
gl.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER, GL20.GL_COLOR_ATTACHMENT0, GL20.GL_TEXTURE_2D,
texture.mId, 0);
int result = gl.glCheckFramebufferStatus(GL20.GL_FRAMEBUFFER);
if (result != GL20.GL_FRAMEBUFFER_COMPLETE) {
deleteFrameBuffer(framebufferHandle);
return null;
}
int preFrameBuffer = mRenderState.getFrameBuffer();
mRenderState.bindFrameBuffer(framebufferHandle);
beginFrame();
renderNode.renderWithoutLayer(this);
endFrame();
Bitmap bitmap = null;
int[] pixels = new int[size];
gl.glReadPixels(0, 0, texture.getWidth(), texture.getHeight(), GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, IntBuffer.wrap(pixels));
adaptBitmapFormat(pixels);
bitmap = Bitmap.createBitmap(pixels, texture.getWidth(), texture.getHeight(), Config.ARGB_8888);
mRenderState.bindFrameBuffer(preFrameBuffer);
deleteFrameBuffer(framebufferHandle);
return bitmap;
}
/**
* FIXME 耗时操作啊
* @param corlorArr
*/
private void adaptBitmapFormat(int corlorArr[]){
int vColor;
int count = corlorArr.length;
int r;
int g;
int b;
int a;
for(int i = 0; i < count; i++){
vColor = corlorArr[i];
a = Color.alpha(vColor);
b = Color.red(vColor);
g = Color.green(vColor);
r = Color.blue(vColor);
vColor = Color.argb(a, r, g, b);
corlorArr[i] = vColor;
}
}
private void deleteFrameBuffer(int framebufferHandle) {
final IntBuffer handle = sThreadLocal.get();
handle.put(0, framebufferHandle);
handle.position(0);
mGL.glDeleteFramebuffers(1, handle);
}
}