Home | History | Annotate | Download | only in gldebugger
      1 /*
      2  ** Copyright 2011, The Android Open Source Project
      3  **
      4  ** Licensed under the Apache License, Version 2.0 (the "License");
      5  ** you may not use this file except in compliance with the License.
      6  ** You may obtain a copy of the License at
      7  **
      8  **     http://www.apache.org/licenses/LICENSE-2.0
      9  **
     10  ** Unless required by applicable law or agreed to in writing, software
     11  ** distributed under the License is distributed on an "AS IS" BASIS,
     12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 
     17 package com.android.ide.eclipse.gldebugger;
     18 
     19 import com.android.ide.eclipse.gldebugger.DebuggerMessage.Message;
     20 import com.android.sdklib.util.SparseArray;
     21 
     22 import java.nio.ByteBuffer;
     23 import java.util.ArrayList;
     24 
     25 class GLTexture implements Cloneable {
     26     public final int name;
     27     public final GLEnum target;
     28     public ArrayList<Message> contentChanges = new ArrayList<Message>();
     29     public GLEnum wrapS = GLEnum.GL_REPEAT, wrapT = GLEnum.GL_REPEAT;
     30     public GLEnum min = GLEnum.GL_NEAREST_MIPMAP_LINEAR;
     31     public GLEnum mag = GLEnum.GL_LINEAR;
     32     public GLEnum format;
     33     public int width, height;
     34 
     35     GLTexture(final int name, final GLEnum target) {
     36         this.name = name;
     37         this.target = target;
     38     }
     39 
     40     @Override
     41     public GLTexture clone() {
     42         try {
     43             GLTexture copy = (GLTexture) super.clone();
     44             copy.contentChanges = (ArrayList<Message>) contentChanges.clone();
     45             return copy;
     46         } catch (CloneNotSupportedException e) {
     47             e.printStackTrace();
     48             assert false;
     49             return null;
     50         }
     51     }
     52 
     53     boolean processMessage(final Message msg) {
     54         switch (msg.getFunction()) {
     55             case glCompressedTexImage2D:
     56             case glCopyTexImage2D:
     57             case glTexImage2D:
     58                 if (msg.getArg1() == 0) { // level 0
     59                     format = GLEnum.valueOf(msg.getArg2());
     60                     width = msg.getArg3();
     61                     height = msg.getArg4();
     62                 }
     63                 //$FALL-THROUGH$
     64             case glCompressedTexSubImage2D:
     65             case glCopyTexSubImage2D:
     66             case glTexSubImage2D:
     67             case glGenerateMipmap:
     68                 contentChanges.add(msg);
     69                 break;
     70             default:
     71                 assert false;
     72         }
     73         return true;
     74     }
     75 
     76     @Override
     77     public String toString() {
     78         return String.format("%s %s %d*%d %d change(s)", target, format, width, height,
     79                 contentChanges.size());
     80     }
     81 }
     82 
     83 public class GLServerTexture implements Cloneable {
     84     Context context;
     85 
     86     public GLEnum activeTexture = GLEnum.GL_TEXTURE0;
     87     public int[] tmu2D;
     88     public int[] tmuCube;
     89     public SparseArray<GLTexture> textures = new SparseArray<GLTexture>();
     90     public GLTexture tex2D = null, texCube = null;
     91 
     92     GLServerTexture(final Context context, final int MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
     93         this.context = context;
     94         textures.append(0, null);
     95         tmu2D = new int[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
     96         tmuCube = new int[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
     97     }
     98 
     99     public GLServerTexture clone(final Context copyContext) {
    100         try {
    101             GLServerTexture copy = (GLServerTexture) super.clone();
    102             copy.context = copyContext;
    103 
    104             copy.tmu2D = tmu2D.clone();
    105             copy.tmuCube = tmuCube.clone();
    106 
    107             copy.textures = new SparseArray<GLTexture>(textures.size());
    108             for (int i = 0; i < textures.size(); i++)
    109                 if (textures.valueAt(i) != null)
    110                     copy.textures.append(textures.keyAt(i), textures.valueAt(i).clone());
    111                 else
    112                     copy.textures.append(textures.keyAt(i), null);
    113 
    114             if (tex2D != null)
    115                 copy.tex2D = copy.textures.get(tex2D.name);
    116             if (texCube != null)
    117                 copy.texCube = copy.textures.get(texCube.name);
    118 
    119             return copy;
    120         } catch (CloneNotSupportedException e) {
    121             e.printStackTrace();
    122             assert false;
    123             return null;
    124         }
    125     }
    126 
    127     public boolean processMessage(final Message msg) {
    128         switch (msg.getFunction()) {
    129             case glActiveTexture:
    130                 activeTexture = GLEnum.valueOf(msg.getArg0());
    131                 return true;
    132             case glBindTexture:
    133                 return bindTexture(msg.getArg0(), msg.getArg1());
    134             case glCompressedTexImage2D:
    135             case glCompressedTexSubImage2D:
    136             case glCopyTexImage2D:
    137             case glCopyTexSubImage2D:
    138             case glTexImage2D:
    139             case glTexSubImage2D:
    140                 switch (GLEnum.valueOf(msg.getArg0())) {
    141                     case GL_TEXTURE_2D:
    142                         if (tex2D != null)
    143                             return tex2D.processMessage(msg);
    144                         return true;
    145                     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
    146                     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
    147                     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
    148                     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
    149                     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
    150                     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
    151                         if (texCube != null)
    152                             return texCube.processMessage(msg);
    153                         return true;
    154                     default:
    155                         return true;
    156                 }
    157             case glDeleteTextures: {
    158                 final ByteBuffer names = msg.getData().asReadOnlyByteBuffer();
    159                 names.order(GLFramesView.TARGET_BYTE_ORDER);
    160                 for (int i = 0; i < msg.getArg0(); i++) {
    161                     final int name = names.getInt();
    162                     if (tex2D != null && tex2D.name == name)
    163                         bindTexture(GLEnum.GL_TEXTURE_2D.value, 0);
    164                     if (texCube != null && texCube.name == name)
    165                         bindTexture(GLEnum.GL_TEXTURE_CUBE_MAP.value, 0);
    166                     if (name != 0)
    167                         textures.remove(name);
    168                 }
    169                 return true;
    170             }
    171             case glGenerateMipmap:
    172                 if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_TEXTURE_2D && tex2D != null)
    173                     return tex2D.processMessage(msg);
    174                 else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_TEXTURE_CUBE_MAP
    175                         && texCube != null)
    176                     return texCube.processMessage(msg);
    177                 return true;
    178             case glTexParameteri:
    179                 return texParameter(msg.getArg0(), msg.getArg1(), msg.getArg2());
    180             case glTexParameterf:
    181                 return texParameter(msg.getArg0(), msg.getArg1(),
    182                         (int) Float.intBitsToFloat(msg.getArg2()));
    183             default:
    184                 return false;
    185         }
    186     }
    187 
    188     boolean bindTexture(final int target, final int name) {
    189         final int index = activeTexture.value - GLEnum.GL_TEXTURE0.value;
    190         if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_2D) {
    191             tex2D = textures.get(name);
    192             if (name != 0 && tex2D == null)
    193                 textures.put(name, tex2D = new GLTexture(name,
    194                         GLEnum.GL_TEXTURE_2D));
    195             if (index >= 0 && index < tmu2D.length)
    196                 tmu2D[index] = name;
    197         } else if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_CUBE_MAP) {
    198             texCube = textures.get(name);
    199             if (name != 0 && texCube == null)
    200                 textures.put(name, texCube = new GLTexture(name,
    201                         GLEnum.GL_TEXTURE_CUBE_MAP));
    202             if (index >= 0 && index < tmu2D.length)
    203                 tmu2D[index] = name;
    204         } else
    205             assert false;
    206         return true;
    207     }
    208 
    209     boolean texParameter(final int target, final int pname, final int param) {
    210         GLTexture tex = null;
    211         if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_2D)
    212             tex = tex2D;
    213         else if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_CUBE_MAP)
    214             tex = texCube;
    215         if (tex == null)
    216             return true;
    217         final GLEnum p = GLEnum.valueOf(param);
    218         switch (GLEnum.valueOf(pname)) {
    219             case GL_TEXTURE_WRAP_S:
    220                 tex.wrapS = p;
    221                 return true;
    222             case GL_TEXTURE_WRAP_T:
    223                 tex.wrapT = p;
    224                 return true;
    225             case GL_TEXTURE_MIN_FILTER:
    226                 tex.min = p;
    227                 return true;
    228             case GL_TEXTURE_MAG_FILTER:
    229                 tex.mag = p;
    230                 return true;
    231             default:
    232                 return true;
    233         }
    234     }
    235 }
    236