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 #include <malloc.h>
18 #include <string.h>
19
20 #include "RenderScript.h"
21 #include <rs.h>
22
23 using namespace android;
24 using namespace RSC;
25
getSubElement(uint32_t index)26 sp<const Element> Element::getSubElement(uint32_t index) {
27 if (!mVisibleElementMap.size()) {
28 mRS->throwError("Element contains no sub-elements");
29 }
30 if (index >= mVisibleElementMap.size()) {
31 mRS->throwError("Illegal sub-element index");
32 }
33 return mElements[mVisibleElementMap[index]];
34 }
35
getSubElementName(uint32_t index)36 const char * Element::getSubElementName(uint32_t index) {
37 if (!mVisibleElementMap.size()) {
38 mRS->throwError("Element contains no sub-elements");
39 }
40 if (index >= mVisibleElementMap.size()) {
41 mRS->throwError("Illegal sub-element index");
42 }
43 return mElementNames[mVisibleElementMap[index]].string();
44 }
45
getSubElementArraySize(uint32_t index)46 size_t Element::getSubElementArraySize(uint32_t index) {
47 if (!mVisibleElementMap.size()) {
48 mRS->throwError("Element contains no sub-elements");
49 }
50 if (index >= mVisibleElementMap.size()) {
51 mRS->throwError("Illegal sub-element index");
52 }
53 return mArraySizes[mVisibleElementMap[index]];
54 }
55
getSubElementOffsetBytes(uint32_t index)56 uint32_t Element::getSubElementOffsetBytes(uint32_t index) {
57 if (mVisibleElementMap.size()) {
58 mRS->throwError("Element contains no sub-elements");
59 }
60 if (index >= mVisibleElementMap.size()) {
61 mRS->throwError("Illegal sub-element index");
62 }
63 return mOffsetInBytes[mVisibleElementMap[index]];
64 }
65
66
67 #define CREATE_USER(N, T) sp<const Element> Element::N(sp<RS> rs) { \
68 return createUser(rs, RS_TYPE_##T); \
69 }
70 CREATE_USER(BOOLEAN, BOOLEAN);
71 CREATE_USER(U8, UNSIGNED_8);
72 CREATE_USER(I8, SIGNED_8);
73 CREATE_USER(U16, UNSIGNED_16);
74 CREATE_USER(I16, SIGNED_16);
75 CREATE_USER(U32, UNSIGNED_32);
76 CREATE_USER(I32, SIGNED_32);
77 CREATE_USER(U64, UNSIGNED_64);
78 CREATE_USER(I64, SIGNED_64);
79 CREATE_USER(F32, FLOAT_32);
80 CREATE_USER(F64, FLOAT_64);
81 CREATE_USER(ELEMENT, ELEMENT);
82 CREATE_USER(TYPE, TYPE);
83 CREATE_USER(ALLOCATION, ALLOCATION);
84 CREATE_USER(SAMPLER, SAMPLER);
85 CREATE_USER(SCRIPT, SCRIPT);
86 CREATE_USER(MESH, MESH);
87 CREATE_USER(PROGRAM_FRAGMENT, PROGRAM_FRAGMENT);
88 CREATE_USER(PROGRAM_VERTEX, PROGRAM_VERTEX);
89 CREATE_USER(PROGRAM_RASTER, PROGRAM_RASTER);
90 CREATE_USER(PROGRAM_STORE, PROGRAM_STORE);
91 CREATE_USER(MATRIX_4X4, MATRIX_4X4);
92 CREATE_USER(MATRIX_3X3, MATRIX_3X3);
93 CREATE_USER(MATRIX_2X2, MATRIX_2X2);
94
95 #define CREATE_PIXEL(N, T, K) sp<const Element> Element::N(sp<RS> rs) { \
96 return createPixel(rs, RS_TYPE_##T, RS_KIND_##K); \
97 }
98 CREATE_PIXEL(A_8, UNSIGNED_8, PIXEL_A);
99 CREATE_PIXEL(RGB_565, UNSIGNED_5_6_5, PIXEL_RGB);
100 CREATE_PIXEL(RGB_888, UNSIGNED_8, PIXEL_RGB);
101 CREATE_PIXEL(RGBA_4444, UNSIGNED_4_4_4_4, PIXEL_RGBA);
102 CREATE_PIXEL(RGBA_8888, UNSIGNED_8, PIXEL_RGBA);
103
104 #define CREATE_VECTOR(N, T) sp<const Element> Element::N##_2(sp<RS> rs) { \
105 return createVector(rs, RS_TYPE_##T, 2); \
106 } \
107 sp<const Element> Element::N##_3(sp<RS> rs) { \
108 return createVector(rs, RS_TYPE_##T, 3); \
109 } \
110 sp<const Element> Element::N##_4(sp<RS> rs) { \
111 return createVector(rs, RS_TYPE_##T, 4); \
112 }
113 CREATE_VECTOR(U8, UNSIGNED_8);
114 CREATE_VECTOR(I8, SIGNED_8);
115 CREATE_VECTOR(U16, UNSIGNED_16);
116 CREATE_VECTOR(I16, SIGNED_16);
117 CREATE_VECTOR(U32, UNSIGNED_32);
118 CREATE_VECTOR(I32, SIGNED_32);
119 CREATE_VECTOR(U64, UNSIGNED_64);
120 CREATE_VECTOR(I64, SIGNED_64);
121 CREATE_VECTOR(F32, FLOAT_32);
122 CREATE_VECTOR(F64, FLOAT_64);
123
124
updateVisibleSubElements()125 void Element::updateVisibleSubElements() {
126 if (!mElements.size()) {
127 return;
128 }
129 mVisibleElementMap.clear();
130
131 int noPaddingFieldCount = 0;
132 size_t fieldCount = mElementNames.size();
133 // Find out how many elements are not padding
134 for (size_t ct = 0; ct < fieldCount; ct ++) {
135 if (mElementNames[ct].string()[0] != '#') {
136 noPaddingFieldCount ++;
137 }
138 }
139
140 // Make a map that points us at non-padding elements
141 for (size_t ct = 0; ct < fieldCount; ct ++) {
142 if (mElementNames[ct].string()[0] != '#') {
143 mVisibleElementMap.push((uint32_t)ct);
144 }
145 }
146 }
147
Element(void * id,sp<RS> rs,android::Vector<sp<Element>> & elements,android::Vector<android::String8> & elementNames,android::Vector<uint32_t> & arraySizes)148 Element::Element(void *id, sp<RS> rs,
149 android::Vector<sp<Element> > &elements,
150 android::Vector<android::String8> &elementNames,
151 android::Vector<uint32_t> &arraySizes) : BaseObj(id, rs) {
152 mSizeBytes = 0;
153 mVectorSize = 1;
154 mElements = elements;
155 mArraySizes = arraySizes;
156 mElementNames = elementNames;
157
158 mType = RS_TYPE_NONE;
159 mKind = RS_KIND_USER;
160
161 for (size_t ct = 0; ct < mElements.size(); ct++ ) {
162 mOffsetInBytes.push(mSizeBytes);
163 mSizeBytes += mElements[ct]->mSizeBytes * mArraySizes[ct];
164 }
165 updateVisibleSubElements();
166 }
167
168
GetSizeInBytesForType(RsDataType dt)169 static uint32_t GetSizeInBytesForType(RsDataType dt) {
170 switch(dt) {
171 case RS_TYPE_NONE:
172 return 0;
173 case RS_TYPE_SIGNED_8:
174 case RS_TYPE_UNSIGNED_8:
175 case RS_TYPE_BOOLEAN:
176 return 1;
177
178 case RS_TYPE_FLOAT_16:
179 case RS_TYPE_SIGNED_16:
180 case RS_TYPE_UNSIGNED_16:
181 case RS_TYPE_UNSIGNED_5_6_5:
182 case RS_TYPE_UNSIGNED_5_5_5_1:
183 case RS_TYPE_UNSIGNED_4_4_4_4:
184 return 2;
185
186 case RS_TYPE_FLOAT_32:
187 case RS_TYPE_SIGNED_32:
188 case RS_TYPE_UNSIGNED_32:
189 return 4;
190
191 case RS_TYPE_FLOAT_64:
192 case RS_TYPE_SIGNED_64:
193 case RS_TYPE_UNSIGNED_64:
194 return 8;
195
196 case RS_TYPE_MATRIX_4X4:
197 return 16 * 4;
198 case RS_TYPE_MATRIX_3X3:
199 return 9 * 4;
200 case RS_TYPE_MATRIX_2X2:
201 return 4 * 4;
202
203 case RS_TYPE_TYPE:
204 case RS_TYPE_ALLOCATION:
205 case RS_TYPE_SAMPLER:
206 case RS_TYPE_SCRIPT:
207 case RS_TYPE_MESH:
208 case RS_TYPE_PROGRAM_FRAGMENT:
209 case RS_TYPE_PROGRAM_VERTEX:
210 case RS_TYPE_PROGRAM_RASTER:
211 case RS_TYPE_PROGRAM_STORE:
212 return 4;
213
214 default:
215 break;
216 }
217
218 ALOGE("Missing type %i", dt);
219 return 0;
220 }
221
Element(void * id,sp<RS> rs,RsDataType dt,RsDataKind dk,bool norm,uint32_t size)222 Element::Element(void *id, sp<RS> rs,
223 RsDataType dt, RsDataKind dk, bool norm, uint32_t size) :
224 BaseObj(id, rs)
225 {
226 uint32_t tsize = GetSizeInBytesForType(dt);
227 if ((dt != RS_TYPE_UNSIGNED_5_6_5) &&
228 (dt != RS_TYPE_UNSIGNED_4_4_4_4) &&
229 (dt != RS_TYPE_UNSIGNED_5_5_5_1)) {
230 if (size == 3) {
231 mSizeBytes = tsize * 4;
232 } else {
233 mSizeBytes = tsize * size;
234 }
235 } else {
236 mSizeBytes = tsize;
237 }
238 mType = dt;
239 mKind = dk;
240 mNormalized = norm;
241 mVectorSize = size;
242 }
243
~Element()244 Element::~Element() {
245 }
246
updateFromNative()247 void Element::updateFromNative() {
248 BaseObj::updateFromNative();
249 updateVisibleSubElements();
250 }
251
createUser(sp<RS> rs,RsDataType dt)252 sp<const Element> Element::createUser(sp<RS> rs, RsDataType dt) {
253 void * id = rsElementCreate(rs->getContext(), dt, RS_KIND_USER, false, 1);
254 return new Element(id, rs, dt, RS_KIND_USER, false, 1);
255 }
256
createVector(sp<RS> rs,RsDataType dt,uint32_t size)257 sp<const Element> Element::createVector(sp<RS> rs, RsDataType dt, uint32_t size) {
258 if (size < 2 || size > 4) {
259 rs->throwError("Vector size out of range 2-4.");
260 }
261 void *id = rsElementCreate(rs->getContext(), dt, RS_KIND_USER, false, size);
262 return new Element(id, rs, dt, RS_KIND_USER, false, size);
263 }
264
createPixel(sp<RS> rs,RsDataType dt,RsDataKind dk)265 sp<const Element> Element::createPixel(sp<RS> rs, RsDataType dt, RsDataKind dk) {
266 if (!(dk == RS_KIND_PIXEL_L ||
267 dk == RS_KIND_PIXEL_A ||
268 dk == RS_KIND_PIXEL_LA ||
269 dk == RS_KIND_PIXEL_RGB ||
270 dk == RS_KIND_PIXEL_RGBA ||
271 dk == RS_KIND_PIXEL_DEPTH)) {
272 rs->throwError("Unsupported DataKind");
273 }
274 if (!(dt == RS_TYPE_UNSIGNED_8 ||
275 dt == RS_TYPE_UNSIGNED_16 ||
276 dt == RS_TYPE_UNSIGNED_5_6_5 ||
277 dt == RS_TYPE_UNSIGNED_4_4_4_4 ||
278 dt == RS_TYPE_UNSIGNED_5_5_5_1)) {
279 rs->throwError("Unsupported DataType");
280 }
281 if (dt == RS_TYPE_UNSIGNED_5_6_5 && dk != RS_KIND_PIXEL_RGB) {
282 rs->throwError("Bad kind and type combo");
283 }
284 if (dt == RS_TYPE_UNSIGNED_5_5_5_1 && dk != RS_KIND_PIXEL_RGBA) {
285 rs->throwError("Bad kind and type combo");
286 }
287 if (dt == RS_TYPE_UNSIGNED_4_4_4_4 && dk != RS_KIND_PIXEL_RGBA) {
288 rs->throwError("Bad kind and type combo");
289 }
290 if (dt == RS_TYPE_UNSIGNED_16 && dk != RS_KIND_PIXEL_DEPTH) {
291 rs->throwError("Bad kind and type combo");
292 }
293
294 int size = 1;
295 switch (dk) {
296 case RS_KIND_PIXEL_LA:
297 size = 2;
298 break;
299 case RS_KIND_PIXEL_RGB:
300 size = 3;
301 break;
302 case RS_KIND_PIXEL_RGBA:
303 size = 4;
304 break;
305 case RS_KIND_PIXEL_DEPTH:
306 size = 2;
307 break;
308 default:
309 break;
310 }
311
312 void * id = rsElementCreate(rs->getContext(), dt, dk, true, size);
313 return new Element(id, rs, dt, dk, true, size);
314 }
315
isCompatible(sp<const Element> e)316 bool Element::isCompatible(sp<const Element>e) {
317 // Try strict BaseObj equality to start with.
318 if (this == e.get()) {
319 return true;
320 }
321
322 // Ignore mKind because it is allowed to be different (user vs. pixel).
323 // We also ignore mNormalized because it can be different. The mType
324 // field must be non-null since we require name equivalence for
325 // user-created Elements.
326 return ((mSizeBytes == e->mSizeBytes) &&
327 (mType != RS_TYPE_NONE) &&
328 (mType == e->mType) &&
329 (mVectorSize == e->mVectorSize));
330 }
331
Builder(sp<RS> rs)332 Element::Builder::Builder(sp<RS> rs) {
333 mRS = rs;
334 mSkipPadding = false;
335 }
336
add(sp<Element> e,android::String8 & name,uint32_t arraySize)337 void Element::Builder::add(sp</*const*/ Element>e, android::String8 &name, uint32_t arraySize) {
338 // Skip padding fields after a vector 3 type.
339 if (mSkipPadding) {
340 const char *s1 = "#padding_";
341 const char *s2 = name.string();
342 size_t len = strlen(s1);
343 if (strlen(s2) >= len) {
344 if (!memcmp(s1, s2, len)) {
345 mSkipPadding = false;
346 return;
347 }
348 }
349 }
350
351 if (e->mVectorSize == 3) {
352 mSkipPadding = true;
353 } else {
354 mSkipPadding = false;
355 }
356
357 mElements.add(e);
358 mElementNames.add(name);
359 mArraySizes.add(arraySize);
360 }
361
create()362 sp<const Element> Element::Builder::create() {
363 size_t fieldCount = mElements.size();
364 const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *));
365 const Element ** elementArray = (const Element **)calloc(fieldCount, sizeof(Element *));
366 size_t* sizeArray = (size_t*)calloc(fieldCount, sizeof(size_t));
367
368 for (size_t ct = 0; ct < fieldCount; ct++) {
369 nameArray[ct] = mElementNames[ct].string();
370 elementArray[ct] = mElements[ct].get();
371 sizeArray[ct] = mElementNames[ct].length();
372 }
373
374 void *id = rsElementCreate2(mRS->getContext(),
375 (RsElement *)elementArray, fieldCount,
376 nameArray, fieldCount * sizeof(size_t), sizeArray,
377 (const uint32_t *)mArraySizes.array(), fieldCount);
378
379
380 free(nameArray);
381 free(sizeArray);
382 free(elementArray);
383 return new Element(id, mRS, mElements, mElementNames, mArraySizes);
384 }
385
386