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