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.state.GLCompositeProperty; 20 import com.android.ide.eclipse.gltrace.state.GLSparseArrayProperty; 21 import com.android.ide.eclipse.gltrace.state.GLStateType; 22 import com.android.ide.eclipse.gltrace.state.GLStringProperty; 23 import com.android.ide.eclipse.gltrace.state.IGLProperty; 24 import com.android.ide.eclipse.gltrace.views.FitToCanvasAction; 25 import com.android.ide.eclipse.gltrace.views.SaveImageAction; 26 import com.android.ide.eclipse.gltrace.widgets.ImageCanvas; 27 28 import org.eclipse.jface.action.ActionContributionItem; 29 import org.eclipse.jface.action.IContributionItem; 30 import org.eclipse.swt.graphics.Image; 31 import org.eclipse.swt.widgets.Composite; 32 import org.eclipse.swt.widgets.Control; 33 import org.eclipse.swt.widgets.Display; 34 35 import java.util.Arrays; 36 import java.util.List; 37 38 public class TextureImageDetailsProvider implements IStateDetailProvider { 39 private ImageCanvas mImageCanvas; 40 private FitToCanvasAction mFitToCanvasAction; 41 private SaveImageAction mSaveImageAction; 42 private List<IContributionItem> mToolBarItems; 43 44 @Override isApplicable(IGLProperty state)45 public boolean isApplicable(IGLProperty state) { 46 return getTextureImageProperty(state) != null; 47 } 48 49 @Override createControl(Composite parent)50 public void createControl(Composite parent) { 51 mImageCanvas = new ImageCanvas(parent); 52 mImageCanvas.setFitToCanvas(false); 53 54 mFitToCanvasAction = new FitToCanvasAction(false, mImageCanvas); 55 mSaveImageAction = new SaveImageAction(mImageCanvas); 56 57 mToolBarItems = Arrays.asList( 58 (IContributionItem) new ActionContributionItem(mFitToCanvasAction), 59 (IContributionItem) new ActionContributionItem(mSaveImageAction)); 60 } 61 62 @Override disposeControl()63 public void disposeControl() { 64 mImageCanvas.dispose(); 65 mImageCanvas = null; 66 } 67 68 @Override getControl()69 public Control getControl() { 70 return mImageCanvas; 71 } 72 73 @Override updateControl(IGLProperty state)74 public void updateControl(IGLProperty state) { 75 IGLProperty imageProperty = getTextureImageProperty(state); 76 if (imageProperty == null) { 77 return; 78 } 79 80 String texturePath = ((GLStringProperty) imageProperty).getStringValue(); 81 if (texturePath != null) { 82 mImageCanvas.setImage(new Image(Display.getDefault(), texturePath)); 83 mImageCanvas.setFitToCanvas(false); 84 return; 85 } 86 } 87 88 /** 89 * Get the {@link GLStateType#TEXTURE_IMAGE} property given a node in 90 * the state hierarchy. 91 * @param state any node in the GL state hierarchy 92 * @return The {@link GLStateType#TEXTURE_IMAGE} property if a unique instance 93 * of it can be accessed from the given node. A unique instance can be 94 * accessed if the given node is either the requested node itself, or 95 * its parent or sibling. In cases where a unique instance cannot be 96 * accessed, but one of the texture mipmap levels can be accessed, then 97 * return the first texture mipmap level. This happens if the selected 98 * state is a child of {@link GLStateType#PER_TEXTURE_STATE}. Returns 99 * null otherwise. 100 */ getTextureImageProperty(IGLProperty state)101 private IGLProperty getTextureImageProperty(IGLProperty state) { 102 if (state.getType() == GLStateType.TEXTURE_IMAGE) { 103 // given node is the requested node 104 return state; 105 } 106 107 IGLProperty img = getImageFromPerTextureLevelState(state); 108 if (img != null) { 109 return img; 110 } 111 112 return getFirstMipmapImage(state); 113 } 114 115 /** 116 * Returns the {@link GLStateType#TEXTURE_IMAGE} if the provided state is either 117 * {@link GLStateType#PER_TEXTURE_LEVEL_STATE} or one of its children. Returns null otherwise. 118 */ getImageFromPerTextureLevelState(IGLProperty state)119 private IGLProperty getImageFromPerTextureLevelState(IGLProperty state) { 120 if (state != null && state.getType() != GLStateType.PER_TEXTURE_LEVEL_STATE) { 121 state = state.getParent(); 122 } 123 124 if (state == null || state.getType() != GLStateType.PER_TEXTURE_LEVEL_STATE) { 125 return null; 126 } 127 128 return ((GLCompositeProperty) state).getProperty(GLStateType.TEXTURE_IMAGE); 129 } 130 131 /** 132 * Returns the first mipmap level's image entry if the provided state is either 133 * {@link GLStateType#PER_TEXTURE_STATE} or one of its immediate children, null otherwise. 134 */ getFirstMipmapImage(IGLProperty state)135 private IGLProperty getFirstMipmapImage(IGLProperty state) { 136 if (state != null && state.getType() != GLStateType.PER_TEXTURE_STATE) { 137 state = state.getParent(); 138 } 139 140 if (state == null || state.getType() != GLStateType.PER_TEXTURE_STATE) { 141 return null; 142 } 143 144 IGLProperty mipmaps = 145 ((GLCompositeProperty) state).getProperty(GLStateType.TEXTURE_MIPMAPS); 146 if (!(mipmaps instanceof GLSparseArrayProperty)) { 147 return null; 148 } 149 150 IGLProperty perTextureLevelState = ((GLSparseArrayProperty) mipmaps).getProperty(0); 151 return getImageFromPerTextureLevelState(perTextureLevelState); 152 } 153 154 @Override getToolBarItems()155 public List<IContributionItem> getToolBarItems() { 156 return mToolBarItems; 157 } 158 } 159