165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/* 265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project 365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License"); 565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License. 665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at 765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * http://www.apache.org/licenses/LICENSE-2.0 965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software 1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS, 1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and 1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License. 1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpackage android.filterfw; 1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.content.Context; 2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.AsyncRunner; 2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.FilterGraph; 2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.FilterContext; 2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.FrameManager; 2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.GraphRunner; 2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.RoundRobinScheduler; 2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.SyncRunner; 2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.io.GraphIOException; 2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.io.GraphReader; 3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.io.TextGraphReader; 3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.ArrayList; 3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/** 3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * A GraphEnvironment provides a simple front-end to filter graph setup and execution using the 3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * mobile filter framework. Typically, you use a GraphEnvironment in the following fashion: 3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 1. Instantiate a new GraphEnvironment instance. 3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 2. Perform any configuration, such as adding graph references and setting a GL environment. 3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 3. Load a graph file using loadGraph() or add a graph using addGraph(). 4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 4. Obtain a GraphRunner instance using getRunner(). 4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 5. Execute the obtained runner. 4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Note that it is possible to add multiple graphs and runners to a single GraphEnvironment. 4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @hide 4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpublic class GraphEnvironment extends MffEnvironment { 4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public static final int MODE_ASYNCHRONOUS = 1; 4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public static final int MODE_SYNCHRONOUS = 2; 5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private GraphReader mGraphReader; 5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private ArrayList<GraphHandle> mGraphs = new ArrayList<GraphHandle>(); 5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private class GraphHandle { 5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private FilterGraph mGraph; 5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private AsyncRunner mAsyncRunner; 5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private SyncRunner mSyncRunner; 5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public GraphHandle(FilterGraph graph) { 6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mGraph = graph; 6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public FilterGraph getGraph() { 6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mGraph; 6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public AsyncRunner getAsyncRunner(FilterContext environment) { 6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mAsyncRunner == null) { 6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mAsyncRunner = new AsyncRunner(environment, RoundRobinScheduler.class); 7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mAsyncRunner.setGraph(mGraph); 7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mAsyncRunner; 7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public GraphRunner getSyncRunner(FilterContext environment) { 7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mSyncRunner == null) { 7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mSyncRunner = new SyncRunner(environment, mGraph, RoundRobinScheduler.class); 7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mSyncRunner; 8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Create a new GraphEnvironment with default components. 8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public GraphEnvironment() { 8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn super(null); 8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Create a new GraphEnvironment with a custom FrameManager and GraphReader. Specifying null 9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * for either of these, will auto-create a default instance. 9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param frameManager The FrameManager to use, or null to auto-create one. 9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param reader The GraphReader to use for graph loading, or null to auto-create one. 9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Note, that the reader will not be created until it is required. Pass 9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * null if you will not load any graph files. 9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public GraphEnvironment(FrameManager frameManager, GraphReader reader) { 10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn super(frameManager); 10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mGraphReader = reader; 10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Returns the used graph reader. This will create one, if a reader has not been set already. 10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public GraphReader getGraphReader() { 10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mGraphReader == null) { 10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mGraphReader = new TextGraphReader(); 11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mGraphReader; 11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Add graph references to resolve during graph reading. The references added here are shared 11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * among all graphs. 11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param references An alternating argument list of keys (Strings) and values. 11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void addReferences(Object... references) { 12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn getGraphReader().addReferencesByKeysAndValues(references); 12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Loads a graph file from the specified resource and adds it to this environment. 12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param context The context in which to read the resource. 12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param resourceId The ID of the graph resource to load. 12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @return A unique ID for the graph. 13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public int loadGraph(Context context, int resourceId) { 13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Read the file into a graph 13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FilterGraph graph = null; 13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn try { 13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn graph = getGraphReader().readGraphResource(context, resourceId); 13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } catch (GraphIOException e) { 13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException("Could not read graph: " + e.getMessage()); 13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Add graph to our list of graphs 14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return addGraph(graph); 14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Add a graph to the environment. Consider using loadGraph() if you are loading a graph from 14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * a graph file. 14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param graph The graph to add to the environment. 14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @return A unique ID for the added graph. 15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public int addGraph(FilterGraph graph) { 15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GraphHandle graphHandle = new GraphHandle(graph); 15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mGraphs.add(graphHandle); 15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mGraphs.size() - 1; 15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Access a specific graph of this environment given a graph ID (previously returned from 15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * loadGraph() or addGraph()). Throws an InvalidArgumentException if no graph with the 16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * specified ID could be found. 16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param graphId The ID of the graph to get. 16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @return The graph with the specified ID. 16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public FilterGraph getGraph(int graphId) { 16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (graphId < 0 || graphId >= mGraphs.size()) { 16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new IllegalArgumentException( 16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "Invalid graph ID " + graphId + " specified in runGraph()!"); 16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mGraphs.get(graphId).getGraph(); 17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Get a GraphRunner instance for the graph with the specified ID. The GraphRunner instance can 17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * be used to execute the graph. Throws an InvalidArgumentException if no graph with the 17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * specified ID could be found. 17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param graphId The ID of the graph to get. 17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param executionMode The mode of graph execution. Currently this can be either 18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn MODE_SYNCHRONOUS or MODE_ASYNCHRONOUS. 18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @return A GraphRunner instance for this graph. 18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public GraphRunner getRunner(int graphId, int executionMode) { 18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn switch (executionMode) { 18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case MODE_ASYNCHRONOUS: 18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mGraphs.get(graphId).getAsyncRunner(getContext()); 18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case MODE_SYNCHRONOUS: 18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mGraphs.get(graphId).getSyncRunner(getContext()); 19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn default: 19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException( 19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "Invalid execution mode " + executionMode + " specified in getRunner()!"); 19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 198