1 /*
2  * Copyright (C) 2012 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.gltrace.views.detail;
18 
19 import com.android.ide.eclipse.gltrace.GLEnum;
20 import com.android.ide.eclipse.gltrace.state.GLCompositeProperty;
21 import com.android.ide.eclipse.gltrace.state.GLStateType;
22 import com.android.ide.eclipse.gltrace.state.IGLProperty;
23 import com.google.common.base.Joiner;
24 
25 import org.eclipse.jface.action.IContributionItem;
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Control;
29 import org.eclipse.swt.widgets.Text;
30 
31 import java.util.Collections;
32 import java.util.List;
33 
34 public class ShaderUniformDetailsProvider implements IStateDetailProvider {
35     private Text mTextControl;
36     private static final Joiner JOINER = Joiner.on(", ");
37 
38     @Override
isApplicable(IGLProperty state)39     public boolean isApplicable(IGLProperty state) {
40         return getShaderUniformProperty(state) != null;
41     }
42 
43     @Override
createControl(Composite parent)44     public void createControl(Composite parent) {
45         mTextControl = new Text(parent, SWT.BORDER | SWT.READ_ONLY | SWT.MULTI | SWT.WRAP);
46         mTextControl.setEditable(false);
47     }
48 
49     @Override
disposeControl()50     public void disposeControl() {
51     }
52 
53     @Override
getControl()54     public Control getControl() {
55         return mTextControl;
56     }
57 
58     @Override
updateControl(IGLProperty state)59     public void updateControl(IGLProperty state) {
60         IGLProperty uniform = getShaderUniformProperty(state);
61         if (uniform instanceof GLCompositeProperty) {
62             GLCompositeProperty uniformProperty = (GLCompositeProperty) uniform;
63             IGLProperty nameProperty = uniformProperty.getProperty(GLStateType.UNIFORM_NAME);
64             IGLProperty typeProperty = uniformProperty.getProperty(GLStateType.UNIFORM_TYPE);
65             IGLProperty valueProperty = uniformProperty.getProperty(GLStateType.UNIFORM_VALUE);
66 
67             String name = (String) nameProperty.getValue();
68             GLEnum type = (GLEnum) typeProperty.getValue();
69             Object value = valueProperty.getValue();
70             mTextControl.setText(formatUniform(name, type, value));
71             mTextControl.setEnabled(true);
72         } else {
73             mTextControl.setText(""); //$NON-NLS-1$
74             mTextControl.setEnabled(false);
75         }
76     }
77 
formatUniform(String name, GLEnum type, Object value)78     private String formatUniform(String name, GLEnum type, Object value) {
79         String valueText;
80 
81         switch (type) {
82             case GL_FLOAT:
83             case GL_FLOAT_VEC2:
84             case GL_FLOAT_VEC3:
85             case GL_FLOAT_VEC4:
86             case GL_INT:
87             case GL_INT_VEC2:
88             case GL_INT_VEC3:
89             case GL_INT_VEC4:
90             case GL_BOOL:
91             case GL_BOOL_VEC2:
92             case GL_BOOL_VEC3:
93             case GL_BOOL_VEC4:
94                 valueText = formatVector(value);
95                 break;
96             case GL_FLOAT_MAT2:
97                 valueText = formatMatrix(2, value);
98                 break;
99             case GL_FLOAT_MAT3:
100                 valueText = formatMatrix(3, value);
101                 break;
102             case GL_FLOAT_MAT4:
103                 valueText = formatMatrix(4, value);
104                 break;
105             case GL_SAMPLER_2D:
106             case GL_SAMPLER_CUBE:
107             default:
108                 valueText = value.toString();
109                 break;
110         }
111 
112         return String.format("%s %s = %s", type, name, valueText); //$NON-NLS-1$
113     }
114 
formatVector(Object value)115     private String formatVector(Object value) {
116         if (value instanceof List<?>) {
117             List<?> list = (List<?>) value;
118             StringBuilder sb = new StringBuilder(list.size() * 4);
119             sb.append('[');
120             JOINER.appendTo(sb, list);
121             sb.append(']');
122             return sb.toString();
123         }
124 
125         return value.toString();
126     }
127 
formatMatrix(int dimension, Object value)128     private String formatMatrix(int dimension, Object value) {
129         if (value instanceof List<?>) {
130             List<?> list = (List<?>) value;
131             if (list.size() != dimension * dimension) {
132                 // Uniforms can only be square matrices, so this scenario should
133                 // not occur.
134                 return formatVector(value);
135             }
136 
137             StringBuilder sb = new StringBuilder(list.size() * 4);
138             sb.append('[');
139             sb.append('\n');
140             for (int i = 0; i < dimension; i++) {
141                 sb.append("    "); //$NON-NLS-1$
142                 JOINER.appendTo(sb, list.subList(i * dimension, (i + 1) * dimension));
143                 sb.append('\n');
144             }
145             sb.append(']');
146             return sb.toString();
147         }
148 
149         return value.toString();
150     }
151 
152     /**
153      * Get the {@link GLStateType#PER_UNIFORM_STATE} property given a node in
154      * the state hierarchy.
155      */
getShaderUniformProperty(IGLProperty state)156     private IGLProperty getShaderUniformProperty(IGLProperty state) {
157         if (state.getType() == GLStateType.PER_UNIFORM_STATE) {
158             return state;
159         }
160 
161         state = state.getParent();
162         if (state != null && state.getType() == GLStateType.PER_UNIFORM_STATE) {
163             return state;
164         }
165 
166         return null;
167     }
168 
169     @Override
getToolBarItems()170     public List<IContributionItem> getToolBarItems() {
171         return Collections.emptyList();
172     }
173 }
174