• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GLTexture(final int name, final GLEnum target)35     GLTexture(final int name, final GLEnum target) {
36         this.name = name;
37         this.target = target;
38     }
39 
40     @Override
clone()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 
processMessage(final Message msg)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
toString()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 
GLServerTexture(final Context context, final int MAX_COMBINED_TEXTURE_IMAGE_UNITS)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 
clone(final Context copyContext)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 
processMessage(final Message msg)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 
bindTexture(final int target, final int name)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 
texParameter(final int target, final int pname, final int param)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