1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/*
2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright (C) 2011 The Android Open Source Project
3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * in compliance with the License. You may obtain a copy of the License at
6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * http://www.apache.org/licenses/LICENSE-2.0
8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software distributed under the License
10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * or implied. See the License for the specific language governing permissions and limitations under
12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * the License.
13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */
14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspackage androidx.media.filterfw;
16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/**
19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * A FrameType instance specifies the data format of a Frame.
20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * FrameTypes are used mainly by Filters to specify the data type they intend to consume or produce.
22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * When filters are connected, their FrameType information is analyzed and checked for
23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * compatibility. This allows Filter writers to assume a certain data input type. It also helps
24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * filter-graph designers determine which filters can be hooked up to one another.
25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * A FrameType generally consists of an element type and number of dimensions. The currently
27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * supported element types are:
28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <ul>
30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <li>int8, int16, int32, in64</li>
31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <li>float32, float64</li>
32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <li>rgba8888</li>
33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <li>object</li>
34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <li>don't-care</li>
35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * </ul>
36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * If the object element type is used, class information may be appended to the FrameType to
38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * indicate what class of objects are expected. When constructing an object based FrameType, you
39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * have the option of either specifying a type that represents a single object of that class, or
40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * an array of objects (see the {@link #single()} and {@link #array()} constructors). A single
41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * object has a dimensionality of 0, while an array has a dimensionality of 1.
42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * When constructing a non-object type, you have the option of creating a 1D or 2D buffer, or
44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * a 2D image (see the {@link #buffer1D(int)}, {@link #buffer2D(int)}, and
45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link #image2D(int, int)} constructors). To optimize access, provide access hints when making
46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * an image type.
47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Finally, it is possible to create a wild-card type with the {@link #any()} constructor. This
49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * type matches any other type. Note, that this is a more general type than a {@code single(Object)}
50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * type that matches only object-base types (of any Object subclass). You may also specify the
51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * leave the element of any type unspecified by using the {@code ELEMENT_DONTCARE} constant.
52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * When a graph is connected the types between outputs and inputs are merged to a queue-type. All
54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Frames in this queue will be of that type. In order for a merge to succeed the following
55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * conditions must hold:
56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <ul>
58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <li>The element types must be identical.</li>
59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <li>The dimensions must match (except for singles and arrays, see below).</li>
60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <li>For object-based types: The classes must be compatible.</li>
61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <li>If one of the types is a wild-card, both types are always compatible.</li>
62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * </ul>
63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Class compatibility is determined in an optimistic fashion, i.e. one class must be the subclass
65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * of the other. It does not matter which of the types is the subclass of the other. For instance,
66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * if one Filter outputs a type of class {@code Object}, and the consumer expects a Filter of type
67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@code Bitmap}, the connection is considered compatible. (Of course if at runtime a non-Bitmap
68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * object is produced, this will cause a runtime exception to be thrown).
69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * For convenience, single and array object-based types are compatible with one another. This
71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * in turn means that Frames with a single object can be accessed as an array with a single entry,
72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * and array based Frames can be accessed as a single object of the array class. For this reason
73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you should prefer consuming objects as array types (if it makes sense for that specific port),
74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * as this will allow your Filter to handle multiple objects in one Frame while not giving up the
75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * possibility to deal with singles.
76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * TODO: This needs to be reworked. An array(int) should not be interchangeable with a single(int),
77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * but rather with a single(int[]). Use ArraySelectFilter for the former!
78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * After the types are merged, the queue-type must be a fully specified type. This means that the
80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * type must have its element and dimensions specified. This ensures that filters that need to
81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * query their input or output types receive meaningful information.
82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */
83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic final class FrameType {
84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int ELEMENT_DONTCARE = 0;
86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int ELEMENT_OBJECT = 1;
87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int ELEMENT_INT8 = 100;
89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int ELEMENT_INT16 = 101;
90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int ELEMENT_INT32 = 102;
91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int ELEMENT_INT64 = 103;
92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int ELEMENT_FLOAT32 = 200;
94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int ELEMENT_FLOAT64 = 201;
95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int ELEMENT_RGBA8888 = 301;
97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int READ_CPU = 0x01;
99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int READ_GPU = 0x02;
100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int READ_ALLOCATION = 0x04;
101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int WRITE_CPU = 0x08;
102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int WRITE_GPU = 0x10;
103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public final static int WRITE_ALLOCATION = 0x20;
104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private final static int ACCESS_UNKNOWN = 0x00;
106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private final int mElementId;
108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private final int mDimensions;
109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private final int mAccessHints;
110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private final Class<?> mClass;
111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static SimpleCache<String, FrameType> mTypeCache =
113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            new SimpleCache<String, FrameType>(64);
114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Constructs a wild-card FrameType that matches any other FrameType.
117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return The wild-card FrameType instance.
118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static FrameType any() {
120227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return FrameType.fetchType(ELEMENT_DONTCARE, -1, ACCESS_UNKNOWN);
121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Constructs an object-based single FrameType that matches object-based FrameTypes of any
125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * class.
126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return A single object-based FrameType instance.
127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static FrameType single() {
129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return FrameType.fetchType(null, 0);
130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Constructs an object-based single FrameType of the specified class.
134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param clazz The class of the FrameType.
135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return A single object-base FrameType instance of the specified class.
136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static FrameType single(Class<?> clazz) {
138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return FrameType.fetchType(clazz, 0);
139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Constructs an object-based array FrameType that matches object-based FrameTypes of any class.
143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return An array object-based FrameType instance.
144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static FrameType array() {
146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return FrameType.fetchType(null, 1);
147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Constructs an object-based array FrameType with elements of the specified class.
151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param clazz The class of the array elements (not the array type).
152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return An array object-based FrameType instance of the specified class.
153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static FrameType array(Class<?> clazz) {
155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return FrameType.fetchType(clazz, 1);
156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Constructs a one-dimensional buffer type of the specified element.
160227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param elementType One of the {@code ELEMENT} constants.
161227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return A 1D buffer FrameType instance.
162227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
163227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static FrameType buffer1D(int elementType) {
164227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return FrameType.fetchType(elementType, 1, ACCESS_UNKNOWN);
165227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
166227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
167227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
168227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Constructs a two-dimensional buffer type of the specified element.
169227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param elementType One of the {@code ELEMENT} constants.
170227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return A 2D buffer FrameType instance.
171227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
172227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static FrameType buffer2D(int elementType) {
173227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return FrameType.fetchType(elementType, 2, ACCESS_UNKNOWN);
174227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
175227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
176227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
177227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Constructs a two-dimensional image type of the specified element.
178227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param elementType One of the {@code ELEMENT} constants.
179227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param accessHint A bit-mask of access flags (see {@code READ} and {@code WRITE} constants).
180227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return A 2D image FrameType instance.
181227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
182227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static FrameType image2D(int elementType, int accessHint) {
183227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return FrameType.fetchType(elementType, 2, accessHint);
184227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
185227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
186227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
187227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Converts the current array type to a single type.
188227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * The type must be an object-based type. If the type is already a single type, this does
189227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * nothing.
190227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return type as a single type.
191227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
192227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public FrameType asSingle() {
193227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (mElementId != ELEMENT_OBJECT) {
194227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            throw new RuntimeException("Calling asSingle() on non-object type!");
195227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
196227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return FrameType.fetchType(mClass, 0);
197227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
198227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
199227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
200227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Converts the current single type to an array type.
201227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * The type must be an object-based type. If the type is already an array type, this does
202227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * nothing.
203227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return type as an array type.
204227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
205227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public FrameType asArray() {
206227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (mElementId != ELEMENT_OBJECT) {
207227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            throw new RuntimeException("Calling asArray() on non-object type!");
208227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
209227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return FrameType.fetchType(mClass, 1);
210227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
211227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
212227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
213227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Returns the FrameType's class specifier, or null if no class was set or the receiver is not
214227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * an object-based type.
215227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return The FrameType's class specifier or null.
216227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
217227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public Class<?> getContentClass() {
218227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return mClass;
219227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
220227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
221227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
222227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Returns the FrameType's element id.
223227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return The element id constant.
224227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
225227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public int getElementId() {
226227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return mElementId;
227227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
228227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
229227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
230227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Returns the number of bytes of the FrameType's element, or 0 if no such size can be
231227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * determined.
232227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return The number of bytes of the FrameType's element.
233227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
234227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public int getElementSize() {
235227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        switch (mElementId) {
236227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_INT8:
237227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return 1;
238227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_INT16:
239227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return 2;
240227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_INT32:
241227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_FLOAT32:
242227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_RGBA8888:
243227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return 4;
244227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_INT64:
245227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_FLOAT64:
246227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return 4;
247227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            default:
248227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return 0;
249227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
250227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
251227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
252227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
253227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Returns the access hints bit-mask of the FrameType.
254227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return The access hints bit-mask of the FrameType.
255227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
256227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public int getAccessHints() {
257227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return mAccessHints;
258227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
259227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
260227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
261227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Returns the number of dimensions of the FrameType or -1 if no dimensions were set.
262227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return The number of dimensions of the FrameType.
263227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
264227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public int getNumberOfDimensions() {
265227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return mDimensions;
266227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
267227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
268227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
269227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Returns true, if the FrameType is fully specified.
270227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
271227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * A FrameType is fully specified if its element and dimensions are specified.
272227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
273227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return true, if the FrameType is fully specified.
274227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
275227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public boolean isSpecified() {
276227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return mElementId != ELEMENT_DONTCARE && mDimensions >= 0;
277227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
278227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
279227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    @Override
280227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public boolean equals(Object object) {
281227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (object instanceof FrameType) {
282227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            FrameType type = (FrameType) object;
283227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return mElementId == type.mElementId && mDimensions == type.mDimensions
284227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    && mAccessHints == type.mAccessHints && mClass == type.mClass;
285227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
286227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return false;
287227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
288227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
289227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    @Override
290227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public int hashCode() {
291227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return mElementId ^ mDimensions ^ mAccessHints ^ mClass.hashCode();
292227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
293227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
294227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    @Override
295227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public String toString() {
296227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        String result = elementToString(mElementId, mClass) + "[" + mDimensions + "]";
297227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if ((mAccessHints & READ_CPU) != 0) {
298227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            result += "(rcpu)";
299227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
300227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if ((mAccessHints & READ_GPU) != 0) {
301227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            result += "(rgpu)";
302227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
303227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if ((mAccessHints & READ_ALLOCATION) != 0) {
304227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            result += "(ralloc)";
305227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
306227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if ((mAccessHints & WRITE_CPU) != 0) {
307227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            result += "(wcpu)";
308227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
309227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if ((mAccessHints & WRITE_GPU) != 0) {
310227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            result += "(wgpu)";
311227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
312227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if ((mAccessHints & WRITE_ALLOCATION) != 0) {
313227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            result += "(walloc)";
314227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
315227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return result;
316227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
317227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
318227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    String keyString() {
319227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return keyValueForType(mElementId, mDimensions, mAccessHints, mClass);
320227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
321227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
322227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    static FrameType tryMerge(FrameType writer, FrameType reader) {
323227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (writer.mElementId == ELEMENT_DONTCARE) {
324227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return reader;
325227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else if (reader.mElementId == ELEMENT_DONTCARE) {
326227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return writer;
327227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else if (writer.mElementId == ELEMENT_OBJECT && reader.mElementId == ELEMENT_OBJECT) {
328227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return tryMergeObjectTypes(writer, reader);
329227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else if (writer.mDimensions > 0 && writer.mElementId == reader.mElementId) {
330227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return tryMergeBuffers(writer, reader);
331227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else {
332227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return null;
333227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
334227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
335227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
336227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    static FrameType tryMergeObjectTypes(FrameType writer, FrameType reader) {
337227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        int dimensions = Math.max(writer.mDimensions, reader.mDimensions);
338227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        Class<?> mergedClass = mergeClasses(writer.mClass, reader.mClass);
339227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        boolean success = mergedClass != null || writer.mClass == null;
340227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return success ? FrameType.fetchType(mergedClass, dimensions) : null;
341227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
342227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
343227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    static FrameType tryMergeBuffers(FrameType writer, FrameType reader) {
344227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (writer.mDimensions == reader.mDimensions) {
345227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            int accessHints = writer.mAccessHints | reader.mAccessHints;
346227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return FrameType.fetchType(writer.mElementId, writer.mDimensions, accessHints);
347227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
348227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return null;
349227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
350227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
351227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    static FrameType merge(FrameType writer, FrameType reader) {
352227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        FrameType result = tryMerge(writer, reader);
353227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (result == null) {
354227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            throw new RuntimeException(
355227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    "Incompatible types in connection: " + writer + " vs. " + reader + "!");
356227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
357227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return result;
358227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
359227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
360227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static String keyValueForType(int elemId, int dims, int hints, Class<?> clazz) {
361227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return elemId + ":" + dims + ":" + hints + ":" + (clazz != null ? clazz.getName() : "0");
362227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
363227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
364227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static String elementToString(int elemId, Class<?> clazz) {
365227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        switch (elemId) {
366227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_INT8:
367227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return "int8";
368227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_INT16:
369227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return "int16";
370227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_INT32:
371227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return "int32";
372227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_INT64:
373227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return "int64";
374227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_FLOAT32:
375227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return "float32";
376227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_FLOAT64:
377227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return "float64";
378227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_RGBA8888:
379227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return "rgba8888";
380227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_OBJECT:
381227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return "<" + (clazz == null ? "*" : clazz.getSimpleName()) + ">";
382227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            case ELEMENT_DONTCARE:
383227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return "*";
384227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            default:
385227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return "?";
386227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
387227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
388227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
389227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static Class<?> mergeClasses(Class<?> classA, Class<?> classB) {
390227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        // Return the most specialized class.
391227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (classA == null) {
392227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return classB;
393227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else if (classB == null) {
394227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return classA;
395227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else if (classA.isAssignableFrom(classB)) {
396227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return classB;
397227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else if (classB.isAssignableFrom(classA)) {
398227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return classA;
399227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else {
400227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            return null;
401227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
402227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
403227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
404227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static FrameType fetchType(int elementId, int dimensions, int accessHints) {
405227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return fetchType(elementId, dimensions, accessHints, null);
406227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
407227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
408227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static FrameType fetchType(Class<?> clazz, int dimensions) {
409227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return fetchType(ELEMENT_OBJECT, dimensions, ACCESS_UNKNOWN, clazz);
410227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
411227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
412227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static FrameType fetchType(
413227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            int elementId, int dimensions, int accessHints, Class<?> clazz) {
414227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        String typeKey = FrameType.keyValueForType(elementId, dimensions, accessHints, clazz);
415227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        FrameType type = mTypeCache.get(typeKey);
416227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (type == null) {
417227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            type = new FrameType(elementId, dimensions, accessHints, clazz);
418227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            mTypeCache.put(typeKey, type);
419227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
420227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return type;
421227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
422227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
423227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private FrameType(int elementId, int dimensions, int accessHints, Class<?> clazz) {
424227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mElementId = elementId;
425227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mDimensions = dimensions;
426227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mClass = clazz;
427227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mAccessHints = accessHints;
428227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
429227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
430227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks}
431