blob: 651a8f33148fe0f6bcd01276ce874008ec4d8172 [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 Sakhartchouk4edf0302012-03-09 10:47:27 -080018#include "rsMesh.h"
Alex Sakhartchouke23d2392012-03-09 09:24:39 -080019#include "rs.h"
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070020
Jason Samsa89371c2009-06-30 14:13:04 -070021using namespace android;
22using namespace android::renderscript;
23
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080024Mesh::Mesh(Context *rsc) : ObjectBase(rsc) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070025 mHal.drv = NULL;
26 mHal.state.primitives = NULL;
27 mHal.state.primitivesCount = 0;
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070028 mHal.state.indexBuffers = NULL;
29 mHal.state.indexBuffersCount = 0;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070030 mHal.state.vertexBuffers = NULL;
31 mHal.state.vertexBuffersCount = 0;
32 mInitialized = false;
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070033
34 mVertexBuffers = NULL;
35 mIndexBuffers = NULL;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070036}
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080037
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070038Mesh::Mesh(Context *rsc,
39 uint32_t vertexBuffersCount,
40 uint32_t primitivesCount) : ObjectBase(rsc) {
41 mHal.drv = NULL;
42 mHal.state.primitivesCount = primitivesCount;
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070043 mHal.state.indexBuffersCount = primitivesCount;
44 mHal.state.primitives = new RsPrimitive[mHal.state.primitivesCount];
45 mHal.state.indexBuffers = new Allocation *[mHal.state.indexBuffersCount];
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070046 for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070047 mHal.state.primitives[i] = RS_PRIMITIVE_POINT;
48 }
49 for (uint32_t i = 0; i < mHal.state.indexBuffersCount; i ++) {
50 mHal.state.indexBuffers[i] = NULL;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070051 }
52 mHal.state.vertexBuffersCount = vertexBuffersCount;
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070053 mHal.state.vertexBuffers = new Allocation *[mHal.state.vertexBuffersCount];
54 for (uint32_t i = 0; i < mHal.state.vertexBuffersCount; i ++) {
55 mHal.state.vertexBuffers[i] = NULL;
56 }
57
58 mVertexBuffers = new ObjectBaseRef<Allocation>[mHal.state.vertexBuffersCount];
59 mIndexBuffers = new ObjectBaseRef<Allocation>[mHal.state.primitivesCount];
Jason Samsa89371c2009-06-30 14:13:04 -070060}
61
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080062Mesh::~Mesh() {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -080063#ifndef ANDROID_RS_SERIALIZE
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070064 mRSC->mHal.funcs.mesh.destroy(mRSC, this);
65#endif
66
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070067 delete[] mHal.state.vertexBuffers;
68 delete[] mHal.state.primitives;
69 delete[] mHal.state.indexBuffers;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070070
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070071 delete[] mVertexBuffers;
72 delete[] mIndexBuffers;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070073}
74
75void Mesh::init() {
76#ifndef ANDROID_RS_SERIALIZE
77 mRSC->mHal.funcs.mesh.init(mRSC, this);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080078#endif
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -080079}
80
Jason Samse3150cf2012-07-24 18:10:20 -070081void Mesh::serialize(Context *rsc, OStream *stream) const {
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080082 // Need to identify ourselves
83 stream->addU32((uint32_t)getClassId());
84
85 String8 name(getName());
86 stream->addString(&name);
87
88 // Store number of vertex streams
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070089 stream->addU32(mHal.state.vertexBuffersCount);
90 for (uint32_t vCount = 0; vCount < mHal.state.vertexBuffersCount; vCount ++) {
Jason Samse3150cf2012-07-24 18:10:20 -070091 mHal.state.vertexBuffers[vCount]->serialize(rsc, stream);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080092 }
93
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070094 stream->addU32(mHal.state.primitivesCount);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080095 // Store the primitives
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070096 for (uint32_t pCount = 0; pCount < mHal.state.primitivesCount; pCount ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070097 stream->addU8((uint8_t)mHal.state.primitives[pCount]);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080098
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070099 if (mHal.state.indexBuffers[pCount]) {
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800100 stream->addU32(1);
Jason Samse3150cf2012-07-24 18:10:20 -0700101 mHal.state.indexBuffers[pCount]->serialize(rsc, stream);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800102 } else {
103 stream->addU32(0);
104 }
105 }
106}
107
108Mesh *Mesh::createFromStream(Context *rsc, IStream *stream) {
109 // First make sure we are reading the correct object
110 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
111 if (classID != RS_A3D_CLASS_ID_MESH) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000112 ALOGE("mesh loading skipped due to invalid class id");
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800113 return NULL;
114 }
115
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800116 String8 name;
117 stream->loadString(&name);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800118
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700119 uint32_t vertexBuffersCount = stream->loadU32();
120 ObjectBaseRef<Allocation> *vertexBuffers = NULL;
121 if (vertexBuffersCount) {
122 vertexBuffers = new ObjectBaseRef<Allocation>[vertexBuffersCount];
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800123
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700124 for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800125 Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700126 vertexBuffers[vCount].set(vertexAlloc);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800127 }
128 }
129
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700130 uint32_t primitivesCount = stream->loadU32();
131 ObjectBaseRef<Allocation> *indexBuffers = NULL;
132 RsPrimitive *primitives = NULL;
133 if (primitivesCount) {
134 indexBuffers = new ObjectBaseRef<Allocation>[primitivesCount];
135 primitives = new RsPrimitive[primitivesCount];
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800136
137 // load all primitives
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700138 for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
139 primitives[pCount] = (RsPrimitive)stream->loadU8();
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800140
141 // Check to see if the index buffer was stored
142 uint32_t isIndexPresent = stream->loadU32();
143 if (isIndexPresent) {
144 Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700145 indexBuffers[pCount].set(indexAlloc);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800146 }
147 }
148 }
149
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700150 Mesh *mesh = new Mesh(rsc, vertexBuffersCount, primitivesCount);
151 mesh->setName(name.string(), name.size());
152 for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
153 mesh->setVertexBuffer(vertexBuffers[vCount].get(), vCount);
154 }
155 for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
156 mesh->setPrimitive(indexBuffers[pCount].get(), primitives[pCount], pCount);
157 }
158
159 // Cleanup
160 if (vertexBuffersCount) {
161 delete[] vertexBuffers;
162 }
163 if (primitivesCount) {
164 delete[] indexBuffers;
165 delete[] primitives;
166 }
167
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800168#ifndef ANDROID_RS_SERIALIZE
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700169 mesh->init();
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800170 mesh->uploadAll(rsc);
171#endif
172 return mesh;
173}
174
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800175void Mesh::render(Context *rsc) const {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700176 for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700177 renderPrimitive(rsc, ct);
178 }
179}
180
181void Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700182 if (primIndex >= mHal.state.primitivesCount) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000183 ALOGE("Invalid primitive index");
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700184 return;
185 }
186
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700187 if (mHal.state.indexBuffers[primIndex]) {
188 renderPrimitiveRange(rsc, primIndex, 0, mHal.state.indexBuffers[primIndex]->getType()->getDimX());
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700189 return;
190 }
191
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700192 renderPrimitiveRange(rsc, primIndex, 0, mHal.state.vertexBuffers[0]->getType()->getDimX());
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700193}
194
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800195void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700196 if (len < 1 || primIndex >= mHal.state.primitivesCount) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000197 ALOGE("Invalid mesh or parameters");
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700198 return;
199 }
200
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700201 mRSC->mHal.funcs.mesh.draw(mRSC, this, primIndex, start, len);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700202}
203
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800204void Mesh::uploadAll(Context *rsc) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700205 for (uint32_t ct = 0; ct < mHal.state.vertexBuffersCount; ct ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700206 if (mHal.state.vertexBuffers[ct]) {
207 rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.vertexBuffers[ct]);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700208 }
209 }
210
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700211 for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700212 if (mHal.state.indexBuffers[ct]) {
213 rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.indexBuffers[ct]);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700214 }
215 }
Jason Samsa89371c2009-06-30 14:13:04 -0700216}
217
Jason Samse3150cf2012-07-24 18:10:20 -0700218void Mesh::computeBBox(Context *rsc) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700219 float *posPtr = NULL;
220 uint32_t vectorSize = 0;
221 uint32_t stride = 0;
222 uint32_t numVerts = 0;
Jason Sams807fdc42012-07-25 17:55:39 -0700223 Allocation *posAlloc = NULL;
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700224 // First we need to find the position ptr and stride
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700225 for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
226 const Type *bufferType = mHal.state.vertexBuffers[ct]->getType();
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700227 const Element *bufferElem = bufferType->getElement();
228
229 for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800230 if (strcmp(bufferElem->getFieldName(ct), "position") == 0) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700231 vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
232 stride = bufferElem->getSizeBytes() / sizeof(float);
233 uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
Jason Sams807fdc42012-07-25 17:55:39 -0700234 posAlloc = mHal.state.vertexBuffers[ct];
235 const uint8_t *bp = (const uint8_t *)rsc->mHal.funcs.allocation.lock1D(
236 rsc, posAlloc);
237 posPtr = (float*)(bp + offset);
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700238 numVerts = bufferType->getDimX();
239 break;
240 }
241 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800242 if (posPtr) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700243 break;
244 }
245 }
246
247 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
248 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800249 if (!posPtr) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000250 ALOGE("Unable to compute bounding box");
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700251 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
252 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
253 return;
254 }
255
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800256 for (uint32_t i = 0; i < numVerts; i ++) {
257 for (uint32_t v = 0; v < vectorSize; v ++) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700258 mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
259 mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
260 }
261 posPtr += stride;
262 }
Jason Sams807fdc42012-07-25 17:55:39 -0700263
264 if (posAlloc) {
265 rsc->mHal.funcs.allocation.unlock1D(rsc, posAlloc);
266 }
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700267}
268
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700269namespace android {
270namespace renderscript {
271
Alex Sakhartchouk9003e562011-05-12 10:38:03 -0700272RsMesh rsi_MeshCreate(Context *rsc,
Alex Sakhartchoukb81a0eb2011-06-03 10:18:01 -0700273 RsAllocation * vtx, size_t vtxCount,
274 RsAllocation * idx, size_t idxCount,
275 uint32_t * primType, size_t primTypeCount) {
Alex Sakhartchouk9003e562011-05-12 10:38:03 -0700276 rsAssert(idxCount == primTypeCount);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700277 Mesh *sm = new Mesh(rsc, vtxCount, idxCount);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700278 sm->incUserRef();
279
Alex Sakhartchouk9003e562011-05-12 10:38:03 -0700280 for (uint32_t i = 0; i < vtxCount; i ++) {
281 sm->setVertexBuffer((Allocation*)vtx[i], i);
282 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700283
Alex Sakhartchouk9003e562011-05-12 10:38:03 -0700284 for (uint32_t i = 0; i < idxCount; i ++) {
285 sm->setPrimitive((Allocation*)idx[i], (RsPrimitive)primType[i], i);
286 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700287
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700288 sm->init();
Alex Sakhartchouk9003e562011-05-12 10:38:03 -0700289
290 return sm;
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800291}
292
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700293}}
294
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800295void rsaMeshGetVertexBufferCount(RsContext con, RsMesh mv, int32_t *numVtx) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700296 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700297 *numVtx = sm->mHal.state.vertexBuffersCount;
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700298}
299
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800300void rsaMeshGetIndexCount(RsContext con, RsMesh mv, int32_t *numIdx) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700301 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700302 *numIdx = sm->mHal.state.primitivesCount;
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700303}
304
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800305void rsaMeshGetVertices(RsContext con, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700306 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700307 rsAssert(vtxDataCount == sm->mHal.state.vertexBuffersCount);
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700308
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800309 for (uint32_t ct = 0; ct < vtxDataCount; ct ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700310 vtxData[ct] = sm->mHal.state.vertexBuffers[ct];
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700311 sm->mHal.state.vertexBuffers[ct]->incUserRef();
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700312 }
313}
314
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800315void rsaMeshGetIndices(RsContext con, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700316 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700317 rsAssert(idxDataCount == sm->mHal.state.primitivesCount);
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700318
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800319 for (uint32_t ct = 0; ct < idxDataCount; ct ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700320 va[ct] = sm->mHal.state.indexBuffers[ct];
321 primType[ct] = sm->mHal.state.primitives[ct];
322 if (sm->mHal.state.indexBuffers[ct]) {
323 sm->mHal.state.indexBuffers[ct]->incUserRef();
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700324 }
325 }
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700326}