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 19 #include <GLES/gl.h> 20 21 using namespace android; 22 using namespace android::renderscript; 23 24 25 Element::Element(Context *rsc) : ObjectBase(rsc) 26 { 27 mBits = 0; 28 mAllocFile = __FILE__; 29 mAllocLine = __LINE__; 30 mFields = NULL; 31 mFieldCount = 0; 32 } 33 34 35 Element::~Element() 36 { 37 for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) { 38 if (mRSC->mStateElement.mElements[ct] == this) { 39 mRSC->mStateElement.mElements.removeAt(ct); 40 break; 41 } 42 } 43 clear(); 44 } 45 46 void Element::clear() 47 { 48 delete [] mFields; 49 mFields = NULL; 50 mFieldCount = 0; 51 } 52 53 size_t Element::getSizeBits() const 54 { 55 if (!mFieldCount) { 56 return mBits; 57 } 58 59 size_t total = 0; 60 for (size_t ct=0; ct < mFieldCount; ct++) { 61 total += mFields[ct].e->mBits; 62 } 63 return total; 64 } 65 66 size_t Element::getFieldOffsetBits(uint32_t componentNumber) const 67 { 68 size_t offset = 0; 69 for (uint32_t ct = 0; ct < componentNumber; ct++) { 70 offset += mFields[ct].e->mBits; 71 } 72 return offset; 73 } 74 75 void Element::dumpLOGV(const char *prefix) const 76 { 77 ObjectBase::dumpLOGV(prefix); 78 LOGV("%s Element: components %i, size %i", prefix, mFieldCount, mBits); 79 for (uint32_t ct = 0; ct < mFieldCount; ct++) { 80 char buf[1024]; 81 sprintf(buf, "%s component %i: ", prefix, ct); 82 //mComponents[ct]->dumpLOGV(buf); 83 } 84 } 85 86 87 const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk, 88 bool isNorm, uint32_t vecSize) 89 { 90 // Look for an existing match. 91 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) { 92 const Element *ee = rsc->mStateElement.mElements[ct]; 93 if (!ee->getFieldCount() && 94 (ee->getComponent().getType() == dt) && 95 (ee->getComponent().getKind() == dk) && 96 (ee->getComponent().getIsNormalized() == isNorm) && 97 (ee->getComponent().getVectorSize() == vecSize)) { 98 // Match 99 ee->incUserRef(); 100 return ee; 101 } 102 } 103 104 Element *e = new Element(rsc); 105 e->mComponent.set(dt, dk, isNorm, vecSize); 106 e->mBits = e->mComponent.getBits(); 107 rsc->mStateElement.mElements.push(e); 108 return e; 109 } 110 111 const Element * Element::create(Context *rsc, size_t count, const Element **ein, 112 const char **nin, const size_t * lengths) 113 { 114 // Look for an existing match. 115 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) { 116 const Element *ee = rsc->mStateElement.mElements[ct]; 117 if (ee->getFieldCount() == count) { 118 bool match = true; 119 for (uint32_t i=0; i < count; i++) { 120 if ((ee->mFields[i].e.get() != ein[i]) || 121 (ee->mFields[i].name.length() != lengths[i]) || 122 (ee->mFields[i].name != nin[i])) { 123 match = false; 124 break; 125 } 126 } 127 if (match) { 128 ee->incUserRef(); 129 return ee; 130 } 131 } 132 } 133 134 Element *e = new Element(rsc); 135 e->mFields = new ElementField_t [count]; 136 e->mFieldCount = count; 137 for (size_t ct=0; ct < count; ct++) { 138 e->mFields[ct].e.set(ein[ct]); 139 e->mFields[ct].name.setTo(nin[ct], lengths[ct]); 140 } 141 142 rsc->mStateElement.mElements.push(e); 143 return e; 144 } 145 146 String8 Element::getCStructBody(uint32_t indent) const 147 { 148 String8 si; 149 for (uint32_t ct=0; ct < indent; ct++) { 150 si.append(" "); 151 } 152 153 String8 s(si); 154 s.append("{\n"); 155 for (uint32_t ct = 0; ct < mFieldCount; ct++) { 156 s.append(si); 157 s.append(mFields[ct].e->getCType(indent+4)); 158 s.append(" "); 159 s.append(mFields[ct].name); 160 s.append(";\n"); 161 } 162 s.append(si); 163 s.append("}"); 164 return s; 165 } 166 167 String8 Element::getCType(uint32_t indent) const 168 { 169 String8 s; 170 for (uint32_t ct=0; ct < indent; ct++) { 171 s.append(" "); 172 } 173 174 if (!mFieldCount) { 175 // Basic component. 176 s.append(mComponent.getCType()); 177 } else { 178 s.append("struct "); 179 s.append(getCStructBody(indent)); 180 } 181 182 return s; 183 } 184 185 String8 Element::getGLSLType(uint32_t indent) const 186 { 187 String8 s; 188 for (uint32_t ct=0; ct < indent; ct++) { 189 s.append(" "); 190 } 191 192 if (!mFieldCount) { 193 // Basic component. 194 s.append(mComponent.getGLSLType()); 195 } else { 196 rsAssert(0); 197 //s.append("struct "); 198 //s.append(getCStructBody(indent)); 199 } 200 201 return s; 202 } 203 204 205 206 ElementState::ElementState() 207 { 208 } 209 210 ElementState::~ElementState() 211 { 212 rsAssert(!mElements.size()); 213 } 214 215 216 ///////////////////////////////////////// 217 // 218 219 namespace android { 220 namespace renderscript { 221 222 RsElement rsi_ElementCreate(Context *rsc, 223 RsDataType dt, 224 RsDataKind dk, 225 bool norm, 226 uint32_t vecSize) 227 { 228 //LOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize); 229 const Element *e = Element::create(rsc, dt, dk, norm, vecSize); 230 e->incUserRef(); 231 return (RsElement)e; 232 } 233 234 RsElement rsi_ElementCreate2(Context *rsc, 235 size_t count, 236 const RsElement * ein, 237 const char ** names, 238 const size_t * nameLengths) 239 { 240 //LOGE("rsi_ElementCreate2 %i", count); 241 const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths); 242 e->incUserRef(); 243 return (RsElement)e; 244 } 245 246 247 } 248 } 249