blob: 35184c18c417b13fdd93c2770c0d67660de793a4 [file] [log] [blame]
Jason Samsa89371c2009-06-30 14:13:04 -07001/*
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -07002 * Copyright (C) 2011 The Android Open Source Project
Jason Samsa89371c2009-06-30 14:13:04 -07003 *
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"
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070018
Jason Samsa89371c2009-06-30 14:13:04 -070019using namespace android;
20using namespace android::renderscript;
21
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080022Mesh::Mesh(Context *rsc) : ObjectBase(rsc) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070023 mHal.drv = NULL;
24 mHal.state.primitives = NULL;
25 mHal.state.primitivesCount = 0;
26 mHal.state.vertexBuffers = NULL;
27 mHal.state.vertexBuffersCount = 0;
28 mInitialized = false;
29}
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080030
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070031Mesh::Mesh(Context *rsc,
32 uint32_t vertexBuffersCount,
33 uint32_t primitivesCount) : ObjectBase(rsc) {
34 mHal.drv = NULL;
35 mHal.state.primitivesCount = primitivesCount;
36 mHal.state.primitives = new Primitive_t *[mHal.state.primitivesCount];
37 for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
38 mHal.state.primitives[i] = new Primitive_t;
39 }
40 mHal.state.vertexBuffersCount = vertexBuffersCount;
41 mHal.state.vertexBuffers = new ObjectBaseRef<Allocation>[mHal.state.vertexBuffersCount];
Jason Samsa89371c2009-06-30 14:13:04 -070042}
43
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080044Mesh::~Mesh() {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -080045#ifndef ANDROID_RS_SERIALIZE
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070046 mRSC->mHal.funcs.mesh.destroy(mRSC, this);
47#endif
48
49 if (mHal.state.vertexBuffers) {
50 delete[] mHal.state.vertexBuffers;
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -080051 }
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070052
53 if (mHal.state.primitives) {
54 for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
55 mHal.state.primitives[i]->mIndexBuffer.clear();
56 delete mHal.state.primitives[i];
57 }
58 delete[] mHal.state.primitives;
59 }
60}
61
62void Mesh::init() {
63#ifndef ANDROID_RS_SERIALIZE
64 mRSC->mHal.funcs.mesh.init(mRSC, this);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080065#endif
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -080066}
67
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080068void Mesh::serialize(OStream *stream) const {
69 // Need to identify ourselves
70 stream->addU32((uint32_t)getClassId());
71
72 String8 name(getName());
73 stream->addString(&name);
74
75 // Store number of vertex streams
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070076 stream->addU32(mHal.state.vertexBuffersCount);
77 for (uint32_t vCount = 0; vCount < mHal.state.vertexBuffersCount; vCount ++) {
78 mHal.state.vertexBuffers[vCount]->serialize(stream);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080079 }
80
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070081 stream->addU32(mHal.state.primitivesCount);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080082 // Store the primitives
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070083 for (uint32_t pCount = 0; pCount < mHal.state.primitivesCount; pCount ++) {
84 Primitive_t * prim = mHal.state.primitives[pCount];
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080085
86 stream->addU8((uint8_t)prim->mPrimitive);
87
88 if (prim->mIndexBuffer.get()) {
89 stream->addU32(1);
90 prim->mIndexBuffer->serialize(stream);
91 } else {
92 stream->addU32(0);
93 }
94 }
95}
96
97Mesh *Mesh::createFromStream(Context *rsc, IStream *stream) {
98 // First make sure we are reading the correct object
99 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
100 if (classID != RS_A3D_CLASS_ID_MESH) {
101 LOGE("mesh loading skipped due to invalid class id");
102 return NULL;
103 }
104
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800105 String8 name;
106 stream->loadString(&name);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800107
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700108 uint32_t vertexBuffersCount = stream->loadU32();
109 ObjectBaseRef<Allocation> *vertexBuffers = NULL;
110 if (vertexBuffersCount) {
111 vertexBuffers = new ObjectBaseRef<Allocation>[vertexBuffersCount];
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800112
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700113 for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800114 Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700115 vertexBuffers[vCount].set(vertexAlloc);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800116 }
117 }
118
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700119 uint32_t primitivesCount = stream->loadU32();
120 ObjectBaseRef<Allocation> *indexBuffers = NULL;
121 RsPrimitive *primitives = NULL;
122 if (primitivesCount) {
123 indexBuffers = new ObjectBaseRef<Allocation>[primitivesCount];
124 primitives = new RsPrimitive[primitivesCount];
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800125
126 // load all primitives
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700127 for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
128 primitives[pCount] = (RsPrimitive)stream->loadU8();
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800129
130 // Check to see if the index buffer was stored
131 uint32_t isIndexPresent = stream->loadU32();
132 if (isIndexPresent) {
133 Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700134 indexBuffers[pCount].set(indexAlloc);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800135 }
136 }
137 }
138
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700139 Mesh *mesh = new Mesh(rsc, vertexBuffersCount, primitivesCount);
140 mesh->setName(name.string(), name.size());
141 for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
142 mesh->setVertexBuffer(vertexBuffers[vCount].get(), vCount);
143 }
144 for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
145 mesh->setPrimitive(indexBuffers[pCount].get(), primitives[pCount], pCount);
146 }
147
148 // Cleanup
149 if (vertexBuffersCount) {
150 delete[] vertexBuffers;
151 }
152 if (primitivesCount) {
153 delete[] indexBuffers;
154 delete[] primitives;
155 }
156
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800157#ifndef ANDROID_RS_SERIALIZE
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700158 mesh->init();
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800159 mesh->uploadAll(rsc);
160#endif
161 return mesh;
162}
163
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800164#ifndef ANDROID_RS_SERIALIZE
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800165
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800166void Mesh::render(Context *rsc) const {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700167 for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700168 renderPrimitive(rsc, ct);
169 }
170}
171
172void Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700173 if (primIndex >= mHal.state.primitivesCount) {
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700174 LOGE("Invalid primitive index");
175 return;
176 }
177
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700178 Primitive_t *prim = mHal.state.primitives[primIndex];
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700179
180 if (prim->mIndexBuffer.get()) {
181 renderPrimitiveRange(rsc, primIndex, 0, prim->mIndexBuffer->getType()->getDimX());
182 return;
183 }
184
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700185 renderPrimitiveRange(rsc, primIndex, 0, mHal.state.vertexBuffers[0]->getType()->getDimX());
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700186}
187
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800188void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700189 if (len < 1 || primIndex >= mHal.state.primitivesCount) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800190 LOGE("Invalid mesh or parameters");
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700191 return;
192 }
193
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700194 for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
195 mHal.state.vertexBuffers[ct]->uploadCheck(rsc);
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800196 }
197
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700198 Primitive_t *prim = mHal.state.primitives[primIndex];
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700199 if (prim->mIndexBuffer.get()) {
200 prim->mIndexBuffer->uploadCheck(rsc);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700201 }
202
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700203 mRSC->mHal.funcs.mesh.draw(mRSC, this, primIndex, start, len);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700204}
205
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800206void Mesh::uploadAll(Context *rsc) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700207 for (uint32_t ct = 0; ct < mHal.state.vertexBuffersCount; ct ++) {
208 if (mHal.state.vertexBuffers[ct].get()) {
209 mHal.state.vertexBuffers[ct]->deferredUploadToBufferObject(rsc);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700210 }
211 }
212
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700213 for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
214 if (mHal.state.primitives[ct]->mIndexBuffer.get()) {
215 mHal.state.primitives[ct]->mIndexBuffer->deferredUploadToBufferObject(rsc);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700216 }
217 }
Jason Samsa89371c2009-06-30 14:13:04 -0700218}
219
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700220void Mesh::computeBBox() {
221 float *posPtr = NULL;
222 uint32_t vectorSize = 0;
223 uint32_t stride = 0;
224 uint32_t numVerts = 0;
225 // First we need to find the position ptr and stride
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700226 for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
227 const Type *bufferType = mHal.state.vertexBuffers[ct]->getType();
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700228 const Element *bufferElem = bufferType->getElement();
229
230 for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800231 if (strcmp(bufferElem->getFieldName(ct), "position") == 0) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700232 vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
233 stride = bufferElem->getSizeBytes() / sizeof(float);
234 uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700235 posPtr = (float*)((uint8_t*)mHal.state.vertexBuffers[ct]->getPtr() + offset);
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700236 numVerts = bufferType->getDimX();
237 break;
238 }
239 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800240 if (posPtr) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700241 break;
242 }
243 }
244
245 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
246 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800247 if (!posPtr) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700248 LOGE("Unable to compute bounding box");
249 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
250 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
251 return;
252 }
253
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800254 for (uint32_t i = 0; i < numVerts; i ++) {
255 for (uint32_t v = 0; v < vectorSize; v ++) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700256 mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
257 mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
258 }
259 posPtr += stride;
260 }
261}
262
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700263namespace android {
264namespace renderscript {
265
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800266RsMesh rsi_MeshCreate(Context *rsc, uint32_t vtxCount, uint32_t idxCount) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700267 Mesh *sm = new Mesh(rsc, vtxCount, idxCount);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700268 sm->incUserRef();
269
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700270 return sm;
271}
272
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800273void rsi_MeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot) {
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700274 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700275 rsAssert(slot < sm->mHal.state.vertexBuffersCount);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700276
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700277 sm->setVertexBuffer((Allocation *)va, slot);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700278}
279
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800280void rsi_MeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot) {
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700281 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700282 rsAssert(slot < sm->mHal.state.primitivesCount);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700283
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700284 sm->setPrimitive((Allocation *)va, (RsPrimitive)primType, slot);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700285}
286
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800287void rsi_MeshInitVertexAttribs(Context *rsc, RsMesh mv) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800288 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700289 sm->init();
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800290}
291
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700292}}
293
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800294void rsaMeshGetVertexBufferCount(RsContext con, RsMesh mv, int32_t *numVtx) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700295 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700296 *numVtx = sm->mHal.state.vertexBuffersCount;
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700297}
298
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800299void rsaMeshGetIndexCount(RsContext con, RsMesh mv, int32_t *numIdx) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700300 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700301 *numIdx = sm->mHal.state.primitivesCount;
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700302}
303
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800304void rsaMeshGetVertices(RsContext con, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700305 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700306 rsAssert(vtxDataCount == sm->mHal.state.vertexBuffersCount);
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700307
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800308 for (uint32_t ct = 0; ct < vtxDataCount; ct ++) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700309 vtxData[ct] = sm->mHal.state.vertexBuffers[ct].get();
310 sm->mHal.state.vertexBuffers[ct]->incUserRef();
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700311 }
312}
313
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800314void rsaMeshGetIndices(RsContext con, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700315 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700316 rsAssert(idxDataCount == sm->mHal.state.primitivesCount);
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700317
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800318 for (uint32_t ct = 0; ct < idxDataCount; ct ++) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700319 va[ct] = sm->mHal.state.primitives[ct]->mIndexBuffer.get();
320 primType[ct] = sm->mHal.state.primitives[ct]->mPrimitive;
321 if (sm->mHal.state.primitives[ct]->mIndexBuffer.get()) {
322 sm->mHal.state.primitives[ct]->mIndexBuffer->incUserRef();
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700323 }
324 }
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700325}
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800326
327#endif