Change-Id: I55c360372623c019da0c1ba2eebbc68f73f0f211 Signed-off-by: David Li <davidxli@google.com>
236 lines
8.6 KiB
Java
236 lines
8.6 KiB
Java
/*
|
|
** Copyright 2011, The Android Open Source Project
|
|
**
|
|
** 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.
|
|
*/
|
|
|
|
package com.android.glesv2debugger;
|
|
|
|
import com.android.glesv2debugger.DebuggerMessage.Message;
|
|
import com.android.sdklib.util.SparseArray;
|
|
|
|
import java.nio.ByteBuffer;
|
|
import java.util.ArrayList;
|
|
|
|
class GLTexture implements Cloneable {
|
|
public final int name;
|
|
public final GLEnum target;
|
|
public ArrayList<Message> contentChanges = new ArrayList<Message>();
|
|
public GLEnum wrapS = GLEnum.GL_REPEAT, wrapT = GLEnum.GL_REPEAT;
|
|
public GLEnum min = GLEnum.GL_NEAREST_MIPMAP_LINEAR;
|
|
public GLEnum mag = GLEnum.GL_LINEAR;
|
|
public GLEnum format;
|
|
public int width, height;
|
|
|
|
GLTexture(final int name, final GLEnum target) {
|
|
this.name = name;
|
|
this.target = target;
|
|
}
|
|
|
|
@Override
|
|
public GLTexture clone() {
|
|
try {
|
|
GLTexture copy = (GLTexture) super.clone();
|
|
copy.contentChanges = (ArrayList<Message>) contentChanges.clone();
|
|
return copy;
|
|
} catch (CloneNotSupportedException e) {
|
|
e.printStackTrace();
|
|
assert false;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
boolean processMessage(final Message msg) {
|
|
switch (msg.getFunction()) {
|
|
case glCompressedTexImage2D:
|
|
case glCopyTexImage2D:
|
|
case glTexImage2D:
|
|
if (msg.getArg1() == 0) { // level 0
|
|
format = GLEnum.valueOf(msg.getArg2());
|
|
width = msg.getArg3();
|
|
height = msg.getArg4();
|
|
}
|
|
//$FALL-THROUGH$
|
|
case glCompressedTexSubImage2D:
|
|
case glCopyTexSubImage2D:
|
|
case glTexSubImage2D:
|
|
case glGenerateMipmap:
|
|
contentChanges.add(msg);
|
|
break;
|
|
default:
|
|
assert false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return String.format("%s %s %d*%d %d change(s)", target, format, width, height,
|
|
contentChanges.size());
|
|
}
|
|
}
|
|
|
|
public class GLServerTexture implements Cloneable {
|
|
Context context;
|
|
|
|
public GLEnum activeTexture = GLEnum.GL_TEXTURE0;
|
|
public int[] tmu2D;
|
|
public int[] tmuCube;
|
|
public SparseArray<GLTexture> textures = new SparseArray<GLTexture>();
|
|
public GLTexture tex2D = null, texCube = null;
|
|
|
|
GLServerTexture(final Context context, final int MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
|
|
this.context = context;
|
|
textures.append(0, null);
|
|
tmu2D = new int[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
|
|
tmuCube = new int[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
|
|
}
|
|
|
|
public GLServerTexture clone(final Context copyContext) {
|
|
try {
|
|
GLServerTexture copy = (GLServerTexture) super.clone();
|
|
copy.context = copyContext;
|
|
|
|
copy.tmu2D = tmu2D.clone();
|
|
copy.tmuCube = tmuCube.clone();
|
|
|
|
copy.textures = new SparseArray<GLTexture>(textures.size());
|
|
for (int i = 0; i < textures.size(); i++)
|
|
if (textures.valueAt(i) != null)
|
|
copy.textures.append(textures.keyAt(i), textures.valueAt(i).clone());
|
|
else
|
|
copy.textures.append(textures.keyAt(i), null);
|
|
|
|
if (tex2D != null)
|
|
copy.tex2D = copy.textures.get(tex2D.name);
|
|
if (texCube != null)
|
|
copy.texCube = copy.textures.get(texCube.name);
|
|
|
|
return copy;
|
|
} catch (CloneNotSupportedException e) {
|
|
e.printStackTrace();
|
|
assert false;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public boolean processMessage(final Message msg) {
|
|
switch (msg.getFunction()) {
|
|
case glActiveTexture:
|
|
activeTexture = GLEnum.valueOf(msg.getArg0());
|
|
return true;
|
|
case glBindTexture:
|
|
return bindTexture(msg.getArg0(), msg.getArg1());
|
|
case glCompressedTexImage2D:
|
|
case glCompressedTexSubImage2D:
|
|
case glCopyTexImage2D:
|
|
case glCopyTexSubImage2D:
|
|
case glTexImage2D:
|
|
case glTexSubImage2D:
|
|
switch (GLEnum.valueOf(msg.getArg0())) {
|
|
case GL_TEXTURE_2D:
|
|
if (tex2D != null)
|
|
return tex2D.processMessage(msg);
|
|
return true;
|
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
|
if (texCube != null)
|
|
return texCube.processMessage(msg);
|
|
return true;
|
|
default:
|
|
return true;
|
|
}
|
|
case glDeleteTextures: {
|
|
final ByteBuffer names = msg.getData().asReadOnlyByteBuffer();
|
|
names.order(SampleView.targetByteOrder);
|
|
for (int i = 0; i < msg.getArg0(); i++) {
|
|
final int name = names.getInt();
|
|
if (tex2D != null && tex2D.name == name)
|
|
bindTexture(GLEnum.GL_TEXTURE_2D.value, 0);
|
|
if (texCube != null && texCube.name == name)
|
|
bindTexture(GLEnum.GL_TEXTURE_CUBE_MAP.value, 0);
|
|
if (name != 0)
|
|
textures.remove(name);
|
|
}
|
|
return true;
|
|
}
|
|
case glGenerateMipmap:
|
|
if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_TEXTURE_2D && tex2D != null)
|
|
return tex2D.processMessage(msg);
|
|
else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_TEXTURE_CUBE_MAP
|
|
&& texCube != null)
|
|
return texCube.processMessage(msg);
|
|
return true;
|
|
case glTexParameteri:
|
|
return texParameter(msg.getArg0(), msg.getArg1(), msg.getArg2());
|
|
case glTexParameterf:
|
|
return texParameter(msg.getArg0(), msg.getArg1(),
|
|
(int) Float.intBitsToFloat(msg.getArg2()));
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
boolean bindTexture(final int target, final int name) {
|
|
final int index = activeTexture.value - GLEnum.GL_TEXTURE0.value;
|
|
if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_2D) {
|
|
tex2D = textures.get(name);
|
|
if (name != 0 && tex2D == null)
|
|
textures.put(name, tex2D = new GLTexture(name,
|
|
GLEnum.GL_TEXTURE_2D));
|
|
if (index >= 0 && index < tmu2D.length)
|
|
tmu2D[index] = name;
|
|
} else if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_CUBE_MAP) {
|
|
texCube = textures.get(name);
|
|
if (name != 0 && texCube == null)
|
|
textures.put(name, texCube = new GLTexture(name,
|
|
GLEnum.GL_TEXTURE_CUBE_MAP));
|
|
if (index >= 0 && index < tmu2D.length)
|
|
tmu2D[index] = name;
|
|
} else
|
|
assert false;
|
|
return true;
|
|
}
|
|
|
|
boolean texParameter(final int target, final int pname, final int param) {
|
|
GLTexture tex = null;
|
|
if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_2D)
|
|
tex = tex2D;
|
|
else if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_CUBE_MAP)
|
|
tex = texCube;
|
|
if (tex == null)
|
|
return true;
|
|
final GLEnum p = GLEnum.valueOf(param);
|
|
switch (GLEnum.valueOf(pname)) {
|
|
case GL_TEXTURE_WRAP_S:
|
|
tex.wrapS = p;
|
|
return true;
|
|
case GL_TEXTURE_WRAP_T:
|
|
tex.wrapT = p;
|
|
return true;
|
|
case GL_TEXTURE_MIN_FILTER:
|
|
tex.min = p;
|
|
return true;
|
|
case GL_TEXTURE_MAG_FILTER:
|
|
tex.mag = p;
|
|
return true;
|
|
default:
|
|
return true;
|
|
}
|
|
}
|
|
}
|