rsType.cpp revision 700ba38f022208686523ab4280c4fc9f102aa273
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/* 2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2009 The Android Open Source Project 3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License. 6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at 7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * http://www.apache.org/licenses/LICENSE-2.0 9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software 11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and 14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License. 15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */ 16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 17fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#ifndef ANDROID_RS_BUILD_FOR_HOST 18326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include "rsContext.h" 19e5ffb879ae535a899a486285a23bea05e912480fJason Sams#include <GLES/gl.h> 20fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#else 21fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include "rsContextHostStub.h" 22fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include <OpenGL/gl.h> 23fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#endif 24326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 25326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android; 26326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript; 27326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 28e514b45de8561fbc6ef6770845102ca10b0a69d7Jason SamsType::Type(Context *rsc) : ObjectBase(rsc) 29326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 30f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams mAllocFile = __FILE__; 31f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams mAllocLine = __LINE__; 32326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODs = 0; 33326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODCount = 0; 34700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk mAttribs = NULL; 35700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk mAttribsSize = 0; 36326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams clear(); 37326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 38326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 39326e0ddf89e8df2837752fbfd7a014814b32082cJason SamsType::~Type() 40326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 418154954868694e1f233d87d4933a474518b1cb81Jason Sams for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) { 428154954868694e1f233d87d4933a474518b1cb81Jason Sams if (mRSC->mStateType.mTypes[ct] == this) { 438154954868694e1f233d87d4933a474518b1cb81Jason Sams mRSC->mStateType.mTypes.removeAt(ct); 448154954868694e1f233d87d4933a474518b1cb81Jason Sams break; 458154954868694e1f233d87d4933a474518b1cb81Jason Sams } 468154954868694e1f233d87d4933a474518b1cb81Jason Sams } 47326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (mLODs) { 48326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams delete [] mLODs; 49700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk mLODs = NULL; 50700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk } 51700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk if(mAttribs) { 52700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk delete [] mAttribs; 53700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk mAttribs = NULL; 54326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 55326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 56326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 57326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsvoid Type::clear() 58326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 59326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (mLODs) { 60326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams delete [] mLODs; 61326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODs = NULL; 62326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 63326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mDimX = 0; 64326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mDimY = 0; 65326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mDimZ = 0; 66326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mDimLOD = 0; 67326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mFaces = false; 68326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mElement.clear(); 69326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 70326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 71326e0ddf89e8df2837752fbfd7a014814b32082cJason SamsTypeState::TypeState() 72326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 73326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 74326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 75326e0ddf89e8df2837752fbfd7a014814b32082cJason SamsTypeState::~TypeState() 76326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 77326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 78326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 79326e0ddf89e8df2837752fbfd7a014814b32082cJason Samssize_t Type::getOffsetForFace(uint32_t face) const 80326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 81326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams rsAssert(mFaces); 82326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return 0; 83326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 84326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 85326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsvoid Type::compute() 86326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 87326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t oldLODCount = mLODCount; 88326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (mDimLOD) { 89326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t l2x = rsFindHighBit(mDimX) + 1; 90326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t l2y = rsFindHighBit(mDimY) + 1; 91326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t l2z = rsFindHighBit(mDimZ) + 1; 92326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 93326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODCount = rsMax(l2x, l2y); 94326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODCount = rsMax(mLODCount, l2z); 95326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } else { 96326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODCount = 1; 97326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 98326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (mLODCount != oldLODCount) { 99d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mLODs){ 100d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk delete [] mLODs; 101417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk } 102326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODs = new LOD[mLODCount]; 103326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 104326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 105326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t tx = mDimX; 106326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t ty = mDimY; 107326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t tz = mDimZ; 108326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams size_t offset = 0; 109326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams for (uint32_t lod=0; lod < mLODCount; lod++) { 110326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODs[lod].mX = tx; 111326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODs[lod].mY = ty; 112326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODs[lod].mZ = tz; 113326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mLODs[lod].mOffset = offset; 114326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes(); 1157c52898ac201043a26b3edb7526d414684cfb96bJason Sams if (tx > 1) tx >>= 1; 1167c52898ac201043a26b3edb7526d414684cfb96bJason Sams if (ty > 1) ty >>= 1; 1177c52898ac201043a26b3edb7526d414684cfb96bJason Sams if (tz > 1) tz >>= 1; 118326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 119326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 120326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams // At this point the offset is the size of a mipmap chain; 121326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mMipChainSizeBytes = offset; 122326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 123326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (mFaces) { 124326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams offset *= 6; 125326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 126326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mTotalSizeBytes = offset; 127326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 128e5ffb879ae535a899a486285a23bea05e912480fJason Sams makeGLComponents(); 129326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 130326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 131326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsuint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const 132326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 133326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t offset = mLODs[lod].mOffset; 134326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams offset += x * mElement->getSizeBytes(); 135326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return offset; 136326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 137326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 138326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsuint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const 139326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 140326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t offset = mLODs[lod].mOffset; 141326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes(); 142326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return offset; 143326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 144326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 145326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsuint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const 146326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 147326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t offset = mLODs[lod].mOffset; 148326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes(); 149326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return offset; 150326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 151326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 152326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 153e5ffb879ae535a899a486285a23bea05e912480fJason Samsvoid Type::makeGLComponents() 154e5ffb879ae535a899a486285a23bea05e912480fJason Sams{ 155700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk // Count the number of gl attrs to initialize 156700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk mAttribsSize = 0; 157700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) { 158700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk if(getElement()->getFieldName(ct)[0] != '#') { 159700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk mAttribsSize ++; 160700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk } 161700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk } 162700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk if(mAttribs) { 163700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk delete [] mAttribs; 164700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk mAttribs = NULL; 165700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk } 166700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk if(mAttribsSize) { 167700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk mAttribs = new VertexArray::Attrib[mAttribsSize]; 168700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk } 169700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk 170433eca30b2efe0cf84bbda33f2dfdfd6dcafaf59Jason Sams uint32_t userNum = 0; 1714815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) { 172d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams const Component &c = getElement()->getField(ct)->getComponent(); 173e5ffb879ae535a899a486285a23bea05e912480fJason Sams 174886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk if(getElement()->getFieldName(ct)[0] == '#') { 175886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk continue; 176886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk } 177886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk 17879f52df541f87ac07709e770cd79f14dd1a05e93Jason Sams mAttribs[userNum].size = c.getVectorSize(); 17979f52df541f87ac07709e770cd79f14dd1a05e93Jason Sams mAttribs[userNum].offset = mElement->getFieldOffsetBytes(ct); 18079f52df541f87ac07709e770cd79f14dd1a05e93Jason Sams mAttribs[userNum].type = c.getGLType(); 18179f52df541f87ac07709e770cd79f14dd1a05e93Jason Sams mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized(); 182886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk String8 tmp(RS_SHADER_ATTR); 183886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk tmp.append(getElement()->getFieldName(ct)); 184886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk mAttribs[userNum].name.setTo(tmp.string()); 185886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk 186700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk userNum ++; 187e5ffb879ae535a899a486285a23bea05e912480fJason Sams } 188e5ffb879ae535a899a486285a23bea05e912480fJason Sams} 189e5ffb879ae535a899a486285a23bea05e912480fJason Sams 190e5ffb879ae535a899a486285a23bea05e912480fJason Sams 19179f52df541f87ac07709e770cd79f14dd1a05e93Jason Samsvoid Type::enableGLVertexBuffer(VertexArray *va) const 192433eca30b2efe0cf84bbda33f2dfdfd6dcafaf59Jason Sams{ 193433eca30b2efe0cf84bbda33f2dfdfd6dcafaf59Jason Sams uint32_t stride = mElement->getSizeBytes(); 194700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk for (uint32_t ct=0; ct < mAttribsSize; ct++) { 195700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk // Load up to RS_MAX_ATTRIBS inputs 196700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk // TODO: grow vertexarray dynamically 197700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk if(ct >= RS_MAX_ATTRIBS) { 198700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk LOGE("More GL attributes than we can handle"); 199700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk break; 200700ba38f022208686523ab4280c4fc9f102aa273Alex Sakhartchouk } 20179f52df541f87ac07709e770cd79f14dd1a05e93Jason Sams if (mAttribs[ct].size) { 20279f52df541f87ac07709e770cd79f14dd1a05e93Jason Sams va->add(mAttribs[ct], stride); 203433eca30b2efe0cf84bbda33f2dfdfd6dcafaf59Jason Sams } 204433eca30b2efe0cf84bbda33f2dfdfd6dcafaf59Jason Sams } 205433eca30b2efe0cf84bbda33f2dfdfd6dcafaf59Jason Sams} 206433eca30b2efe0cf84bbda33f2dfdfd6dcafaf59Jason Sams 207433eca30b2efe0cf84bbda33f2dfdfd6dcafaf59Jason Sams 208e5ffb879ae535a899a486285a23bea05e912480fJason Sams 209e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Samsvoid Type::dumpLOGV(const char *prefix) const 210e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams{ 211e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams char buf[1024]; 212e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams ObjectBase::dumpLOGV(prefix); 213e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams LOGV("%s Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces); 214e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams sprintf(buf, "%s element: ", prefix); 215e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams mElement->dumpLOGV(buf); 216e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams} 217e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams 218fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchoukvoid Type::serialize(OStream *stream) const 219fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk{ 220fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk // Need to identify ourselves 221fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk stream->addU32((uint32_t)getClassId()); 222fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 223fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk String8 name(getName()); 224fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk stream->addString(&name); 225fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 226fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk mElement->serialize(stream); 227fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 228fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk stream->addU32(mDimX); 229fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk stream->addU32(mDimY); 230fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk stream->addU32(mDimZ); 231fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 232fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk stream->addU8((uint8_t)(mDimLOD ? 1 : 0)); 233fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk stream->addU8((uint8_t)(mFaces ? 1 : 0)); 234fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk} 235fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 236fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex SakhartchoukType *Type::createFromStream(Context *rsc, IStream *stream) 237fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk{ 238fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk // First make sure we are reading the correct object 239b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk RsA3DClassID classID = (RsA3DClassID)stream->loadU32(); 240b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk if(classID != RS_A3D_CLASS_ID_TYPE) { 241fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk LOGE("type loading skipped due to invalid class id\n"); 242fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk return NULL; 243fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk } 244fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 245fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk String8 name; 246fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk stream->loadString(&name); 247fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 248fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk Element *elem = Element::createFromStream(rsc, stream); 249fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk if(!elem) { 250fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk return NULL; 251fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk } 252fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 253fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk Type *type = new Type(rsc); 254fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk type->mDimX = stream->loadU32(); 255fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk type->mDimY = stream->loadU32(); 256fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk type->mDimZ = stream->loadU32(); 257fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 258fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk uint8_t temp = stream->loadU8(); 259fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk type->mDimLOD = temp != 0; 260fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 261fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk temp = stream->loadU8(); 262fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk type->mFaces = temp != 0; 263fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 264fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk type->setElement(elem); 265fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 266fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk return type; 267fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk} 268fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk 269ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Samsbool Type::getIsNp2() const 270ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams{ 271ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams uint32_t x = getDimX(); 272ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams uint32_t y = getDimY(); 273ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams uint32_t z = getDimZ(); 274ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams 275ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams if (x && (x & (x-1))) { 276ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams return true; 277ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams } 278ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams if (y && (y & (y-1))) { 279ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams return true; 280ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams } 281ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams if (z && (z & (z-1))) { 282ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams return true; 283ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams } 284ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams return false; 285ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams} 286ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams 287383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchoukbool Type::isEqual(const Type *other) const { 288383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk if(other == NULL) { 289383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk return false; 290383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk } 291383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk if (other->getElement()->isEqual(getElement()) && 292383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk other->getDimX() == mDimX && 293383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk other->getDimY() == mDimY && 294383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk other->getDimZ() == mDimZ && 295383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk other->getDimLOD() == mDimLOD && 296383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk other->getDimFaces() == mFaces) { 297383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk return true; 298383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk } 299383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk return false; 300383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk} 301e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams 30296abf819e50b59ba8cf886c13f894633eb0a24baJason SamsType * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const 30396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams{ 30496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams TypeState * stc = &rsc->mStateType; 30596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) { 30696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams Type *t = stc->mTypes[ct]; 30796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getElement() != mElement.get()) continue; 30896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getDimX() != dimX) continue; 30996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getDimY() != mDimY) continue; 31096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getDimZ() != mDimZ) continue; 31196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getDimLOD() != mDimLOD) continue; 31296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getDimFaces() != mFaces) continue; 31396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams t->incUserRef(); 31496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams return t; 31596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams } 31696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams 31796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams Type *nt = new Type(rsc); 31896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mElement.set(mElement); 31996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mDimX = dimX; 32096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mDimY = mDimY; 32196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mDimZ = mDimZ; 32296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mDimLOD = mDimLOD; 32396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mFaces = mFaces; 32496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->compute(); 32596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams return nt; 32696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams} 32796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams 32896abf819e50b59ba8cf886c13f894633eb0a24baJason SamsType * Type::cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const 32996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams{ 33096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams TypeState * stc = &rsc->mStateType; 33196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) { 33296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams Type *t = stc->mTypes[ct]; 33396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getElement() != mElement.get()) continue; 33496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getDimX() != dimX) continue; 33596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getDimY() != dimY) continue; 33696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getDimZ() != mDimZ) continue; 33796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getDimLOD() != mDimLOD) continue; 33896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams if (t->getDimFaces() != mFaces) continue; 33996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams t->incUserRef(); 34096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams return t; 34196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams } 34296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams 34396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams Type *nt = new Type(rsc); 34496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mElement.set(mElement); 34596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mDimX = dimX; 34696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mDimY = dimY; 34796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mDimZ = mDimZ; 34896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mDimLOD = mDimLOD; 34996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->mFaces = mFaces; 35096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams nt->compute(); 35196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams return nt; 35296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams} 35396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams 35496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams 355326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams////////////////////////////////////////////////// 356e5ffb879ae535a899a486285a23bea05e912480fJason Sams// 357326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android { 358326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript { 359326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 360326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsvoid rsi_TypeBegin(Context *rsc, RsElement vse) 361326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 362326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams TypeState * stc = &rsc->mStateType; 363326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 364326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mX = 0; 365326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mY = 0; 366326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mZ = 0; 367326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mLOD = false; 368326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mFaces = false; 369326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mElement.set(static_cast<const Element *>(vse)); 370326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 371326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 372326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsvoid rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value) 373326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 374326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams TypeState * stc = &rsc->mStateType; 375326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 376326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (dim < 0) { 377326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams //error 378326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return; 379326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 380326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 381326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 382326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams switch (dim) { 383326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams case RS_DIMENSION_X: 384326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mX = value; 385326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return; 386326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams case RS_DIMENSION_Y: 387326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mY = value; 388326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return; 389326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams case RS_DIMENSION_Z: 390326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mZ = value; 391326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return; 392326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams case RS_DIMENSION_FACE: 393326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mFaces = (value != 0); 394326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return; 395326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams case RS_DIMENSION_LOD: 396326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams stc->mLOD = (value != 0); 397326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return; 398326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams default: 399326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams break; 400326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 401326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 402326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if ((dim < 0) || (dim > RS_DIMENSION_MAX)) { 403326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams LOGE("rsTypeAdd: Bad dimension"); 404326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams //error 405326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return; 406326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 407326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 408326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams // todo: implement array support 409326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 410326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 411326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 412326e0ddf89e8df2837752fbfd7a014814b32082cJason SamsRsType rsi_TypeCreate(Context *rsc) 413326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 414326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams TypeState * stc = &rsc->mStateType; 415326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 4168154954868694e1f233d87d4933a474518b1cb81Jason Sams for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) { 4178154954868694e1f233d87d4933a474518b1cb81Jason Sams Type *t = stc->mTypes[ct]; 4188154954868694e1f233d87d4933a474518b1cb81Jason Sams if (t->getElement() != stc->mElement.get()) continue; 4198154954868694e1f233d87d4933a474518b1cb81Jason Sams if (t->getDimX() != stc->mX) continue; 4208154954868694e1f233d87d4933a474518b1cb81Jason Sams if (t->getDimY() != stc->mY) continue; 4218154954868694e1f233d87d4933a474518b1cb81Jason Sams if (t->getDimZ() != stc->mZ) continue; 4228154954868694e1f233d87d4933a474518b1cb81Jason Sams if (t->getDimLOD() != stc->mLOD) continue; 4238154954868694e1f233d87d4933a474518b1cb81Jason Sams if (t->getDimFaces() != stc->mFaces) continue; 4248154954868694e1f233d87d4933a474518b1cb81Jason Sams t->incUserRef(); 4258154954868694e1f233d87d4933a474518b1cb81Jason Sams return t; 4268154954868694e1f233d87d4933a474518b1cb81Jason Sams } 4278154954868694e1f233d87d4933a474518b1cb81Jason Sams 428e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams Type * st = new Type(rsc); 4299397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams st->incUserRef(); 430326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams st->setDimX(stc->mX); 431326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams st->setDimY(stc->mY); 432326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams st->setDimZ(stc->mZ); 433326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams st->setElement(stc->mElement.get()); 434326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams st->setDimLOD(stc->mLOD); 435326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams st->setDimFaces(stc->mFaces); 436326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams st->compute(); 4378312801ccbed0c86cb2592f7ca2fd1cb9847ab8dJason Sams stc->mElement.clear(); 4388154954868694e1f233d87d4933a474518b1cb81Jason Sams stc->mTypes.push(st); 439326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return st; 440326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 441326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 442417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchoukvoid rsi_TypeGetNativeData(Context *rsc, RsType type, uint32_t *typeData, uint32_t typeDataSize) 443417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk{ 444417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk rsAssert(typeDataSize == 6); 445417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk // Pack the data in the follofing way mDimX; mDimY; mDimZ; 446417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk // mDimLOD; mDimFaces; mElement; into typeData 447417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk Type *t = static_cast<Type *>(type); 448417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk 449417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk (*typeData++) = t->getDimX(); 450417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk (*typeData++) = t->getDimY(); 451417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk (*typeData++) = t->getDimZ(); 452417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk (*typeData++) = t->getDimLOD(); 453417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk (*typeData++) = t->getDimFaces() ? 1 : 0; 454417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk (*typeData++) = (uint32_t)t->getElement(); 455417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk 456417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk} 457417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk 458326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 459326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 460326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 461326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 462