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