blob: f9dbc33c96f5a1138d6ab49cc23a7eda6a2380b2 [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 Sakhartchouke23d2392012-03-09 09:24:39 -080018#include "rs.h"
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070019
Jason Samsa89371c2009-06-30 14:13:04 -070020using namespace android;
21using namespace android::renderscript;
22
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080023Mesh::Mesh(Context *rsc) : ObjectBase(rsc) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070024 mHal.drv = NULL;
25 mHal.state.primitives = NULL;
26 mHal.state.primitivesCount = 0;
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070027 mHal.state.indexBuffers = NULL;
28 mHal.state.indexBuffersCount = 0;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070029 mHal.state.vertexBuffers = NULL;
30 mHal.state.vertexBuffersCount = 0;
31 mInitialized = false;
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070032
33 mVertexBuffers = NULL;
34 mIndexBuffers = NULL;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070035}
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080036
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070037Mesh::Mesh(Context *rsc,
38 uint32_t vertexBuffersCount,
39 uint32_t primitivesCount) : ObjectBase(rsc) {
40 mHal.drv = NULL;
41 mHal.state.primitivesCount = primitivesCount;
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070042 mHal.state.indexBuffersCount = primitivesCount;
43 mHal.state.primitives = new RsPrimitive[mHal.state.primitivesCount];
44 mHal.state.indexBuffers = new Allocation *[mHal.state.indexBuffersCount];
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070045 for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070046 mHal.state.primitives[i] = RS_PRIMITIVE_POINT;
47 }
48 for (uint32_t i = 0; i < mHal.state.indexBuffersCount; i ++) {
49 mHal.state.indexBuffers[i] = NULL;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070050 }
51 mHal.state.vertexBuffersCount = vertexBuffersCount;
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070052 mHal.state.vertexBuffers = new Allocation *[mHal.state.vertexBuffersCount];
53 for (uint32_t i = 0; i < mHal.state.vertexBuffersCount; i ++) {
54 mHal.state.vertexBuffers[i] = NULL;
55 }
56
57 mVertexBuffers = new ObjectBaseRef<Allocation>[mHal.state.vertexBuffersCount];
58 mIndexBuffers = new ObjectBaseRef<Allocation>[mHal.state.primitivesCount];
Jason Samsa89371c2009-06-30 14:13:04 -070059}
60
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080061Mesh::~Mesh() {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -080062#ifndef ANDROID_RS_SERIALIZE
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070063 mRSC->mHal.funcs.mesh.destroy(mRSC, this);
64#endif
65
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070066 delete[] mHal.state.vertexBuffers;
67 delete[] mHal.state.primitives;
68 delete[] mHal.state.indexBuffers;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070069
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070070 delete[] mVertexBuffers;
71 delete[] mIndexBuffers;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070072}
73
74void Mesh::init() {
75#ifndef ANDROID_RS_SERIALIZE
76 mRSC->mHal.funcs.mesh.init(mRSC, this);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080077#endif
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -080078}
79
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080080void Mesh::serialize(OStream *stream) const {
81 // Need to identify ourselves
82 stream->addU32((uint32_t)getClassId());
83
84 String8 name(getName());
85 stream->addString(&name);
86
87 // Store number of vertex streams
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070088 stream->addU32(mHal.state.vertexBuffersCount);
89 for (uint32_t vCount = 0; vCount < mHal.state.vertexBuffersCount; vCount ++) {
90 mHal.state.vertexBuffers[vCount]->serialize(stream);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080091 }
92
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070093 stream->addU32(mHal.state.primitivesCount);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080094 // Store the primitives
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070095 for (uint32_t pCount = 0; pCount < mHal.state.primitivesCount; pCount ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070096 stream->addU8((uint8_t)mHal.state.primitives[pCount]);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080097
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -070098 if (mHal.state.indexBuffers[pCount]) {
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080099 stream->addU32(1);
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700100 mHal.state.indexBuffers[pCount]->serialize(stream);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800101 } else {
102 stream->addU32(0);
103 }
104 }
105}
106
107Mesh *Mesh::createFromStream(Context *rsc, IStream *stream) {
108 // First make sure we are reading the correct object
109 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
110 if (classID != RS_A3D_CLASS_ID_MESH) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000111 ALOGE("mesh loading skipped due to invalid class id");
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800112 return NULL;
113 }
114
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800115 String8 name;
116 stream->loadString(&name);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800117
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700118 uint32_t vertexBuffersCount = stream->loadU32();
119 ObjectBaseRef<Allocation> *vertexBuffers = NULL;
120 if (vertexBuffersCount) {
121 vertexBuffers = new ObjectBaseRef<Allocation>[vertexBuffersCount];
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800122
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700123 for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800124 Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700125 vertexBuffers[vCount].set(vertexAlloc);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800126 }
127 }
128
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700129 uint32_t primitivesCount = stream->loadU32();
130 ObjectBaseRef<Allocation> *indexBuffers = NULL;
131 RsPrimitive *primitives = NULL;
132 if (primitivesCount) {
133 indexBuffers = new ObjectBaseRef<Allocation>[primitivesCount];
134 primitives = new RsPrimitive[primitivesCount];
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800135
136 // load all primitives
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700137 for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
138 primitives[pCount] = (RsPrimitive)stream->loadU8();
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800139
140 // Check to see if the index buffer was stored
141 uint32_t isIndexPresent = stream->loadU32();
142 if (isIndexPresent) {
143 Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700144 indexBuffers[pCount].set(indexAlloc);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800145 }
146 }
147 }
148
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700149 Mesh *mesh = new Mesh(rsc, vertexBuffersCount, primitivesCount);
150 mesh->setName(name.string(), name.size());
151 for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
152 mesh->setVertexBuffer(vertexBuffers[vCount].get(), vCount);
153 }
154 for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
155 mesh->setPrimitive(indexBuffers[pCount].get(), primitives[pCount], pCount);
156 }
157
158 // Cleanup
159 if (vertexBuffersCount) {
160 delete[] vertexBuffers;
161 }
162 if (primitivesCount) {
163 delete[] indexBuffers;
164 delete[] primitives;
165 }
166
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800167#ifndef ANDROID_RS_SERIALIZE
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700168 mesh->init();
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800169 mesh->uploadAll(rsc);
170#endif
171 return mesh;
172}
173
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800174void Mesh::render(Context *rsc) const {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700175 for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700176 renderPrimitive(rsc, ct);
177 }
178}
179
180void Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700181 if (primIndex >= mHal.state.primitivesCount) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000182 ALOGE("Invalid primitive index");
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700183 return;
184 }
185
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700186 if (mHal.state.indexBuffers[primIndex]) {
187 renderPrimitiveRange(rsc, primIndex, 0, mHal.state.indexBuffers[primIndex]->getType()->getDimX());
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700188 return;
189 }
190
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700191 renderPrimitiveRange(rsc, primIndex, 0, mHal.state.vertexBuffers[0]->getType()->getDimX());
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700192}
193
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800194void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700195 if (len < 1 || primIndex >= mHal.state.primitivesCount) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000196 ALOGE("Invalid mesh or parameters");
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700197 return;
198 }
199
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700200 mRSC->mHal.funcs.mesh.draw(mRSC, this, primIndex, start, len);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700201}
202
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800203void Mesh::uploadAll(Context *rsc) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700204 for (uint32_t ct = 0; ct < mHal.state.vertexBuffersCount; ct ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700205 if (mHal.state.vertexBuffers[ct]) {
206 rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.vertexBuffers[ct]);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700207 }
208 }
209
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700210 for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700211 if (mHal.state.indexBuffers[ct]) {
212 rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.indexBuffers[ct]);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700213 }
214 }
Jason Samsa89371c2009-06-30 14:13:04 -0700215}
216
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700217void Mesh::computeBBox() {
218 float *posPtr = NULL;
219 uint32_t vectorSize = 0;
220 uint32_t stride = 0;
221 uint32_t numVerts = 0;
222 // First we need to find the position ptr and stride
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700223 for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
224 const Type *bufferType = mHal.state.vertexBuffers[ct]->getType();
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700225 const Element *bufferElem = bufferType->getElement();
226
227 for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800228 if (strcmp(bufferElem->getFieldName(ct), "position") == 0) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700229 vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
230 stride = bufferElem->getSizeBytes() / sizeof(float);
231 uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700232 posPtr = (float*)((uint8_t*)mHal.state.vertexBuffers[ct]->getPtr() + offset);
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700233 numVerts = bufferType->getDimX();
234 break;
235 }
236 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800237 if (posPtr) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700238 break;
239 }
240 }
241
242 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
243 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800244 if (!posPtr) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000245 ALOGE("Unable to compute bounding box");
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700246 mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
247 mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
248 return;
249 }
250
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800251 for (uint32_t i = 0; i < numVerts; i ++) {
252 for (uint32_t v = 0; v < vectorSize; v ++) {
Alex Sakhartchoukba4aa5c2010-08-13 14:32:23 -0700253 mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
254 mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
255 }
256 posPtr += stride;
257 }
258}
259
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700260namespace android {
261namespace renderscript {
262
Alex Sakhartchouk9003e562011-05-12 10:38:03 -0700263RsMesh rsi_MeshCreate(Context *rsc,
Alex Sakhartchoukb81a0eb2011-06-03 10:18:01 -0700264 RsAllocation * vtx, size_t vtxCount,
265 RsAllocation * idx, size_t idxCount,
266 uint32_t * primType, size_t primTypeCount) {
Alex Sakhartchouk9003e562011-05-12 10:38:03 -0700267 rsAssert(idxCount == primTypeCount);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700268 Mesh *sm = new Mesh(rsc, vtxCount, idxCount);
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700269 sm->incUserRef();
270
Alex Sakhartchouk9003e562011-05-12 10:38:03 -0700271 for (uint32_t i = 0; i < vtxCount; i ++) {
272 sm->setVertexBuffer((Allocation*)vtx[i], i);
273 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700274
Alex Sakhartchouk9003e562011-05-12 10:38:03 -0700275 for (uint32_t i = 0; i < idxCount; i ++) {
276 sm->setPrimitive((Allocation*)idx[i], (RsPrimitive)primType[i], i);
277 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700278
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700279 sm->init();
Alex Sakhartchouk9003e562011-05-12 10:38:03 -0700280
281 return sm;
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800282}
283
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700284}}
285
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800286void rsaMeshGetVertexBufferCount(RsContext con, RsMesh mv, int32_t *numVtx) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700287 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700288 *numVtx = sm->mHal.state.vertexBuffersCount;
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700289}
290
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800291void rsaMeshGetIndexCount(RsContext con, RsMesh mv, int32_t *numIdx) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700292 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700293 *numIdx = sm->mHal.state.primitivesCount;
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700294}
295
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800296void rsaMeshGetVertices(RsContext con, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700297 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700298 rsAssert(vtxDataCount == sm->mHal.state.vertexBuffersCount);
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700299
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800300 for (uint32_t ct = 0; ct < vtxDataCount; ct ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700301 vtxData[ct] = sm->mHal.state.vertexBuffers[ct];
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700302 sm->mHal.state.vertexBuffers[ct]->incUserRef();
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700303 }
304}
305
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800306void rsaMeshGetIndices(RsContext con, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700307 Mesh *sm = static_cast<Mesh *>(mv);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700308 rsAssert(idxDataCount == sm->mHal.state.primitivesCount);
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700309
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800310 for (uint32_t ct = 0; ct < idxDataCount; ct ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700311 va[ct] = sm->mHal.state.indexBuffers[ct];
312 primType[ct] = sm->mHal.state.primitives[ct];
313 if (sm->mHal.state.indexBuffers[ct]) {
314 sm->mHal.state.indexBuffers[ct]->incUserRef();
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700315 }
316 }
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700317}