• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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