Home | History | Annotate | Download | only in cpp
      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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    244 Element::~Element() {
    245 }
    246 
    247 void Element::updateFromNative() {
    248     BaseObj::updateFromNative();
    249     updateVisibleSubElements();
    250 }
    251 
    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 
    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 
    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 
    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 
    332 Element::Builder::Builder(sp<RS> rs) {
    333     mRS = rs;
    334     mSkipPadding = false;
    335 }
    336 
    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 
    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