aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse
diff options
context:
space:
mode:
authorSiva Velusamy <vsiva@google.com>2012-02-27 09:14:09 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-02-27 09:14:09 -0800
commitd5b97a3273fdaf4f335daf3c8e9ceccacd7b4b4a (patch)
tree5c64dfde72fbedbb8b242bf7f357a7ba313220a3 /eclipse
parent9109f4c300ac241beaa6adec77844b81e8fc2552 (diff)
parent3099b177619345a94ce3c7c8a2dc03e06f1b7bf5 (diff)
downloadsdk-d5b97a3273fdaf4f335daf3c8e9ceccacd7b4b4a.zip
sdk-d5b97a3273fdaf4f335daf3c8e9ceccacd7b4b4a.tar.gz
sdk-d5b97a3273fdaf4f335daf3c8e9ceccacd7b4b4a.tar.bz2
Merge "gltrace: Add support for VBO's"
Diffstat (limited to 'eclipse')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/plugin.xml2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/format/GLMessageFormatter.java5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/GLState.java16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/GLStateType.java7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/BufferSubDataTransform.java71
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/CurrentVboPropertyAccessor.java66
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/StateTransformFactory.java93
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/detail/DetailsPage.java1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/detail/VboDetailProvider.java276
9 files changed, 535 insertions, 2 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.gldebugger/plugin.xml
index ff2799f..ab95306 100644
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/plugin.xml
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/plugin.xml
@@ -84,7 +84,7 @@
class="com.android.ide.eclipse.gltrace.GLTracePerspective"
icon="icons/opengl.png"
id="com.android.ide.eclipse.gltrace.perspective"
- name="Android OpenGL Trace">
+ name="OpenGL Trace">
</perspective>
</extension>
<extension
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/format/GLMessageFormatter.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/format/GLMessageFormatter.java
index c0a11fe..e3249e6 100644
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/format/GLMessageFormatter.java
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/format/GLMessageFormatter.java
@@ -144,6 +144,11 @@ public class GLMessageFormatter {
}
sb.append(']');
return sb.toString();
+ case VOID:
+ if (var.getRawBytesList().size() > 0) {
+ return String.format("[ %d bytes ]", var.getRawBytesList().get(0).size()); //$NON-NLS-1$
+ }
+ return "[]"; //$NON-NLS-1$
}
// We have a pointer, but we don't have the data pointed to.
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/GLState.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/GLState.java
index 690fb7e..aeb9d89 100644
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/GLState.java
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/GLState.java
@@ -93,15 +93,29 @@ public class GLState {
MAX_VERTEX_ATTRIBS);
}
+ private IGLProperty createVboState() {
+ IGLProperty size = new GLIntegerProperty(GLStateType.BUFFER_SIZE, Integer.valueOf(0));
+ IGLProperty usage = new GLEnumProperty(GLStateType.BUFFER_USAGE, GLEnum.GL_STATIC_DRAW);
+ IGLProperty data = new GLObjectProperty(GLStateType.BUFFER_DATA, new byte[0]);
+ IGLProperty type = new GLEnumProperty(GLStateType.BUFFER_TYPE, GLEnum.GL_ARRAY_BUFFER);
+
+ IGLProperty perVboState = new GLCompositeProperty(GLStateType.VBO_COMPOSITE,
+ size, usage, data, type);
+
+ return new GLSparseArrayProperty(GLStateType.VBO, perVboState);
+ }
+
private IGLProperty createVertexArrayData() {
IGLProperty vertexAttribArrays = createVertexAttribArrays();
IGLProperty bufferBindings = createBufferBindings();
IGLProperty genericAttribs = createGenericVertexAttributeState();
+ IGLProperty vboState = createVboState();
return new GLCompositeProperty(GLStateType.VERTEX_ARRAY_DATA,
genericAttribs,
vertexAttribArrays,
- bufferBindings);
+ bufferBindings,
+ vboState);
}
private IGLProperty createTransformationState() {
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/GLStateType.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/GLStateType.java
index 9d367be..a07edc2 100644
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/GLStateType.java
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/GLStateType.java
@@ -47,6 +47,13 @@ public enum GLStateType {
VERTEX_ATTRIB_ARRAY_BUFFER_BINDINGS("Attribute Array Buffer Bindings"),
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_PER_INDEX("Attribute Array Buffer Binding"),
+ VBO("Vertex Buffer Objects"),
+ VBO_COMPOSITE("Per VBO State"),
+ BUFFER_SIZE("Size"),
+ BUFFER_USAGE("Usage"),
+ BUFFER_DATA("Data"),
+ BUFFER_TYPE("Type"),
+
TRANSFORMATION_STATE("Transformation State"),
VIEWPORT("Viewport"),
VIEWPORT_X("Lower Left X"),
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/BufferSubDataTransform.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/BufferSubDataTransform.java
new file mode 100644
index 0000000..844c7dc
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/BufferSubDataTransform.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2012 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.ide.eclipse.gltrace.state.transforms;
+
+import com.android.ide.eclipse.gltrace.GLProtoBuf.GLMessage.Function;
+import com.android.ide.eclipse.gltrace.state.IGLProperty;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A {@link BufferSubDataTransform} updates a portion of the buffer data as specified by
+ * the {@link Function#glBufferSubData} function.
+ */
+public class BufferSubDataTransform implements IStateTransform {
+ private final IGLPropertyAccessor mAccessor;
+ private final int mOffset;
+
+ private final byte[] mSubData;
+ private byte[] mOldData;
+ private byte[] mNewData;
+
+ public BufferSubDataTransform(IGLPropertyAccessor accessor, int offset, byte[] data) {
+ mAccessor = accessor;
+ mOffset = offset;
+ mSubData = data;
+ }
+
+ @Override
+ public void apply(IGLProperty state) {
+ IGLProperty property = mAccessor.getProperty(state);
+ mOldData = (byte[]) property.getValue();
+
+ if (mNewData != null) {
+ mNewData = new byte[mOldData.length];
+ ByteBuffer bb = ByteBuffer.wrap(mNewData);
+ bb.put(mOldData); // copy all of the old buffer
+ bb.rewind();
+ bb.put(mSubData, mOffset, mSubData.length); // update with the sub buffer data
+ }
+
+ property.setValue(mNewData);
+ }
+
+ @Override
+ public void revert(IGLProperty state) {
+ if (mOldData != null) {
+ IGLProperty property = mAccessor.getProperty(state);
+ property.setValue(mOldData);
+ mOldData = null;
+ }
+ }
+
+ @Override
+ public IGLProperty getChangedProperty(IGLProperty state) {
+ return mAccessor.getProperty(state);
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/CurrentVboPropertyAccessor.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/CurrentVboPropertyAccessor.java
new file mode 100644
index 0000000..3f763e0
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/CurrentVboPropertyAccessor.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 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.ide.eclipse.gltrace.state.transforms;
+
+import com.android.ide.eclipse.gldebugger.GLEnum;
+import com.android.ide.eclipse.gltrace.state.GLIntegerProperty;
+import com.android.ide.eclipse.gltrace.state.GLStateType;
+import com.android.ide.eclipse.gltrace.state.IGLProperty;
+
+/**
+ * An {@link IGLPropertyAccessor} that retrieves the requested property in the
+ * currently bound {@link GLEnum#GL_ARRAY_BUFFER} or {@link GLEnum#GL_ELEMENT_ARRAY_BUFFER}.
+ */
+public class CurrentVboPropertyAccessor implements IGLPropertyAccessor {
+ private final int mContextId;
+ private final IGLPropertyAccessor mVboBindingAccessor;
+ private final GLStateType mVboProperty;
+
+ public CurrentVboPropertyAccessor(int contextId, GLEnum target, GLStateType vboProperty) {
+ mContextId = contextId;
+ mVboProperty = vboProperty;
+
+ GLStateType vboType;
+ if (target == GLEnum.GL_ARRAY_BUFFER) {
+ vboType = GLStateType.ARRAY_BUFFER_BINDING;
+ } else {
+ vboType = GLStateType.ELEMENT_ARRAY_BUFFER_BINDING;
+ }
+
+ mVboBindingAccessor = GLPropertyAccessor.makeAccessor(contextId,
+ GLStateType.VERTEX_ARRAY_DATA,
+ GLStateType.BUFFER_BINDINGS,
+ vboType);
+ }
+
+ @Override
+ public IGLProperty getProperty(IGLProperty state) {
+ // obtain the current bound buffer
+ IGLProperty currentBinding = mVboBindingAccessor.getProperty(state);
+ if (!(currentBinding instanceof GLIntegerProperty)) {
+ return null;
+ }
+
+ Integer buffer = (Integer) currentBinding.getValue();
+
+ return GLPropertyAccessor.makeAccessor(mContextId,
+ GLStateType.VERTEX_ARRAY_DATA,
+ GLStateType.VBO,
+ buffer,
+ mVboProperty).getProperty(state);
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/StateTransformFactory.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/StateTransformFactory.java
index 0afd2e1..5751025 100644
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/StateTransformFactory.java
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/state/transforms/StateTransformFactory.java
@@ -65,6 +65,14 @@ public class StateTransformFactory {
// VBO's
case glBindBuffer:
return transformsForGlBindBuffer(msg);
+ case glGenBuffers:
+ return transformsForGlGenBuffers(msg);
+ case glDeleteBuffers:
+ return transformsForGlDeleteBuffers(msg);
+ case glBufferData:
+ return transformsForGlBufferData(msg);
+ case glBufferSubData:
+ return transformsForGlBufferSubData(msg);
// transformation state
case glViewport:
@@ -338,6 +346,91 @@ public class StateTransformFactory {
return Collections.singletonList(transform);
}
+ private static List<IStateTransform> transformsForGlGenBuffers(GLMessage msg) {
+ // void glGenBuffers(GLsizei n, GLuint * buffers);
+ int n = msg.getArgs(0).getIntValue(0);
+ List<IStateTransform> transforms = new ArrayList<IStateTransform>();
+
+ for (int i = 0; i < n; i++) {
+ transforms.add(new SparseArrayElementAddTransform(
+ GLPropertyAccessor.makeAccessor(msg.getContextId(),
+ GLStateType.VERTEX_ARRAY_DATA,
+ GLStateType.VBO),
+ msg.getArgs(1).getIntValue(i)));
+ }
+
+ return transforms;
+ }
+
+ private static List<IStateTransform> transformsForGlDeleteBuffers(GLMessage msg) {
+ // void glDeleteBuffers(GLsizei n, const GLuint * buffers);
+ int n = msg.getArgs(0).getIntValue(0);
+ List<IStateTransform> transforms = new ArrayList<IStateTransform>();
+
+ for (int i = 0; i < n; i++) {
+ transforms.add(new SparseArrayElementRemoveTransform(
+ GLPropertyAccessor.makeAccessor(msg.getContextId(),
+ GLStateType.VERTEX_ARRAY_DATA,
+ GLStateType.VBO),
+ msg.getArgs(1).getIntValue(i)));
+ }
+
+ return transforms;
+ }
+
+ private static List<IStateTransform> transformsForGlBufferData(GLMessage msg) {
+ // void glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
+ GLEnum target = GLEnum.valueOf(msg.getArgs(0).getIntValue(0));
+ int size = msg.getArgs(1).getIntValue(0);
+ byte[] data = null;
+ GLEnum usage = GLEnum.valueOf(msg.getArgs(3).getIntValue(0));
+
+ if (msg.getArgs(2).getRawBytesList().size() > 0) {
+ data = msg.getArgs(2).getRawBytesList().get(0).toByteArray();
+ } else {
+ data = new byte[size];
+ }
+
+ List<IStateTransform> transforms = new ArrayList<IStateTransform>();
+
+ transforms.add(new PropertyChangeTransform(
+ new CurrentVboPropertyAccessor(msg.getContextId(),
+ target,
+ GLStateType.BUFFER_SIZE),
+ Integer.valueOf(size)));
+ transforms.add(new PropertyChangeTransform(
+ new CurrentVboPropertyAccessor(msg.getContextId(),
+ target,
+ GLStateType.BUFFER_DATA),
+ data));
+ transforms.add(new PropertyChangeTransform(
+ new CurrentVboPropertyAccessor(msg.getContextId(),
+ target,
+ GLStateType.BUFFER_USAGE),
+ usage));
+ transforms.add(new PropertyChangeTransform(
+ new CurrentVboPropertyAccessor(msg.getContextId(),
+ target,
+ GLStateType.BUFFER_TYPE),
+ target));
+ return transforms;
+ }
+
+ private static List<IStateTransform> transformsForGlBufferSubData(GLMessage msg) {
+ // void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
+ GLEnum target = GLEnum.valueOf(msg.getArgs(0).getIntValue(0));
+ int offset = msg.getArgs(1).getIntValue(0);
+ byte[] data = msg.getArgs(3).getRawBytesList().get(0).toByteArray();
+
+ IStateTransform transform = new BufferSubDataTransform(
+ new CurrentVboPropertyAccessor(msg.getContextId(),
+ target,
+ GLStateType.BUFFER_SIZE),
+ offset, data);
+
+ return Collections.singletonList(transform);
+ }
+
private static List<IStateTransform> transformsForGlBindFramebuffer(GLMessage msg) {
// void glBindFramebuffer(GLenum target, GLuint framebuffer);
int fb = msg.getArgs(1).getIntValue(0);
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/detail/DetailsPage.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/detail/DetailsPage.java
index 6d6f00d..8141feb 100644
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/detail/DetailsPage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/detail/DetailsPage.java
@@ -53,6 +53,7 @@ public class DetailsPage extends Page implements ISelectionListener {
new ShaderSourceDetailsProvider(),
new ShaderUniformDetailsProvider(),
new TextureImageDetailsProvider(),
+ new VboDetailProvider(),
new GlDrawCallDetailProvider());
public DetailsPage(GLTrace trace) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/detail/VboDetailProvider.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/detail/VboDetailProvider.java
new file mode 100644
index 0000000..273ea20
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/detail/VboDetailProvider.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2012 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.ide.eclipse.gltrace.views.detail;
+
+import com.android.ide.eclipse.gltrace.state.GLCompositeProperty;
+import com.android.ide.eclipse.gltrace.state.GLStateType;
+import com.android.ide.eclipse.gltrace.state.IGLProperty;
+
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class VboDetailProvider implements IStateDetailProvider {
+ private static enum DisplayFormat {
+ GL_FLOAT,
+ GL_BYTE,
+ GL_UNSIGNED_BYTE,
+ GL_SHORT,
+ GL_UNSIGNED_SHORT,
+ GL_FIXED,
+ }
+
+ private Composite mComposite;
+
+ private Label mSizeLabel;
+ private Label mUsageLabel;
+ private Label mTypeLabel;
+ private Combo mDisplayFormatCombo;
+ private Text mTextControl;
+
+ private byte[] mBufferData;
+
+ @Override
+ public boolean isApplicable(IGLProperty state) {
+ return getVboProperty(state) != null;
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ mComposite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginWidth = layout.marginHeight = 0;
+ mComposite.setLayout(layout);
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(mComposite);
+
+ Label l = new Label(mComposite, SWT.NONE);
+ l.setText("Size: ");
+ GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(l);
+
+ mSizeLabel = new Label(mComposite, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(mSizeLabel);
+
+ l = new Label(mComposite, SWT.NONE);
+ l.setText("Usage: ");
+ GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(l);
+
+ mUsageLabel = new Label(mComposite, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(mUsageLabel);
+
+ l = new Label(mComposite, SWT.NONE);
+ l.setText("Type: ");
+ GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(l);
+
+ mTypeLabel = new Label(mComposite, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(mTypeLabel);
+
+ l = new Label(mComposite, SWT.NONE);
+ l.setText("Format Data As: ");
+ GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(l);
+
+ DisplayFormat[] values = DisplayFormat.values();
+ List<String> formats = new ArrayList<String>(values.length);
+ for (DisplayFormat format: values) {
+ formats.add(format.name());
+ }
+
+ mDisplayFormatCombo = new Combo(mComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
+ mDisplayFormatCombo.setItems(formats.toArray(new String[formats.size()]));
+ mDisplayFormatCombo.select(0);
+ mDisplayFormatCombo.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateContents();
+ }
+ });
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(mDisplayFormatCombo);
+
+ mTextControl = new Text(mComposite, SWT.BORDER | SWT.READ_ONLY | SWT.MULTI
+ | SWT.WRAP | SWT.V_SCROLL | SWT.H_SCROLL);
+ GridDataFactory.fillDefaults().span(2, 1).grab(true, true).applyTo(mTextControl);
+ mTextControl.setEditable(false);
+ }
+
+ @Override
+ public void disposeControl() {
+ }
+
+ @Override
+ public Control getControl() {
+ return mComposite;
+ }
+
+ @Override
+ public void updateControl(IGLProperty state) {
+ IGLProperty vbo = getVboProperty(state);
+ if (vbo instanceof GLCompositeProperty) {
+ GLCompositeProperty vboProperty = (GLCompositeProperty) vbo;
+
+ IGLProperty sizeProperty = vboProperty.getProperty(GLStateType.BUFFER_SIZE);
+ mSizeLabel.setText(sizeProperty.getStringValue() + " bytes"); //$NON-NLS-1$
+
+ IGLProperty usageProperty = vboProperty.getProperty(GLStateType.BUFFER_USAGE);
+ mUsageLabel.setText(usageProperty.getStringValue());
+
+ IGLProperty typeProperty = vboProperty.getProperty(GLStateType.BUFFER_TYPE);
+ mTypeLabel.setText(typeProperty.getStringValue());
+
+ IGLProperty dataProperty = vboProperty.getProperty(GLStateType.BUFFER_DATA);
+ mBufferData = (byte[]) dataProperty.getValue();
+ } else {
+ mBufferData = null;
+ }
+
+ updateContents();
+ }
+
+ private void updateContents() {
+ if (mBufferData != null) {
+ mTextControl.setText(formatData(mBufferData));
+ mTextControl.setEnabled(true);
+ mDisplayFormatCombo.setEnabled(true);
+ } else {
+ mTextControl.setText("");
+ mTextControl.setEnabled(false);
+ mDisplayFormatCombo.setEnabled(false);
+ }
+ }
+
+ private String formatData(byte[] data) {
+ DisplayFormat format = DisplayFormat.valueOf(mDisplayFormatCombo.getText());
+
+ switch (format) {
+ case GL_BYTE:
+ return formatBytes(data, false);
+ case GL_UNSIGNED_BYTE:
+ return formatBytes(data, true);
+ case GL_SHORT:
+ return formatShorts(data, false);
+ case GL_UNSIGNED_SHORT:
+ return formatShorts(data, true);
+ case GL_FIXED:
+ return formatInts(data);
+ case GL_FLOAT:
+ return formatFloats(data);
+ default:
+ return ""; //$NON-NLS-1$
+ }
+ }
+
+ private String formatFloats(byte[] data) {
+ FloatBuffer bb = ByteBuffer.wrap(data).asFloatBuffer();
+
+ StringBuilder sb = new StringBuilder(bb.capacity() * 3);
+
+ while (bb.remaining() > 0) {
+ sb.append(String.format("%.4f", bb.get()));
+ sb.append(',');
+ sb.append('\n');
+ }
+
+ return sb.toString();
+ }
+
+ private String formatInts(byte[] data) {
+ IntBuffer bb = ByteBuffer.wrap(data).asIntBuffer();
+
+ StringBuilder sb = new StringBuilder(bb.capacity() * 3);
+
+ while (bb.remaining() > 0) {
+ sb.append(bb.get());
+ sb.append(',');
+ sb.append('\n');
+ }
+
+ return sb.toString();
+ }
+
+ private String formatShorts(byte[] data, boolean unsigned) {
+ ShortBuffer bb = ByteBuffer.wrap(data).asShortBuffer();
+
+ StringBuilder sb = new StringBuilder(bb.capacity() * 3);
+
+ while (bb.remaining() > 0) {
+ if (unsigned) {
+ sb.append(bb.get() & 0xffff);
+ } else {
+ sb.append(bb.get());
+ }
+ sb.append(',');
+ sb.append('\n');
+ }
+
+ return sb.toString();
+ }
+
+ private String formatBytes(byte[] data, boolean unsigned) {
+ ByteBuffer bb = ByteBuffer.wrap(data);
+
+ StringBuilder sb = new StringBuilder(bb.capacity() * 3);
+
+ while (bb.remaining() > 0) {
+ if (unsigned) {
+ sb.append(bb.get() & 0xff);
+ } else {
+ sb.append(bb.get());
+ }
+
+ sb.append(',');
+ sb.append('\n');
+ }
+
+ return sb.toString();
+ }
+
+ @Override
+ public List<IContributionItem> getToolBarItems() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Get the {@link GLStateType#VBO_COMPOSITE} property given a node in
+ * the state hierarchy.
+ */
+ private IGLProperty getVboProperty(IGLProperty state) {
+ if (state.getType() == GLStateType.VBO_COMPOSITE) {
+ return state;
+ }
+
+ state = state.getParent();
+ if (state != null && state.getType() == GLStateType.VBO_COMPOSITE) {
+ return state;
+ }
+
+ return null;
+ }
+}