Home | History | Annotate | Download | only in rs
      1 /*
      2  * Copyright (C) 2009 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 "rsContext.h"
     18 
     19 #include <GLES/gl.h>
     20 
     21 using namespace android;
     22 using namespace android::renderscript;
     23 
     24 
     25 Element::Element(Context *rsc) : ObjectBase(rsc)
     26 {
     27     mBits = 0;
     28     mAllocFile = __FILE__;
     29     mAllocLine = __LINE__;
     30     mFields = NULL;
     31     mFieldCount = 0;
     32 }
     33 
     34 
     35 Element::~Element()
     36 {
     37     for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) {
     38         if (mRSC->mStateElement.mElements[ct] == this) {
     39             mRSC->mStateElement.mElements.removeAt(ct);
     40             break;
     41         }
     42     }
     43     clear();
     44 }
     45 
     46 void Element::clear()
     47 {
     48     delete [] mFields;
     49     mFields = NULL;
     50     mFieldCount = 0;
     51 }
     52 
     53 size_t Element::getSizeBits() const
     54 {
     55     if (!mFieldCount) {
     56         return mBits;
     57     }
     58 
     59     size_t total = 0;
     60     for (size_t ct=0; ct < mFieldCount; ct++) {
     61         total += mFields[ct].e->mBits;
     62     }
     63     return total;
     64 }
     65 
     66 size_t Element::getFieldOffsetBits(uint32_t componentNumber) const
     67 {
     68     size_t offset = 0;
     69     for (uint32_t ct = 0; ct < componentNumber; ct++) {
     70         offset += mFields[ct].e->mBits;
     71     }
     72     return offset;
     73 }
     74 
     75 void Element::dumpLOGV(const char *prefix) const
     76 {
     77     ObjectBase::dumpLOGV(prefix);
     78     LOGV("%s   Element: components %i,  size %i", prefix, mFieldCount, mBits);
     79     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
     80         char buf[1024];
     81         sprintf(buf, "%s component %i: ", prefix, ct);
     82         //mComponents[ct]->dumpLOGV(buf);
     83     }
     84 }
     85 
     86 
     87 const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
     88                             bool isNorm, uint32_t vecSize)
     89 {
     90     // Look for an existing match.
     91     for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
     92         const Element *ee = rsc->mStateElement.mElements[ct];
     93         if (!ee->getFieldCount() &&
     94             (ee->getComponent().getType() == dt) &&
     95             (ee->getComponent().getKind() == dk) &&
     96             (ee->getComponent().getIsNormalized() == isNorm) &&
     97             (ee->getComponent().getVectorSize() == vecSize)) {
     98             // Match
     99             ee->incUserRef();
    100             return ee;
    101         }
    102     }
    103 
    104     Element *e = new Element(rsc);
    105     e->mComponent.set(dt, dk, isNorm, vecSize);
    106     e->mBits = e->mComponent.getBits();
    107     rsc->mStateElement.mElements.push(e);
    108     return e;
    109 }
    110 
    111 const Element * Element::create(Context *rsc, size_t count, const Element **ein,
    112                             const char **nin, const size_t * lengths)
    113 {
    114     // Look for an existing match.
    115     for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
    116         const Element *ee = rsc->mStateElement.mElements[ct];
    117         if (ee->getFieldCount() == count) {
    118             bool match = true;
    119             for (uint32_t i=0; i < count; i++) {
    120                 if ((ee->mFields[i].e.get() != ein[i]) ||
    121                     (ee->mFields[i].name.length() != lengths[i]) ||
    122                     (ee->mFields[i].name != nin[i])) {
    123                     match = false;
    124                     break;
    125                 }
    126             }
    127             if (match) {
    128                 ee->incUserRef();
    129                 return ee;
    130             }
    131         }
    132     }
    133 
    134     Element *e = new Element(rsc);
    135     e->mFields = new ElementField_t [count];
    136     e->mFieldCount = count;
    137     for (size_t ct=0; ct < count; ct++) {
    138         e->mFields[ct].e.set(ein[ct]);
    139         e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
    140     }
    141 
    142     rsc->mStateElement.mElements.push(e);
    143     return e;
    144 }
    145 
    146 String8 Element::getCStructBody(uint32_t indent) const
    147 {
    148     String8 si;
    149     for (uint32_t ct=0; ct < indent; ct++) {
    150         si.append(" ");
    151     }
    152 
    153     String8 s(si);
    154     s.append("{\n");
    155     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
    156         s.append(si);
    157         s.append(mFields[ct].e->getCType(indent+4));
    158         s.append(" ");
    159         s.append(mFields[ct].name);
    160         s.append(";\n");
    161     }
    162     s.append(si);
    163     s.append("}");
    164     return s;
    165 }
    166 
    167 String8 Element::getCType(uint32_t indent) const
    168 {
    169     String8 s;
    170     for (uint32_t ct=0; ct < indent; ct++) {
    171         s.append(" ");
    172     }
    173 
    174     if (!mFieldCount) {
    175         // Basic component.
    176         s.append(mComponent.getCType());
    177     } else {
    178         s.append("struct ");
    179         s.append(getCStructBody(indent));
    180     }
    181 
    182     return s;
    183 }
    184 
    185 String8 Element::getGLSLType(uint32_t indent) const
    186 {
    187     String8 s;
    188     for (uint32_t ct=0; ct < indent; ct++) {
    189         s.append(" ");
    190     }
    191 
    192     if (!mFieldCount) {
    193         // Basic component.
    194         s.append(mComponent.getGLSLType());
    195     } else {
    196         rsAssert(0);
    197         //s.append("struct ");
    198         //s.append(getCStructBody(indent));
    199     }
    200 
    201     return s;
    202 }
    203 
    204 
    205 
    206 ElementState::ElementState()
    207 {
    208 }
    209 
    210 ElementState::~ElementState()
    211 {
    212     rsAssert(!mElements.size());
    213 }
    214 
    215 
    216 /////////////////////////////////////////
    217 //
    218 
    219 namespace android {
    220 namespace renderscript {
    221 
    222 RsElement rsi_ElementCreate(Context *rsc,
    223                             RsDataType dt,
    224                             RsDataKind dk,
    225                             bool norm,
    226                             uint32_t vecSize)
    227 {
    228     //LOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize);
    229     const Element *e = Element::create(rsc, dt, dk, norm, vecSize);
    230     e->incUserRef();
    231     return (RsElement)e;
    232 }
    233 
    234 RsElement rsi_ElementCreate2(Context *rsc,
    235                              size_t count,
    236                              const RsElement * ein,
    237                              const char ** names,
    238                              const size_t * nameLengths)
    239 {
    240     //LOGE("rsi_ElementCreate2 %i", count);
    241     const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths);
    242     e->incUserRef();
    243     return (RsElement)e;
    244 }
    245 
    246 
    247 }
    248 }
    249