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 #include <GLES/gl.h>
     19 
     20 using namespace android;
     21 using namespace android::renderscript;
     22 
     23 Type::Type(Context *rsc) : ObjectBase(rsc)
     24 {
     25     mAllocFile = __FILE__;
     26     mAllocLine = __LINE__;
     27     mLODs = 0;
     28     mLODCount = 0;
     29     clear();
     30 }
     31 
     32 Type::~Type()
     33 {
     34     for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
     35         if (mRSC->mStateType.mTypes[ct] == this) {
     36             mRSC->mStateType.mTypes.removeAt(ct);
     37             break;
     38         }
     39     }
     40     if (mLODs) {
     41         delete [] mLODs;
     42     }
     43 }
     44 
     45 void Type::clear()
     46 {
     47     if (mLODs) {
     48         delete [] mLODs;
     49         mLODs = NULL;
     50     }
     51     mDimX = 0;
     52     mDimY = 0;
     53     mDimZ = 0;
     54     mDimLOD = 0;
     55     mFaces = false;
     56     mElement.clear();
     57 }
     58 
     59 TypeState::TypeState()
     60 {
     61 }
     62 
     63 TypeState::~TypeState()
     64 {
     65 }
     66 
     67 size_t Type::getOffsetForFace(uint32_t face) const
     68 {
     69     rsAssert(mFaces);
     70     return 0;
     71 }
     72 
     73 void Type::compute()
     74 {
     75     uint32_t oldLODCount = mLODCount;
     76     if (mDimLOD) {
     77         uint32_t l2x = rsFindHighBit(mDimX) + 1;
     78         uint32_t l2y = rsFindHighBit(mDimY) + 1;
     79         uint32_t l2z = rsFindHighBit(mDimZ) + 1;
     80 
     81         mLODCount = rsMax(l2x, l2y);
     82         mLODCount = rsMax(mLODCount, l2z);
     83     } else {
     84         mLODCount = 1;
     85     }
     86     if (mLODCount != oldLODCount) {
     87         delete [] mLODs;
     88         mLODs = new LOD[mLODCount];
     89     }
     90 
     91     uint32_t tx = mDimX;
     92     uint32_t ty = mDimY;
     93     uint32_t tz = mDimZ;
     94     size_t offset = 0;
     95     for (uint32_t lod=0; lod < mLODCount; lod++) {
     96         mLODs[lod].mX = tx;
     97         mLODs[lod].mY = ty;
     98         mLODs[lod].mZ = tz;
     99         mLODs[lod].mOffset = offset;
    100         offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
    101         if (tx > 1) tx >>= 1;
    102         if (ty > 1) ty >>= 1;
    103         if (tz > 1) tz >>= 1;
    104     }
    105 
    106     // At this point the offset is the size of a mipmap chain;
    107     mMipChainSizeBytes = offset;
    108 
    109     if (mFaces) {
    110         offset *= 6;
    111     }
    112     mTotalSizeBytes = offset;
    113 
    114     makeGLComponents();
    115 }
    116 
    117 uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const
    118 {
    119     uint32_t offset = mLODs[lod].mOffset;
    120     offset += x * mElement->getSizeBytes();
    121     return offset;
    122 }
    123 
    124 uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const
    125 {
    126     uint32_t offset = mLODs[lod].mOffset;
    127     offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
    128     return offset;
    129 }
    130 
    131 uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const
    132 {
    133     uint32_t offset = mLODs[lod].mOffset;
    134     offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
    135     return offset;
    136 }
    137 
    138 
    139 void Type::makeGLComponents()
    140 {
    141     uint32_t userNum = 0;
    142 
    143     for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
    144         const Component &c = getElement()->getField(ct)->getComponent();
    145 
    146         switch(c.getKind()) {
    147         case RS_KIND_USER:
    148             mGL.mUser[userNum].size = c.getVectorSize();
    149             mGL.mUser[userNum].offset = mElement->getFieldOffsetBytes(ct);
    150             mGL.mUser[userNum].type = c.getGLType();
    151             mGL.mUser[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
    152             mGL.mUser[userNum].name.setTo(getElement()->getFieldName(ct));
    153             userNum ++;
    154             break;
    155 
    156         case RS_KIND_POSITION:
    157             rsAssert(mGL.mVtx.size == 0);
    158             mGL.mVtx.size = c.getVectorSize();
    159             mGL.mVtx.offset = mElement->getFieldOffsetBytes(ct);
    160             mGL.mVtx.type = c.getGLType();
    161             mGL.mVtx.normalized = false;
    162             mGL.mVtx.name.setTo("Position");
    163             break;
    164 
    165         case RS_KIND_COLOR:
    166             rsAssert(mGL.mColor.size == 0);
    167             mGL.mColor.size = c.getVectorSize();
    168             mGL.mColor.offset = mElement->getFieldOffsetBytes(ct);
    169             mGL.mColor.type = c.getGLType();
    170             mGL.mColor.normalized = c.getType() != RS_TYPE_FLOAT_32;
    171             mGL.mColor.name.setTo("Color");
    172             break;
    173 
    174         case RS_KIND_NORMAL:
    175             rsAssert(mGL.mNorm.size == 0);
    176             mGL.mNorm.size = c.getVectorSize();
    177             mGL.mNorm.offset = mElement->getFieldOffsetBytes(ct);
    178             mGL.mNorm.type = c.getGLType();
    179             mGL.mNorm.normalized = false;
    180             mGL.mNorm.name.setTo("Normal");
    181             break;
    182 
    183         case RS_KIND_TEXTURE:
    184             rsAssert(mGL.mTex.size == 0);
    185             mGL.mTex.size = c.getVectorSize();
    186             mGL.mTex.offset = mElement->getFieldOffsetBytes(ct);
    187             mGL.mTex.type = c.getGLType();
    188             mGL.mTex.normalized = false;
    189             mGL.mTex.name.setTo("Texture");
    190             break;
    191 
    192         case RS_KIND_POINT_SIZE:
    193             rsAssert(!mGL.mPointSize.size);
    194             mGL.mPointSize.size = c.getVectorSize();
    195             mGL.mPointSize.offset = mElement->getFieldOffsetBytes(ct);
    196             mGL.mPointSize.type = c.getGLType();
    197             mGL.mPointSize.normalized = false;
    198             mGL.mPointSize.name.setTo("PointSize");
    199         break;
    200 
    201         default:
    202             break;
    203         }
    204     }
    205 }
    206 
    207 void Type::enableGLVertexBuffer(VertexArray *va) const
    208 {
    209     // Note: We are only going to enable buffers and never disable them
    210     // here.  The reason is more than one Allocation may be used as a vertex
    211     // source.  So we cannot disable arrays that may have been in use by
    212     // another allocation.
    213 
    214     uint32_t stride = mElement->getSizeBytes();
    215     if (mGL.mVtx.size) {
    216         va->addLegacy(mGL.mVtx.type,
    217                       mGL.mVtx.size,
    218                       stride,
    219                       RS_KIND_POSITION,
    220                       false,
    221                       mGL.mVtx.offset);
    222     }
    223 
    224     if (mGL.mNorm.size) {
    225         va->addLegacy(mGL.mNorm.type,
    226                      3,
    227                      stride,
    228                      RS_KIND_NORMAL,
    229                      false,
    230                      mGL.mNorm.offset);
    231     }
    232 
    233     if (mGL.mColor.size) {
    234         va->addLegacy(mGL.mColor.type,
    235                      mGL.mColor.size,
    236                      stride,
    237                      RS_KIND_COLOR,
    238                      true,
    239                      mGL.mColor.offset);
    240     }
    241 
    242     if (mGL.mTex.size) {
    243         va->addLegacy(mGL.mTex.type,
    244                      mGL.mTex.size,
    245                      stride,
    246                      RS_KIND_TEXTURE,
    247                      false,
    248                      mGL.mTex.offset);
    249     }
    250 
    251     if (mGL.mPointSize.size) {
    252         va->addLegacy(mGL.mPointSize.type,
    253                      1,
    254                      stride,
    255                      RS_KIND_POINT_SIZE,
    256                      false,
    257                      mGL.mPointSize.offset);
    258     }
    259 
    260 }
    261 
    262 void Type::enableGLVertexBuffer2(VertexArray *va) const
    263 {
    264     // Do legacy buffers
    265     enableGLVertexBuffer(va);
    266 
    267     uint32_t stride = mElement->getSizeBytes();
    268     for (uint32_t ct=0; ct < RS_MAX_ATTRIBS; ct++) {
    269         if (mGL.mUser[ct].size) {
    270             va->addUser(mGL.mUser[ct], stride);
    271         }
    272     }
    273 }
    274 
    275 
    276 
    277 void Type::dumpLOGV(const char *prefix) const
    278 {
    279     char buf[1024];
    280     ObjectBase::dumpLOGV(prefix);
    281     LOGV("%s   Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
    282     sprintf(buf, "%s element: ", prefix);
    283     mElement->dumpLOGV(buf);
    284 }
    285 
    286 bool Type::getIsNp2() const
    287 {
    288     uint32_t x = getDimX();
    289     uint32_t y = getDimY();
    290     uint32_t z = getDimZ();
    291 
    292     if (x && (x & (x-1))) {
    293         return true;
    294     }
    295     if (y && (y & (y-1))) {
    296         return true;
    297     }
    298     if (z && (z & (z-1))) {
    299         return true;
    300     }
    301     return false;
    302 }
    303 
    304 
    305 //////////////////////////////////////////////////
    306 //
    307 namespace android {
    308 namespace renderscript {
    309 
    310 void rsi_TypeBegin(Context *rsc, RsElement vse)
    311 {
    312     TypeState * stc = &rsc->mStateType;
    313 
    314     stc->mX = 0;
    315     stc->mY = 0;
    316     stc->mZ = 0;
    317     stc->mLOD = false;
    318     stc->mFaces = false;
    319     stc->mElement.set(static_cast<const Element *>(vse));
    320 }
    321 
    322 void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value)
    323 {
    324     TypeState * stc = &rsc->mStateType;
    325 
    326     if (dim < 0) {
    327         //error
    328         return;
    329     }
    330 
    331 
    332     switch (dim) {
    333     case RS_DIMENSION_X:
    334         stc->mX = value;
    335         return;
    336     case RS_DIMENSION_Y:
    337         stc->mY = value;
    338         return;
    339     case RS_DIMENSION_Z:
    340         stc->mZ = value;
    341         return;
    342     case RS_DIMENSION_FACE:
    343         stc->mFaces = (value != 0);
    344         return;
    345     case RS_DIMENSION_LOD:
    346         stc->mLOD = (value != 0);
    347         return;
    348     default:
    349         break;
    350     }
    351 
    352 
    353     int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0;
    354     if ((dim < 0) || (dim > RS_DIMENSION_MAX)) {
    355         LOGE("rsTypeAdd: Bad dimension");
    356         //error
    357         return;
    358     }
    359 
    360     // todo: implement array support
    361 
    362 }
    363 
    364 RsType rsi_TypeCreate(Context *rsc)
    365 {
    366     TypeState * stc = &rsc->mStateType;
    367 
    368     for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
    369         Type *t = stc->mTypes[ct];
    370         if (t->getElement() != stc->mElement.get()) continue;
    371         if (t->getDimX() != stc->mX) continue;
    372         if (t->getDimY() != stc->mY) continue;
    373         if (t->getDimZ() != stc->mZ) continue;
    374         if (t->getDimLOD() != stc->mLOD) continue;
    375         if (t->getDimFaces() != stc->mFaces) continue;
    376         t->incUserRef();
    377         return t;
    378     }
    379 
    380     Type * st = new Type(rsc);
    381     st->incUserRef();
    382     st->setDimX(stc->mX);
    383     st->setDimY(stc->mY);
    384     st->setDimZ(stc->mZ);
    385     st->setElement(stc->mElement.get());
    386     st->setDimLOD(stc->mLOD);
    387     st->setDimFaces(stc->mFaces);
    388     st->compute();
    389     stc->mElement.clear();
    390     stc->mTypes.push(st);
    391     return st;
    392 }
    393 
    394 
    395 }
    396 }
    397 
    398