rsType.cpp revision b99ed44dcffcc268958e86a7bdba2c683d729cf6
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 19using namespace android; 20using namespace android::renderscript; 21 22Type::Type(Context *rsc) : ObjectBase(rsc) { 23 memset(&mHal, 0, sizeof(mHal)); 24 mDimLOD = false; 25} 26 27void Type::preDestroy() const { 28 for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) { 29 if (mRSC->mStateType.mTypes[ct] == this) { 30 mRSC->mStateType.mTypes.removeAt(ct); 31 break; 32 } 33 } 34} 35 36Type::~Type() { 37 clear(); 38} 39 40void Type::clear() { 41 if (mHal.state.lodCount) { 42 delete [] mHal.state.lodDimX; 43 delete [] mHal.state.lodDimY; 44 delete [] mHal.state.lodDimZ; 45 } 46 mElement.clear(); 47 memset(&mHal, 0, sizeof(mHal)); 48} 49 50TypeState::TypeState() { 51} 52 53TypeState::~TypeState() { 54 rsAssert(!mTypes.size()); 55} 56 57void Type::compute() { 58 uint32_t oldLODCount = mHal.state.lodCount; 59 if (mDimLOD) { 60 uint32_t l2x = rsFindHighBit(mHal.state.dimX) + 1; 61 uint32_t l2y = rsFindHighBit(mHal.state.dimY) + 1; 62 uint32_t l2z = rsFindHighBit(mHal.state.dimZ) + 1; 63 64 mHal.state.lodCount = rsMax(l2x, l2y); 65 mHal.state.lodCount = rsMax(mHal.state.lodCount, l2z); 66 } else { 67 mHal.state.lodCount = 1; 68 } 69 if (mHal.state.lodCount != oldLODCount) { 70 if (oldLODCount) { 71 delete [] mHal.state.lodDimX; 72 delete [] mHal.state.lodDimY; 73 delete [] mHal.state.lodDimZ; 74 } 75 mHal.state.lodDimX = new uint32_t[mHal.state.lodCount]; 76 mHal.state.lodDimY = new uint32_t[mHal.state.lodCount]; 77 mHal.state.lodDimZ = new uint32_t[mHal.state.lodCount]; 78 } 79 80 uint32_t tx = mHal.state.dimX; 81 uint32_t ty = mHal.state.dimY; 82 uint32_t tz = mHal.state.dimZ; 83 size_t packedSize = 0; 84 for (uint32_t lod=0; lod < mHal.state.lodCount; lod++) { 85 mHal.state.lodDimX[lod] = tx; 86 mHal.state.lodDimY[lod] = ty; 87 mHal.state.lodDimZ[lod] = tz; 88 packedSize += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes(); 89 if (tx > 1) tx >>= 1; 90 if (ty > 1) ty >>= 1; 91 if (tz > 1) tz >>= 1; 92 } 93 94 // At this point the offset is the size of a mipmap chain; 95 mMipChainSizeBytes = packedSize; 96 97 if (mHal.state.faces) { 98 packedSize *= 6; 99 } 100 mTotalSizeBytes = packedSize; 101 mHal.state.element = mElement.get(); 102} 103 104void Type::dumpLOGV(const char *prefix) const { 105 char buf[1024]; 106 ObjectBase::dumpLOGV(prefix); 107 ALOGV("%s Type: x=%u y=%u z=%u mip=%i face=%i", prefix, 108 mHal.state.dimX, 109 mHal.state.dimY, 110 mHal.state.dimZ, 111 mHal.state.lodCount, 112 mHal.state.faces); 113 snprintf(buf, sizeof(buf), "%s element: ", prefix); 114 mElement->dumpLOGV(buf); 115} 116 117void Type::serialize(Context *rsc, OStream *stream) const { 118 // Need to identify ourselves 119 stream->addU32((uint32_t)getClassId()); 120 121 String8 name(getName()); 122 stream->addString(&name); 123 124 mElement->serialize(rsc, stream); 125 126 stream->addU32(mHal.state.dimX); 127 stream->addU32(mHal.state.dimY); 128 stream->addU32(mHal.state.dimZ); 129 130 stream->addU8((uint8_t)(mHal.state.lodCount ? 1 : 0)); 131 stream->addU8((uint8_t)(mHal.state.faces ? 1 : 0)); 132} 133 134Type *Type::createFromStream(Context *rsc, IStream *stream) { 135 // First make sure we are reading the correct object 136 RsA3DClassID classID = (RsA3DClassID)stream->loadU32(); 137 if (classID != RS_A3D_CLASS_ID_TYPE) { 138 ALOGE("type loading skipped due to invalid class id\n"); 139 return NULL; 140 } 141 142 String8 name; 143 stream->loadString(&name); 144 145 Element *elem = Element::createFromStream(rsc, stream); 146 if (!elem) { 147 return NULL; 148 } 149 150 uint32_t x = stream->loadU32(); 151 uint32_t y = stream->loadU32(); 152 uint32_t z = stream->loadU32(); 153 uint8_t lod = stream->loadU8(); 154 uint8_t faces = stream->loadU8(); 155 Type *type = Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 ); 156 elem->decUserRef(); 157 return type; 158} 159 160bool Type::getIsNp2() const { 161 uint32_t x = getDimX(); 162 uint32_t y = getDimY(); 163 uint32_t z = getDimZ(); 164 165 if (x && (x & (x-1))) { 166 return true; 167 } 168 if (y && (y & (y-1))) { 169 return true; 170 } 171 if (z && (z & (z-1))) { 172 return true; 173 } 174 return false; 175} 176 177ObjectBaseRef<Type> Type::getTypeRef(Context *rsc, const Element *e, 178 uint32_t dimX, uint32_t dimY, uint32_t dimZ, 179 bool dimLOD, bool dimFaces) { 180 ObjectBaseRef<Type> returnRef; 181 182 TypeState * stc = &rsc->mStateType; 183 184 ObjectBase::asyncLock(); 185 for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) { 186 Type *t = stc->mTypes[ct]; 187 if (t->getElement() != e) continue; 188 if (t->getDimX() != dimX) continue; 189 if (t->getDimY() != dimY) continue; 190 if (t->getDimZ() != dimZ) continue; 191 if (t->getDimLOD() != dimLOD) continue; 192 if (t->getDimFaces() != dimFaces) continue; 193 returnRef.set(t); 194 ObjectBase::asyncUnlock(); 195 return returnRef; 196 } 197 ObjectBase::asyncUnlock(); 198 199 200 Type *nt = new Type(rsc); 201 nt->mDimLOD = dimLOD; 202 returnRef.set(nt); 203 nt->mElement.set(e); 204 nt->mHal.state.dimX = dimX; 205 nt->mHal.state.dimY = dimY; 206 nt->mHal.state.dimZ = dimZ; 207 nt->mHal.state.faces = dimFaces; 208 nt->compute(); 209 210 ObjectBase::asyncLock(); 211 stc->mTypes.push(nt); 212 ObjectBase::asyncUnlock(); 213 214 return returnRef; 215} 216 217ObjectBaseRef<Type> Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const { 218 return getTypeRef(rsc, mElement.get(), dimX, 219 getDimY(), getDimZ(), getDimLOD(), getDimFaces()); 220} 221 222ObjectBaseRef<Type> Type::cloneAndResize2D(Context *rsc, 223 uint32_t dimX, 224 uint32_t dimY) const { 225 return getTypeRef(rsc, mElement.get(), dimX, dimY, 226 getDimZ(), getDimLOD(), getDimFaces()); 227} 228 229 230void Type::incRefs(const void *ptr, size_t ct, size_t startOff) const { 231 const uint8_t *p = static_cast<const uint8_t *>(ptr); 232 const Element *e = mHal.state.element; 233 uint32_t stride = e->getSizeBytes(); 234 235 p += stride * startOff; 236 while (ct > 0) { 237 e->incRefs(p); 238 ct--; 239 p += stride; 240 } 241} 242 243 244void Type::decRefs(const void *ptr, size_t ct, size_t startOff) const { 245 if (!mHal.state.element->getHasReferences()) { 246 return; 247 } 248 const uint8_t *p = static_cast<const uint8_t *>(ptr); 249 const Element *e = mHal.state.element; 250 uint32_t stride = e->getSizeBytes(); 251 252 p += stride * startOff; 253 while (ct > 0) { 254 e->decRefs(p); 255 ct--; 256 p += stride; 257 } 258} 259 260 261////////////////////////////////////////////////// 262// 263namespace android { 264namespace renderscript { 265 266RsType rsi_TypeCreate(Context *rsc, RsElement _e, uint32_t dimX, 267 uint32_t dimY, uint32_t dimZ, bool mips, bool faces) { 268 Element *e = static_cast<Element *>(_e); 269 270 return Type::getType(rsc, e, dimX, dimY, dimZ, mips, faces); 271} 272 273} 274} 275 276void rsaTypeGetNativeData(RsContext con, RsType type, uint32_t *typeData, uint32_t typeDataSize) { 277 rsAssert(typeDataSize == 6); 278 // Pack the data in the follofing way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ; 279 // mHal.state.lodCount; mHal.state.faces; mElement; into typeData 280 Type *t = static_cast<Type *>(type); 281 282 (*typeData++) = t->getDimX(); 283 (*typeData++) = t->getDimY(); 284 (*typeData++) = t->getDimZ(); 285 (*typeData++) = t->getDimLOD() ? 1 : 0; 286 (*typeData++) = t->getDimFaces() ? 1 : 0; 287 (*typeData++) = (uint32_t)t->getElement(); 288 t->getElement()->incUserRef(); 289} 290