rsType.cpp revision e5ffb879ae535a899a486285a23bea05e912480f
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 20using namespace android; 21using namespace android::renderscript; 22 23Type::Type() 24{ 25 mLODs = 0; 26 mLODCount = 0; 27 memset(&mGL, 0, sizeof(mGL)); 28 clear(); 29} 30 31Type::~Type() 32{ 33 if (mLODs) { 34 delete [] mLODs; 35 } 36} 37 38void Type::clear() 39{ 40 if (mLODs) { 41 delete [] mLODs; 42 mLODs = NULL; 43 } 44 mDimX = 0; 45 mDimY = 0; 46 mDimZ = 0; 47 mDimLOD = 0; 48 mFaces = false; 49 mElement.clear(); 50} 51 52TypeState::TypeState() 53{ 54} 55 56TypeState::~TypeState() 57{ 58} 59 60size_t Type::getOffsetForFace(uint32_t face) const 61{ 62 rsAssert(mFaces); 63 return 0; 64} 65 66void Type::compute() 67{ 68 uint32_t oldLODCount = mLODCount; 69 if (mDimLOD) { 70 uint32_t l2x = rsFindHighBit(mDimX) + 1; 71 uint32_t l2y = rsFindHighBit(mDimY) + 1; 72 uint32_t l2z = rsFindHighBit(mDimZ) + 1; 73 74 mLODCount = rsMax(l2x, l2y); 75 mLODCount = rsMax(mLODCount, l2z); 76 } else { 77 mLODCount = 1; 78 } 79 if (mLODCount != oldLODCount) { 80 delete [] mLODs; 81 mLODs = new LOD[mLODCount]; 82 } 83 84 uint32_t tx = mDimX; 85 uint32_t ty = mDimY; 86 uint32_t tz = mDimZ; 87 size_t offset = 0; 88 for (uint32_t lod=0; lod < mLODCount; lod++) { 89 mLODs[lod].mX = tx; 90 mLODs[lod].mY = ty; 91 mLODs[lod].mZ = tz; 92 mLODs[lod].mOffset = offset; 93 offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes(); 94 tx = (tx + 1) >> 1; 95 ty = (ty + 1) >> 1; 96 tz = (tz + 1) >> 1; 97 } 98 99 // At this point the offset is the size of a mipmap chain; 100 mMipChainSizeBytes = offset; 101 102 if (mFaces) { 103 offset *= 6; 104 } 105 mTotalSizeBytes = offset; 106 107 makeGLComponents(); 108} 109 110uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const 111{ 112 uint32_t offset = mLODs[lod].mOffset; 113 offset += x * mElement->getSizeBytes(); 114 return offset; 115} 116 117uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const 118{ 119 uint32_t offset = mLODs[lod].mOffset; 120 offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes(); 121 return offset; 122} 123 124uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const 125{ 126 uint32_t offset = mLODs[lod].mOffset; 127 offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes(); 128 return offset; 129} 130 131 132void Type::makeGLComponents() 133{ 134 uint32_t texNum = 0; 135 memset(&mGL, 0, sizeof(mGL)); 136 137 for (uint32_t ct=0; ct < getElement()->getComponentCount(); ct++) { 138 const Component *c = getElement()->getComponent(ct); 139 140 switch(c->getKind()) { 141 case Component::X: 142 rsAssert(mGL.mVtx.size == 0); 143 mGL.mVtx.size = 1; 144 mGL.mVtx.offset = mElement->getComponentOffsetBytes(ct); 145 mGL.mVtx.type = c->getGLType(); 146 break; 147 case Component::Y: 148 rsAssert(mGL.mVtx.size == 1); 149 rsAssert(mGL.mVtx.type == c->getGLType()); 150 mGL.mVtx.size = 2; 151 break; 152 case Component::Z: 153 rsAssert(mGL.mVtx.size == 2); 154 rsAssert(mGL.mVtx.type == c->getGLType()); 155 mGL.mVtx.size = 3; 156 break; 157 case Component::W: 158 rsAssert(mGL.mVtx.size == 4); 159 rsAssert(mGL.mVtx.type == c->getGLType()); 160 mGL.mVtx.size = 4; 161 break; 162 163 case Component::RED: 164 rsAssert(mGL.mColor.size == 0); 165 mGL.mColor.size = 1; 166 mGL.mColor.offset = mElement->getComponentOffsetBytes(ct); 167 mGL.mColor.type = c->getGLType(); 168 break; 169 case Component::GREEN: 170 rsAssert(mGL.mColor.size == 1); 171 rsAssert(mGL.mColor.type == c->getGLType()); 172 mGL.mColor.size = 2; 173 break; 174 case Component::BLUE: 175 rsAssert(mGL.mColor.size == 2); 176 rsAssert(mGL.mColor.type == c->getGLType()); 177 mGL.mColor.size = 3; 178 break; 179 case Component::ALPHA: 180 rsAssert(mGL.mColor.size == 3); 181 rsAssert(mGL.mColor.type == c->getGLType()); 182 mGL.mColor.size = 4; 183 break; 184 185 case Component::NX: 186 rsAssert(mGL.mNorm.size == 0); 187 mGL.mNorm.size = 1; 188 mGL.mNorm.offset = mElement->getComponentOffsetBytes(ct); 189 mGL.mNorm.type = c->getGLType(); 190 break; 191 case Component::NY: 192 rsAssert(mGL.mNorm.size == 1); 193 rsAssert(mGL.mNorm.type == c->getGLType()); 194 mGL.mNorm.size = 2; 195 break; 196 case Component::NZ: 197 rsAssert(mGL.mNorm.size == 2); 198 rsAssert(mGL.mNorm.type == c->getGLType()); 199 mGL.mNorm.size = 3; 200 break; 201 202 case Component::S: 203 if (mGL.mTex[texNum].size) { 204 texNum++; 205 } 206 mGL.mTex[texNum].size = 1; 207 mGL.mTex[texNum].offset = mElement->getComponentOffsetBytes(ct); 208 mGL.mTex[texNum].type = c->getGLType(); 209 break; 210 case Component::T: 211 rsAssert(mGL.mTex[texNum].size == 1); 212 rsAssert(mGL.mTex[texNum].type == c->getGLType()); 213 mGL.mTex[texNum].size = 2; 214 break; 215 case Component::R: 216 rsAssert(mGL.mTex[texNum].size == 2); 217 rsAssert(mGL.mTex[texNum].type == c->getGLType()); 218 mGL.mTex[texNum].size = 3; 219 break; 220 case Component::Q: 221 rsAssert(mGL.mTex[texNum].size == 3); 222 rsAssert(mGL.mTex[texNum].type == c->getGLType()); 223 mGL.mTex[texNum].size = 4; 224 break; 225 226 default: 227 break; 228 } 229 } 230} 231 232void Type::enableGLVertexBuffer() const 233{ 234 // Note: We are only going to enable buffers and never disable them 235 // here. The reasonis more than one Allocation may be used as a vertex 236 // source. So we cannot disable arrays that may have been in use by 237 // another allocation. 238 239 uint32_t stride = mElement->getSizeBytes(); 240 if (mGL.mVtx.size) { 241 glEnableClientState(GL_VERTEX_ARRAY); 242 glVertexPointer(mGL.mVtx.size, 243 mGL.mVtx.type, 244 stride, 245 (void *)mGL.mVtx.offset); 246 } 247 248 if (mGL.mNorm.size) { 249 glEnableClientState(GL_NORMAL_ARRAY); 250 rsAssert(mGL.mNorm.size == 3); 251 glNormalPointer(mGL.mNorm.size, 252 stride, 253 (void *)mGL.mNorm.offset); 254 } 255 256 if (mGL.mColor.size) { 257 glEnableClientState(GL_COLOR_ARRAY); 258 glColorPointer(mGL.mColor.size, 259 mGL.mColor.type, 260 stride, 261 (void *)mGL.mColor.offset); 262 } 263 264 for (uint32_t ct=0; ct < RS_MAX_TEXTURE; ct++) { 265 if (mGL.mTex[ct].size) { 266 glClientActiveTexture(GL_TEXTURE0 + ct); 267 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 268 glTexCoordPointer(mGL.mTex[ct].size, 269 mGL.mTex[ct].type, 270 stride, 271 (void *)mGL.mTex[ct].offset); 272 } 273 } 274 glClientActiveTexture(GL_TEXTURE0); 275 276} 277 278 279////////////////////////////////////////////////// 280// 281namespace android { 282namespace renderscript { 283 284void rsi_TypeBegin(Context *rsc, RsElement vse) 285{ 286 TypeState * stc = &rsc->mStateType; 287 288 stc->mX = 0; 289 stc->mY = 0; 290 stc->mZ = 0; 291 stc->mLOD = false; 292 stc->mFaces = false; 293 stc->mElement.set(static_cast<const Element *>(vse)); 294} 295 296void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value) 297{ 298 TypeState * stc = &rsc->mStateType; 299 300 if (dim < 0) { 301 //error 302 return; 303 } 304 305 306 switch (dim) { 307 case RS_DIMENSION_X: 308 stc->mX = value; 309 return; 310 case RS_DIMENSION_Y: 311 stc->mY = value; 312 return; 313 case RS_DIMENSION_Z: 314 stc->mZ = value; 315 return; 316 case RS_DIMENSION_FACE: 317 stc->mFaces = (value != 0); 318 return; 319 case RS_DIMENSION_LOD: 320 stc->mLOD = (value != 0); 321 return; 322 default: 323 break; 324 } 325 326 327 int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0; 328 if ((dim < 0) || (dim > RS_DIMENSION_MAX)) { 329 LOGE("rsTypeAdd: Bad dimension"); 330 //error 331 return; 332 } 333 334 // todo: implement array support 335 336} 337 338RsType rsi_TypeCreate(Context *rsc) 339{ 340 TypeState * stc = &rsc->mStateType; 341 342 Type * st = new Type(); 343 st->incRef(); 344 st->setDimX(stc->mX); 345 st->setDimY(stc->mY); 346 st->setDimZ(stc->mZ); 347 st->setElement(stc->mElement.get()); 348 st->setDimLOD(stc->mLOD); 349 st->setDimFaces(stc->mFaces); 350 st->compute(); 351 352 return st; 353} 354 355void rsi_TypeDestroy(Context *rsc, RsType vst) 356{ 357 Type * st = static_cast<Type *>(vst); 358 st->decRef(); 359} 360 361} 362} 363 364