rsType.cpp revision 2d7d0b276ed4b3cedf72342a4d2ab287d4653ce0
1/* 2 * Copyright (C) 2013 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#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) 20#include "system/graphics.h" 21#endif 22 23#ifdef RS_COMPATIBILITY_LIB 24#include "rsCompatibilityLib.h" 25#endif 26 27using namespace android; 28using namespace android::renderscript; 29 30Type::Type(Context *rsc) : ObjectBase(rsc) { 31 memset(&mHal, 0, sizeof(mHal)); 32 mDimLOD = false; 33} 34 35void Type::preDestroy() const { 36 for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) { 37 if (mRSC->mStateType.mTypes[ct] == this) { 38 mRSC->mStateType.mTypes.removeAt(ct); 39 break; 40 } 41 } 42} 43 44Type::~Type() { 45 clear(); 46} 47 48void Type::clear() { 49 if (mHal.state.lodCount) { 50 delete [] mHal.state.lodDimX; 51 delete [] mHal.state.lodDimY; 52 delete [] mHal.state.lodDimZ; 53 delete [] mHal.state.lodOffset; 54 } 55 mElement.clear(); 56 memset(&mHal, 0, sizeof(mHal)); 57} 58 59TypeState::TypeState() { 60} 61 62TypeState::~TypeState() { 63 rsAssert(!mTypes.size()); 64} 65 66size_t Type::getOffsetForFace(uint32_t face) const { 67 rsAssert(mHal.state.faces); 68 return 0; 69} 70 71void Type::compute() { 72 uint32_t oldLODCount = mHal.state.lodCount; 73 if (mDimLOD) { 74 uint32_t l2x = rsFindHighBit(mHal.state.dimX) + 1; 75 uint32_t l2y = rsFindHighBit(mHal.state.dimY) + 1; 76 uint32_t l2z = rsFindHighBit(mHal.state.dimZ) + 1; 77 78 mHal.state.lodCount = rsMax(l2x, l2y); 79 mHal.state.lodCount = rsMax(mHal.state.lodCount, l2z); 80 } else { 81 mHal.state.lodCount = 1; 82 } 83 if (mHal.state.lodCount != oldLODCount) { 84 if (oldLODCount) { 85 delete [] mHal.state.lodDimX; 86 delete [] mHal.state.lodDimY; 87 delete [] mHal.state.lodDimZ; 88 delete [] mHal.state.lodOffset; 89 } 90 mHal.state.lodDimX = new uint32_t[mHal.state.lodCount]; 91 mHal.state.lodDimY = new uint32_t[mHal.state.lodCount]; 92 mHal.state.lodDimZ = new uint32_t[mHal.state.lodCount]; 93 mHal.state.lodOffset = new uint32_t[mHal.state.lodCount]; 94 } 95 96 uint32_t tx = mHal.state.dimX; 97 uint32_t ty = mHal.state.dimY; 98 uint32_t tz = mHal.state.dimZ; 99 size_t offset = 0; 100 for (uint32_t lod=0; lod < mHal.state.lodCount; lod++) { 101 mHal.state.lodDimX[lod] = tx; 102 mHal.state.lodDimY[lod] = ty; 103 mHal.state.lodDimZ[lod] = tz; 104 mHal.state.lodOffset[lod] = offset; 105 offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes(); 106 if (tx > 1) tx >>= 1; 107 if (ty > 1) ty >>= 1; 108 if (tz > 1) tz >>= 1; 109 } 110 111 // At this point the offset is the size of a mipmap chain; 112 mMipChainSizeBytes = offset; 113 114 if (mHal.state.faces) { 115 offset *= 6; 116 } 117#ifndef RS_SERVER 118 // YUV only supports basic 2d 119 // so we can stash the plane pointers in the mipmap levels. 120 if (mHal.state.dimYuv) { 121 switch(mHal.state.dimYuv) { 122 case HAL_PIXEL_FORMAT_YV12: 123 mHal.state.lodOffset[1] = offset; 124 mHal.state.lodDimX[1] = mHal.state.lodDimX[0] / 2; 125 mHal.state.lodDimY[1] = mHal.state.lodDimY[0] / 2; 126 offset += offset / 4; 127 mHal.state.lodOffset[2] = offset; 128 mHal.state.lodDimX[2] = mHal.state.lodDimX[0] / 2; 129 mHal.state.lodDimY[2] = mHal.state.lodDimY[0] / 2; 130 offset += offset / 4; 131 break; 132 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21 133 mHal.state.lodOffset[1] = offset; 134 mHal.state.lodDimX[1] = mHal.state.lodDimX[0]; 135 mHal.state.lodDimY[1] = mHal.state.lodDimY[0] / 2; 136 offset += offset / 2; 137 break; 138 default: 139 rsAssert(0); 140 } 141 } 142#endif 143 mTotalSizeBytes = offset; 144 mHal.state.element = mElement.get(); 145} 146 147uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const { 148 uint32_t offset = mHal.state.lodOffset[lod]; 149 offset += x * mElement->getSizeBytes(); 150 return offset; 151} 152 153uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const { 154 uint32_t offset = mHal.state.lodOffset[lod]; 155 offset += (x + y * mHal.state.lodDimX[lod]) * mElement->getSizeBytes(); 156 return offset; 157} 158 159uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const { 160 uint32_t offset = mHal.state.lodOffset[lod]; 161 offset += (x + 162 y * mHal.state.lodDimX[lod] + 163 z * mHal.state.lodDimX[lod] * mHal.state.lodDimY[lod]) * mElement->getSizeBytes(); 164 return offset; 165} 166 167uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, 168 uint32_t x, uint32_t y) const { 169 uint32_t offset = mHal.state.lodOffset[lod]; 170 offset += (x + y * mHal.state.lodDimX[lod]) * mElement->getSizeBytes(); 171 172 if (face != 0) { 173 uint32_t faceOffset = getSizeBytes() / 6; 174 offset += faceOffset * face; 175 } 176 return offset; 177} 178 179void Type::dumpLOGV(const char *prefix) const { 180 char buf[1024]; 181 ObjectBase::dumpLOGV(prefix); 182 ALOGV("%s Type: x=%u y=%u z=%u mip=%i face=%i", prefix, 183 mHal.state.dimX, 184 mHal.state.dimY, 185 mHal.state.dimZ, 186 mHal.state.lodCount, 187 mHal.state.faces); 188 snprintf(buf, sizeof(buf), "%s element: ", prefix); 189 mElement->dumpLOGV(buf); 190} 191 192void Type::serialize(Context *rsc, OStream *stream) const { 193 // Need to identify ourselves 194 stream->addU32((uint32_t)getClassId()); 195 stream->addString(getName()); 196 197 mElement->serialize(rsc, stream); 198 199 stream->addU32(mHal.state.dimX); 200 stream->addU32(mHal.state.dimY); 201 stream->addU32(mHal.state.dimZ); 202 203 stream->addU8((uint8_t)(mHal.state.lodCount ? 1 : 0)); 204 stream->addU8((uint8_t)(mHal.state.faces ? 1 : 0)); 205} 206 207Type *Type::createFromStream(Context *rsc, IStream *stream) { 208 // First make sure we are reading the correct object 209 RsA3DClassID classID = (RsA3DClassID)stream->loadU32(); 210 if (classID != RS_A3D_CLASS_ID_TYPE) { 211 ALOGE("type loading skipped due to invalid class id\n"); 212 return NULL; 213 } 214 215 const char *name = stream->loadString(); 216 217 Element *elem = Element::createFromStream(rsc, stream); 218 if (!elem) { 219 return NULL; 220 } 221 222 uint32_t x = stream->loadU32(); 223 uint32_t y = stream->loadU32(); 224 uint32_t z = stream->loadU32(); 225 uint8_t lod = stream->loadU8(); 226 uint8_t faces = stream->loadU8(); 227 Type *type = Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0, 0); 228 elem->decUserRef(); 229 230 delete [] name; 231 return type; 232} 233 234bool Type::getIsNp2() const { 235 uint32_t x = getDimX(); 236 uint32_t y = getDimY(); 237 uint32_t z = getDimZ(); 238 239 if (x && (x & (x-1))) { 240 return true; 241 } 242 if (y && (y & (y-1))) { 243 return true; 244 } 245 if (z && (z & (z-1))) { 246 return true; 247 } 248 return false; 249} 250 251ObjectBaseRef<Type> Type::getTypeRef(Context *rsc, const Element *e, 252 uint32_t dimX, uint32_t dimY, uint32_t dimZ, 253 bool dimLOD, bool dimFaces, uint32_t dimYuv) { 254 ObjectBaseRef<Type> returnRef; 255 256 TypeState * stc = &rsc->mStateType; 257 258 ObjectBase::asyncLock(); 259 for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) { 260 Type *t = stc->mTypes[ct]; 261 if (t->getElement() != e) continue; 262 if (t->getDimX() != dimX) continue; 263 if (t->getDimY() != dimY) continue; 264 if (t->getDimZ() != dimZ) continue; 265 if (t->getDimLOD() != dimLOD) continue; 266 if (t->getDimFaces() != dimFaces) continue; 267 if (t->getDimYuv() != dimYuv) continue; 268 returnRef.set(t); 269 ObjectBase::asyncUnlock(); 270 return returnRef; 271 } 272 ObjectBase::asyncUnlock(); 273 274 275 Type *nt = new Type(rsc); 276 nt->mDimLOD = dimLOD; 277 returnRef.set(nt); 278 nt->mElement.set(e); 279 nt->mHal.state.dimX = dimX; 280 nt->mHal.state.dimY = dimY; 281 nt->mHal.state.dimZ = dimZ; 282 nt->mHal.state.faces = dimFaces; 283 nt->mHal.state.dimYuv = dimYuv; 284 nt->compute(); 285 286 ObjectBase::asyncLock(); 287 stc->mTypes.push(nt); 288 ObjectBase::asyncUnlock(); 289 290 return returnRef; 291} 292 293ObjectBaseRef<Type> Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const { 294 return getTypeRef(rsc, mElement.get(), dimX, 295 getDimY(), getDimZ(), getDimLOD(), getDimFaces(), getDimYuv()); 296} 297 298ObjectBaseRef<Type> Type::cloneAndResize2D(Context *rsc, 299 uint32_t dimX, 300 uint32_t dimY) const { 301 return getTypeRef(rsc, mElement.get(), dimX, dimY, 302 getDimZ(), getDimLOD(), getDimFaces(), getDimYuv()); 303} 304 305 306void Type::incRefs(const void *ptr, size_t ct, size_t startOff) const { 307 const uint8_t *p = static_cast<const uint8_t *>(ptr); 308 const Element *e = mHal.state.element; 309 uint32_t stride = e->getSizeBytes(); 310 311 p += stride * startOff; 312 while (ct > 0) { 313 e->incRefs(p); 314 ct--; 315 p += stride; 316 } 317} 318 319 320void Type::decRefs(const void *ptr, size_t ct, size_t startOff) const { 321 if (!mHal.state.element->getHasReferences()) { 322 return; 323 } 324 const uint8_t *p = static_cast<const uint8_t *>(ptr); 325 const Element *e = mHal.state.element; 326 uint32_t stride = e->getSizeBytes(); 327 328 p += stride * startOff; 329 while (ct > 0) { 330 e->decRefs(p); 331 ct--; 332 p += stride; 333 } 334} 335 336 337////////////////////////////////////////////////// 338// 339namespace android { 340namespace renderscript { 341 342RsType rsi_TypeCreate(Context *rsc, RsElement _e, uint32_t dimX, 343 uint32_t dimY, uint32_t dimZ, bool mips, bool faces, uint32_t yuv) { 344 Element *e = static_cast<Element *>(_e); 345 346 return Type::getType(rsc, e, dimX, dimY, dimZ, mips, faces, yuv); 347} 348 349} 350} 351 352extern "C" void rsaTypeGetNativeData(RsContext con, RsType type, uintptr_t *typeData, uint32_t typeDataSize) { 353 rsAssert(typeDataSize == 6); 354 // Pack the data in the follofing way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ; 355 // mHal.state.lodCount; mHal.state.faces; mElement; into typeData 356 Type *t = static_cast<Type *>(type); 357 358 (*typeData++) = t->getDimX(); 359 (*typeData++) = t->getDimY(); 360 (*typeData++) = t->getDimZ(); 361 (*typeData++) = t->getDimLOD() ? 1 : 0; 362 (*typeData++) = t->getDimFaces() ? 1 : 0; 363 (*typeData++) = (uintptr_t)t->getElement(); 364 t->getElement()->incUserRef(); 365} 366