• 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.glesv2debugger;
18 
19 import com.android.glesv2debugger.DebuggerMessage.Message;
20 import com.android.glesv2debugger.DebuggerMessage.Message.Function;
21 import com.android.sdklib.util.SparseArray;
22 import com.android.sdklib.util.SparseIntArray;
23 
24 class GLStencilState implements Cloneable {
25     public int ref, mask;
26     public GLEnum func;
27     public GLEnum sf, df, dp; // operation
28 
29     @Override
clone()30     public Object clone() {
31         try {
32             return super.clone();
33         } catch (CloneNotSupportedException e) {
34             e.printStackTrace();
35             return null;
36         }
37     }
38 }
39 
40 public class GLServerState implements Cloneable {
41     final Context context;
42     public GLStencilState front = new GLStencilState(), back = new GLStencilState();
43     public SparseIntArray enableDisables;
44 
45     /** integer states set via a GL function and GLEnum; keyed by GLEnum.value */
46     public SparseArray<Message> integers;
47 
48     /** states set only via a GL function; keyed by Function.getNumber() */
49     public SparseArray<Message> lastSetter;
50 
GLServerState(final Context context)51     GLServerState(final Context context) {
52         this.context = context;
53         enableDisables = new SparseIntArray();
54         enableDisables.put(GLEnum.GL_BLEND.value, 0);
55         enableDisables.put(GLEnum.GL_DITHER.value, 1);
56         enableDisables.put(GLEnum.GL_DEPTH_TEST.value, 0);
57         enableDisables.put(GLEnum.GL_STENCIL_TEST.value, 0);
58         enableDisables.put(GLEnum.GL_SCISSOR_TEST.value, 0);
59         enableDisables.put(GLEnum.GL_SAMPLE_COVERAGE.value, 0);
60         enableDisables.put(GLEnum.GL_SAMPLE_ALPHA_TO_COVERAGE.value, 0);
61         enableDisables.put(GLEnum.GL_POLYGON_OFFSET_FILL.value, 0);
62         enableDisables.put(GLEnum.GL_CULL_FACE.value, 0);
63         // enableDisables.put(GLEnum.GL_TEXTURE_2D.value, 1);
64 
65         lastSetter = new SparseArray<Message>();
66         lastSetter.put(Function.glBlendColor.getNumber(), null);
67         // glBlendEquation overwrites glBlendEquationSeparate
68         lastSetter.put(Function.glBlendEquationSeparate.getNumber(), null);
69         // glBlendFunc overwrites glBlendFuncSeparate
70         lastSetter.put(Function.glBlendFuncSeparate.getNumber(), null);
71         lastSetter.put(Function.glClearColor.getNumber(), null);
72         lastSetter.put(Function.glClearDepthf.getNumber(), null);
73         lastSetter.put(Function.glClearStencil.getNumber(), null);
74         lastSetter.put(Function.glColorMask.getNumber(), null);
75         lastSetter.put(Function.glCullFace.getNumber(), null);
76         lastSetter.put(Function.glDepthMask.getNumber(), null);
77         lastSetter.put(Function.glDepthFunc.getNumber(), null);
78         lastSetter.put(Function.glDepthRangef.getNumber(), null);
79         lastSetter.put(Function.glFrontFace.getNumber(), null);
80         lastSetter.put(Function.glLineWidth.getNumber(), null);
81         lastSetter.put(Function.glPolygonOffset.getNumber(), null);
82         lastSetter.put(Function.glSampleCoverage.getNumber(), null);
83         lastSetter.put(Function.glScissor.getNumber(), null);
84         lastSetter.put(Function.glStencilMaskSeparate.getNumber(), null);
85         lastSetter.put(Function.glViewport.getNumber(), null);
86 
87         integers = new SparseArray<Message>();
88         integers.put(GLEnum.GL_PACK_ALIGNMENT.value, null);
89         integers.put(GLEnum.GL_UNPACK_ALIGNMENT.value, null);
90     }
91 
92     /** returns true if processed */
processMessage(final Message msg)93     public boolean processMessage(final Message msg) {
94         switch (msg.getFunction()) {
95             case glBlendColor:
96             case glBlendEquation:
97             case glBlendEquationSeparate:
98             case glBlendFunc:
99             case glBlendFuncSeparate:
100             case glClearColor:
101             case glClearDepthf:
102             case glClearStencil:
103             case glColorMask:
104             case glCullFace:
105             case glDepthMask:
106             case glDepthFunc:
107             case glDepthRangef:
108                 return setter(msg);
109             case glDisable:
110                 return enableDisable(false, msg);
111             case glEnable:
112                 return enableDisable(true, msg);
113             case glFrontFace:
114             case glLineWidth:
115                 return setter(msg);
116             case glPixelStorei:
117                 if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_PACK_ALIGNMENT)
118                     integers.put(msg.getArg0(), msg);
119                 else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_UNPACK_ALIGNMENT)
120                     integers.put(msg.getArg0(), msg);
121                 else
122                     assert false;
123                 return true;
124             case glPolygonOffset:
125             case glSampleCoverage:
126             case glScissor:
127                 return setter(msg);
128             case glStencilFunc: {
129                 Message.Builder builder = msg.toBuilder();
130                 builder.setArg2(msg.getArg1());
131                 builder.setArg1(msg.getArg0());
132                 builder.setArg0(GLEnum.GL_FRONT_AND_BACK.value);
133                 return glStencilFuncSeparate(builder.build());
134             }
135             case glStencilFuncSeparate:
136                 return glStencilFuncSeparate(msg);
137             case glStencilMask:
138             case glStencilMaskSeparate:
139                 return setter(msg);
140             case glStencilOp: {
141                 Message.Builder builder = msg.toBuilder();
142                 builder.setArg3(msg.getArg2());
143                 builder.setArg2(msg.getArg1());
144                 builder.setArg1(msg.getArg0());
145                 builder.setArg0(GLEnum.GL_FRONT_AND_BACK.value);
146                 return glStencilOpSeparate(builder.build());
147             }
148             case glStencilOpSeparate:
149                 return glStencilOpSeparate(msg);
150             case glViewport:
151                 return setter(msg);
152             default:
153                 return false;
154         }
155     }
156 
setter(final Message msg)157     boolean setter(final Message msg) {
158         switch (msg.getFunction()) {
159             case glBlendFunc:
160                 lastSetter.put(Function.glBlendFuncSeparate.getNumber(), msg);
161                 break;
162             case glBlendEquation:
163                 lastSetter.put(Function.glBlendEquationSeparate.getNumber(), msg);
164                 break;
165             case glStencilMask:
166                 lastSetter.put(Function.glStencilMaskSeparate.getNumber(), msg);
167                 break;
168             default:
169                 lastSetter.put(msg.getFunction().getNumber(), msg);
170                 break;
171         }
172         return true;
173     }
174 
enableDisable(boolean enable, final Message msg)175     boolean enableDisable(boolean enable, final Message msg) {
176         int index = enableDisables.indexOfKey(msg.getArg0());
177         if (index < 0) {
178             System.out.print("invalid glDisable/Enable: ");
179             System.out.println(MessageFormatter.format(msg, false));
180             return true;
181         }
182         if ((enableDisables.valueAt(index) != 0) == enable)
183             return true; // TODO: redundant
184         enableDisables.put(msg.getArg0(), enable ? 1 : 0);
185         return true;
186     }
187 
188     // void StencilFuncSeparate( enum face, enum func, int ref, uint mask )
glStencilFuncSeparate(final Message msg)189     boolean glStencilFuncSeparate(final Message msg) {
190         GLEnum ff = front.func, bf = back.func;
191         int fr = front.ref, br = back.ref;
192         int fm = front.mask, bm = back.mask;
193         final GLEnum face = GLEnum.valueOf(msg.getArg0());
194         if (face == GLEnum.GL_FRONT || face == GLEnum.GL_FRONT_AND_BACK) {
195             ff = GLEnum.valueOf(msg.getArg1());
196             fr = msg.getArg2();
197             fm = msg.getArg3();
198         }
199         if (face == GLEnum.GL_BACK || face == GLEnum.GL_FRONT_AND_BACK) {
200             bf = GLEnum.valueOf(msg.getArg1());
201             br = msg.getArg2();
202             bm = msg.getArg3();
203         }
204         if (ff == front.func && fr == front.ref && fm == front.mask)
205             if (bf == back.func && br == back.ref && bm == back.mask)
206                 return true; // TODO: redundant
207         front.func = ff;
208         front.ref = fr;
209         front.mask = fm;
210         back.func = bf;
211         back.ref = br;
212         back.mask = bm;
213         return true;
214     }
215 
216     // void StencilOpSeparate( enum face, enum sfail, enum dpfail, enum dppass )
glStencilOpSeparate(final Message msg)217     boolean glStencilOpSeparate(final Message msg) {
218         GLEnum fsf = front.sf, fdf = front.df, fdp = front.dp;
219         GLEnum bsf = back.sf, bdf = back.df, bdp = back.dp;
220         final GLEnum face = GLEnum.valueOf(msg.getArg0());
221         if (face == GLEnum.GL_FRONT || face == GLEnum.GL_FRONT_AND_BACK) {
222             fsf = GLEnum.valueOf(msg.getArg1());
223             fdf = GLEnum.valueOf(msg.getArg2());
224             fdp = GLEnum.valueOf(msg.getArg3());
225         }
226         if (face == GLEnum.GL_BACK || face == GLEnum.GL_FRONT_AND_BACK) {
227             bsf = GLEnum.valueOf(msg.getArg1());
228             bdf = GLEnum.valueOf(msg.getArg2());
229             bdp = GLEnum.valueOf(msg.getArg3());
230         }
231         if (fsf == front.sf && fdf == front.df && fdp == front.dp)
232             if (bsf == back.sf && bdf == back.df && bdp == back.dp)
233                 return true; // TODO: redundant
234         front.sf = fsf;
235         front.df = fdf;
236         front.dp = fdp;
237         back.sf = bsf;
238         back.df = bdf;
239         back.dp = bdp;
240         return true;
241     }
242 
243     /** deep copy */
244     @Override
clone()245     public GLServerState clone() {
246         try {
247             GLServerState newState = (GLServerState) super.clone();
248             newState.front = (GLStencilState) front.clone();
249             newState.back = (GLStencilState) back.clone();
250 
251             newState.enableDisables = new SparseIntArray(enableDisables.size());
252             for (int i = 0; i < enableDisables.size(); i++)
253                 newState.enableDisables.append(enableDisables.keyAt(i),
254                         enableDisables.valueAt(i));
255 
256             newState.integers = new SparseArray<Message>(integers.size());
257             for (int i = 0; i < integers.size(); i++)
258                 newState.integers.append(integers.keyAt(i), integers.valueAt(i));
259 
260             newState.lastSetter = new SparseArray<Message>(lastSetter.size());
261             for (int i = 0; i < lastSetter.size(); i++)
262                 newState.lastSetter.append(lastSetter.keyAt(i), lastSetter.valueAt(i));
263 
264             return newState;
265         } catch (CloneNotSupportedException e) {
266             e.printStackTrace();
267             assert false;
268             return null;
269         }
270     }
271 }
272