1 /* 2 * Copyright (C) 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 18 package android.filterfw; 19 20 import android.content.Context; 21 import android.filterfw.core.AsyncRunner; 22 import android.filterfw.core.FilterGraph; 23 import android.filterfw.core.FilterContext; 24 import android.filterfw.core.FrameManager; 25 import android.filterfw.core.GraphRunner; 26 import android.filterfw.core.RoundRobinScheduler; 27 import android.filterfw.core.SyncRunner; 28 import android.filterfw.io.GraphIOException; 29 import android.filterfw.io.GraphReader; 30 import android.filterfw.io.TextGraphReader; 31 32 import java.util.ArrayList; 33 34 /** 35 * A GraphEnvironment provides a simple front-end to filter graph setup and execution using the 36 * mobile filter framework. Typically, you use a GraphEnvironment in the following fashion: 37 * 1. Instantiate a new GraphEnvironment instance. 38 * 2. Perform any configuration, such as adding graph references and setting a GL environment. 39 * 3. Load a graph file using loadGraph() or add a graph using addGraph(). 40 * 4. Obtain a GraphRunner instance using getRunner(). 41 * 5. Execute the obtained runner. 42 * Note that it is possible to add multiple graphs and runners to a single GraphEnvironment. 43 * 44 * @hide 45 */ 46 public class GraphEnvironment extends MffEnvironment { 47 48 public static final int MODE_ASYNCHRONOUS = 1; 49 public static final int MODE_SYNCHRONOUS = 2; 50 51 private GraphReader mGraphReader; 52 private ArrayList<GraphHandle> mGraphs = new ArrayList<GraphHandle>(); 53 54 private class GraphHandle { 55 private FilterGraph mGraph; 56 private AsyncRunner mAsyncRunner; 57 private SyncRunner mSyncRunner; 58 59 public GraphHandle(FilterGraph graph) { 60 mGraph = graph; 61 } 62 63 public FilterGraph getGraph() { 64 return mGraph; 65 } 66 67 public AsyncRunner getAsyncRunner(FilterContext environment) { 68 if (mAsyncRunner == null) { 69 mAsyncRunner = new AsyncRunner(environment, RoundRobinScheduler.class); 70 mAsyncRunner.setGraph(mGraph); 71 } 72 return mAsyncRunner; 73 } 74 75 public GraphRunner getSyncRunner(FilterContext environment) { 76 if (mSyncRunner == null) { 77 mSyncRunner = new SyncRunner(environment, mGraph, RoundRobinScheduler.class); 78 } 79 return mSyncRunner; 80 } 81 } 82 83 /** 84 * Create a new GraphEnvironment with default components. 85 */ 86 public GraphEnvironment() { 87 super(null); 88 } 89 90 /** 91 * Create a new GraphEnvironment with a custom FrameManager and GraphReader. Specifying null 92 * for either of these, will auto-create a default instance. 93 * 94 * @param frameManager The FrameManager to use, or null to auto-create one. 95 * @param reader The GraphReader to use for graph loading, or null to auto-create one. 96 * Note, that the reader will not be created until it is required. Pass 97 * null if you will not load any graph files. 98 */ 99 public GraphEnvironment(FrameManager frameManager, GraphReader reader) { 100 super(frameManager); 101 mGraphReader = reader; 102 } 103 104 /** 105 * Returns the used graph reader. This will create one, if a reader has not been set already. 106 */ 107 public GraphReader getGraphReader() { 108 if (mGraphReader == null) { 109 mGraphReader = new TextGraphReader(); 110 } 111 return mGraphReader; 112 } 113 114 /** 115 * Add graph references to resolve during graph reading. The references added here are shared 116 * among all graphs. 117 * 118 * @param references An alternating argument list of keys (Strings) and values. 119 */ 120 public void addReferences(Object... references) { 121 getGraphReader().addReferencesByKeysAndValues(references); 122 } 123 124 /** 125 * Loads a graph file from the specified resource and adds it to this environment. 126 * 127 * @param context The context in which to read the resource. 128 * @param resourceId The ID of the graph resource to load. 129 * @return A unique ID for the graph. 130 */ 131 public int loadGraph(Context context, int resourceId) { 132 // Read the file into a graph 133 FilterGraph graph = null; 134 try { 135 graph = getGraphReader().readGraphResource(context, resourceId); 136 } catch (GraphIOException e) { 137 throw new RuntimeException("Could not read graph: " + e.getMessage()); 138 } 139 140 // Add graph to our list of graphs 141 return addGraph(graph); 142 } 143 144 /** 145 * Add a graph to the environment. Consider using loadGraph() if you are loading a graph from 146 * a graph file. 147 * 148 * @param graph The graph to add to the environment. 149 * @return A unique ID for the added graph. 150 */ 151 public int addGraph(FilterGraph graph) { 152 GraphHandle graphHandle = new GraphHandle(graph); 153 mGraphs.add(graphHandle); 154 return mGraphs.size() - 1; 155 } 156 157 /** 158 * Access a specific graph of this environment given a graph ID (previously returned from 159 * loadGraph() or addGraph()). Throws an InvalidArgumentException if no graph with the 160 * specified ID could be found. 161 * 162 * @param graphId The ID of the graph to get. 163 * @return The graph with the specified ID. 164 */ 165 public FilterGraph getGraph(int graphId) { 166 if (graphId < 0 || graphId >= mGraphs.size()) { 167 throw new IllegalArgumentException( 168 "Invalid graph ID " + graphId + " specified in runGraph()!"); 169 } 170 return mGraphs.get(graphId).getGraph(); 171 } 172 173 /** 174 * Get a GraphRunner instance for the graph with the specified ID. The GraphRunner instance can 175 * be used to execute the graph. Throws an InvalidArgumentException if no graph with the 176 * specified ID could be found. 177 * 178 * @param graphId The ID of the graph to get. 179 * @param executionMode The mode of graph execution. Currently this can be either 180 MODE_SYNCHRONOUS or MODE_ASYNCHRONOUS. 181 * @return A GraphRunner instance for this graph. 182 */ 183 public GraphRunner getRunner(int graphId, int executionMode) { 184 switch (executionMode) { 185 case MODE_ASYNCHRONOUS: 186 return mGraphs.get(graphId).getAsyncRunner(getContext()); 187 188 case MODE_SYNCHRONOUS: 189 return mGraphs.get(graphId).getSyncRunner(getContext()); 190 191 default: 192 throw new RuntimeException( 193 "Invalid execution mode " + executionMode + " specified in getRunner()!"); 194 } 195 } 196 197 } 198