Home | History | Annotate | Download | only in detail
      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
     45     public boolean isApplicable(IGLProperty state) {
     46         return getTextureImageProperty(state) != null;
     47     }
     48 
     49     @Override
     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
     63     public void disposeControl() {
     64         mImageCanvas.dispose();
     65         mImageCanvas = null;
     66     }
     67 
     68     @Override
     69     public Control getControl() {
     70         return mImageCanvas;
     71     }
     72 
     73     @Override
     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      */
    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      */
    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      */
    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
    155     public List<IContributionItem> getToolBarItems() {
    156         return mToolBarItems;
    157     }
    158 }
    159