blob: 4f90f36b1c400e839d65d0b05e112c5d656f3ff4 [file] [log] [blame]
Jason Samsa89371c2009-06-30 14:13:04 -07001/*
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
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070017#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Samsa89371c2009-06-30 14:13:04 -070018#include "rsContext.h"
19
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070020#include <GLES/gl.h>
21#include <GLES2/gl2.h>
22#include <GLES/glext.h>
23#else
24#include "rsContextHostStub.h"
25
26#include <OpenGL/gl.h>
27#include <OpenGl/glext.h>
28#endif
29
30
Jason Samsa89371c2009-06-30 14:13:04 -070031using namespace android;
32using namespace android::renderscript;
33
Jason Samse514b452009-09-25 14:51:22 -070034Mesh::Mesh(Context *rsc) : ObjectBase(rsc)
Jason Samsa89371c2009-06-30 14:13:04 -070035{
Jason Samsf2649a92009-09-25 16:37:33 -070036 mAllocFile = __FILE__;
37 mAllocLine = __LINE__;
Jason Samsa89371c2009-06-30 14:13:04 -070038 mPrimitives = NULL;
Jason Samsa5597fc2009-07-08 18:01:53 -070039 mPrimitivesCount = 0;
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -070040 mVertexBuffers = NULL;
41 mVertexTypes = NULL;
42 mVertexBufferCount = 0;
Jason Samsa89371c2009-06-30 14:13:04 -070043}
44
45Mesh::~Mesh()
46{
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -070047 if(mVertexTypes) {
48 delete[] mVertexTypes;
49 }
50
51 if(mVertexBuffers) {
52 delete[] mVertexBuffers;
53 }
54
55 if(mPrimitives) {
56 for(uint32_t i = 0; i < mPrimitivesCount; i ++) {
57 delete mPrimitives[i];
58 }
59 delete[] mPrimitives;
60 }
61}
62
63void Mesh::render(Context *rsc) const
64{
65 for(uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
66 renderPrimitive(rsc, ct);
67 }
68}
69
70void Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
71 if (primIndex >= mPrimitivesCount) {
72 LOGE("Invalid primitive index");
73 return;
74 }
75
76 Primitive_t *prim = mPrimitives[primIndex];
77
78 if (prim->mIndexBuffer.get()) {
79 renderPrimitiveRange(rsc, primIndex, 0, prim->mIndexBuffer->getType()->getDimX());
80 return;
81 }
82
83 if (prim->mPrimitiveBuffer.get()) {
84 renderPrimitiveRange(rsc, primIndex, 0, prim->mPrimitiveBuffer->getType()->getDimX());
85 return;
86 }
87
88 renderPrimitiveRange(rsc, primIndex, 0, mVertexBuffers[0]->getType()->getDimX());
89}
90
91void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const
92{
93 if (len < 1 || primIndex >= mPrimitivesCount) {
94 return;
95 }
96
97 rsc->checkError("Mesh::renderPrimitiveRange 1");
98 VertexArray va;
99 for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
100 mVertexBuffers[ct]->uploadCheck(rsc);
101 if (mVertexBuffers[ct]->getIsBufferObject()) {
102 va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID());
103 } else {
104 va.setActiveBuffer(mVertexBuffers[ct]->getPtr());
105 }
106 mVertexBuffers[ct]->getType()->enableGLVertexBuffer(&va);
107 }
108 va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
109
110 rsc->checkError("Mesh::renderPrimitiveRange 2");
111 Primitive_t *prim = mPrimitives[primIndex];
112 if (prim->mIndexBuffer.get()) {
113 prim->mIndexBuffer->uploadCheck(rsc);
114 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prim->mIndexBuffer->getBufferObjectID());
115 glDrawElements(prim->mGLPrimitive, len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2));
116 } else {
117 glDrawArrays(prim->mGLPrimitive, start, len);
118 }
119
120 rsc->checkError("Mesh::renderPrimitiveRange");
121}
122
123
124void Mesh::uploadAll(Context *rsc)
125{
126 for (uint32_t ct = 0; ct < mVertexBufferCount; ct ++) {
127 if (mVertexBuffers[ct].get()) {
128 mVertexBuffers[ct]->deferedUploadToBufferObject(rsc);
129 }
130 }
131
132 for (uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
133 if (mPrimitives[ct]->mIndexBuffer.get()) {
134 mPrimitives[ct]->mIndexBuffer->deferedUploadToBufferObject(rsc);
135 }
136 if (mPrimitives[ct]->mPrimitiveBuffer.get()) {
137 mPrimitives[ct]->mPrimitiveBuffer->deferedUploadToBufferObject(rsc);
138 }
139 }
140
141 rsc->checkError("Mesh::uploadAll");
142}
143
144void Mesh::updateGLPrimitives()
145{
146 for(uint32_t i = 0; i < mPrimitivesCount; i ++) {
147 switch(mPrimitives[i]->mPrimitive) {
148 case RS_PRIMITIVE_POINT: mPrimitives[i]->mGLPrimitive = GL_POINTS; break;
149 case RS_PRIMITIVE_LINE: mPrimitives[i]->mGLPrimitive = GL_LINES; break;
150 case RS_PRIMITIVE_LINE_STRIP: mPrimitives[i]->mGLPrimitive = GL_LINE_STRIP; break;
151 case RS_PRIMITIVE_TRIANGLE: mPrimitives[i]->mGLPrimitive = GL_TRIANGLES; break;
152 case RS_PRIMITIVE_TRIANGLE_STRIP: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_STRIP; break;
153 case RS_PRIMITIVE_TRIANGLE_FAN: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_FAN; break;
154 }
155 }
Jason Samsa89371c2009-06-30 14:13:04 -0700156}
157
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700158void Mesh::serialize(OStream *stream) const
159{
160 // Need to identify ourselves
161 stream->addU32((uint32_t)getClassId());
162
163 String8 name(getName());
164 stream->addString(&name);
165
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700166 // Store number of vertex streams
167 stream->addU32(mVertexBufferCount);
168 for(uint32_t vCount = 0; vCount < mVertexBufferCount; vCount ++) {
169 mVertexBuffers[vCount]->serialize(stream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700170 }
171
172 stream->addU32(mPrimitivesCount);
173 // Store the primitives
174 for (uint32_t pCount = 0; pCount < mPrimitivesCount; pCount ++) {
175 Primitive_t * prim = mPrimitives[pCount];
176
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700177 stream->addU8((uint8_t)prim->mPrimitive);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700178
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700179 if(prim->mIndexBuffer.get()) {
180 stream->addU32(1);
181 prim->mIndexBuffer->serialize(stream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700182 }
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700183 else {
184 stream->addU32(0);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700185 }
186
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700187 if(prim->mPrimitiveBuffer.get()) {
188 stream->addU32(1);
189 prim->mPrimitiveBuffer->serialize(stream);
190 }
191 else {
192 stream->addU32(0);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700193 }
194 }
195}
196
197Mesh *Mesh::createFromStream(Context *rsc, IStream *stream)
198{
199 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700200 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
201 if(classID != RS_A3D_CLASS_ID_MESH) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700202 LOGE("mesh loading skipped due to invalid class id");
203 return NULL;
204 }
205
206 Mesh * mesh = new Mesh(rsc);
207
208 String8 name;
209 stream->loadString(&name);
210 mesh->setName(name.string(), name.size());
211
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700212 mesh->mVertexBufferCount = stream->loadU32();
213 if(mesh->mVertexBufferCount) {
214 mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[mesh->mVertexBufferCount];
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700215
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700216 for(uint32_t vCount = 0; vCount < mesh->mVertexBufferCount; vCount ++) {
217 Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
218 mesh->mVertexBuffers[vCount].set(vertexAlloc);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700219 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700220 }
221
222 mesh->mPrimitivesCount = stream->loadU32();
223 if(mesh->mPrimitivesCount) {
224 mesh->mPrimitives = new Primitive_t *[mesh->mPrimitivesCount];
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700225
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700226 // load all primitives
227 for (uint32_t pCount = 0; pCount < mesh->mPrimitivesCount; pCount ++) {
228 Primitive_t * prim = new Primitive_t;
229 mesh->mPrimitives[pCount] = prim;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700230
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700231 prim->mPrimitive = (RsPrimitive)stream->loadU8();
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700232
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700233 // Check to see if the index buffer was stored
234 uint32_t isIndexPresent = stream->loadU32();
235 if(isIndexPresent) {
236 Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
237 prim->mIndexBuffer.set(indexAlloc);
238 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700239
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700240 // Check to see if the primitive buffer was stored
241 uint32_t isPrimitivePresent = stream->loadU32();
242 if(isPrimitivePresent) {
243 Allocation *primitiveAlloc = Allocation::createFromStream(rsc, stream);
244 prim->mPrimitiveBuffer.set(primitiveAlloc);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700245 }
246 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700247 }
248
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700249 mesh->updateGLPrimitives();
250 mesh->uploadAll(rsc);
251
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700252 return mesh;
253}
Jason Samsa89371c2009-06-30 14:13:04 -0700254
255
256MeshContext::MeshContext()
257{
258}
259
260MeshContext::~MeshContext()
261{
262}
263
Alex Sakhartchouk4e9a7a82010-07-01 16:14:06 -0700264namespace android {
265namespace renderscript {
266
267RsMesh rsi_MeshCreate(Context *rsc, uint32_t vtxCount, uint32_t idxCount)
268{
269 Mesh *sm = new Mesh(rsc);
270 sm->incUserRef();
271
272 sm->mPrimitivesCount = idxCount;
273 sm->mPrimitives = new Mesh::Primitive_t *[sm->mPrimitivesCount];
274 for(uint32_t ct = 0; ct < idxCount; ct ++) {
275 sm->mPrimitives[ct] = new Mesh::Primitive_t;
276 }
277
278 sm->mVertexBufferCount = vtxCount;
279 sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount];
280 sm->mVertexTypes = new ObjectBaseRef<const Type>[vtxCount];
281
282 return sm;
283}
284
285void rsi_MeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot)
286{
287 Mesh *sm = static_cast<Mesh *>(mv);
288 rsAssert(slot < sm->mVertexBufferCount);
289
290 sm->mVertexBuffers[slot].set((Allocation *)va);
291}
292
293void rsi_MeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot)
294{
295 Mesh *sm = static_cast<Mesh *>(mv);
296 rsAssert(slot < sm->mPrimitivesCount);
297
298 sm->mPrimitives[slot]->mIndexBuffer.set((Allocation *)va);
299 sm->mPrimitives[slot]->mPrimitive = (RsPrimitive)primType;
300 sm->updateGLPrimitives();
301}
302
303void rsi_MeshBindPrimitive(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot)
304{
305 Mesh *sm = static_cast<Mesh *>(mv);
306 rsAssert(slot < sm->mPrimitivesCount);
307
308 sm->mPrimitives[slot]->mPrimitiveBuffer.set((Allocation *)va);
309 sm->mPrimitives[slot]->mPrimitive = (RsPrimitive)primType;
310 sm->updateGLPrimitives();
311}
312
313
314// Route all the simple mesh through mesh
315
316RsMesh rsi_SimpleMeshCreate(Context *rsc, RsType prim, RsType idx, RsType *vtx, uint32_t vtxCount, uint32_t primType)
317{
318 Mesh *sm = new Mesh(rsc);
319 sm->incUserRef();
320
321 sm->mPrimitivesCount = 1;
322 sm->mPrimitives = new Mesh::Primitive_t *[sm->mPrimitivesCount];
323 sm->mPrimitives[0] = new Mesh::Primitive_t;
324
325 sm->mPrimitives[0]->mIndexType.set((const Type *)idx);
326 sm->mPrimitives[0]->mPrimitiveType.set((const Type *)prim);
327 sm->mPrimitives[0]->mPrimitive = (RsPrimitive)primType;
328 sm->updateGLPrimitives();
329
330 sm->mVertexBufferCount = vtxCount;
331 sm->mVertexTypes = new ObjectBaseRef<const Type>[vtxCount];
332 sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount];
333 for (uint32_t ct=0; ct < vtxCount; ct++) {
334 sm->mVertexTypes[ct].set((const Type *)vtx[ct]);
335 }
336
337 return sm;
338}
339
340void rsi_SimpleMeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot)
341{
342 Mesh *sm = static_cast<Mesh *>(mv);
343 rsAssert(slot < sm->mVertexBufferCount);
344
345 sm->mVertexBuffers[slot].set((Allocation *)va);
346}
347
348void rsi_SimpleMeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va)
349{
350 Mesh *sm = static_cast<Mesh *>(mv);
351 sm->mPrimitives[0]->mIndexBuffer.set((Allocation *)va);
352}
353
354void rsi_SimpleMeshBindPrimitive(Context *rsc, RsMesh mv, RsAllocation va)
355{
356 Mesh *sm = static_cast<Mesh *>(mv);
357 sm->mPrimitives[0]->mPrimitiveBuffer.set((Allocation *)va);
358}
359
360
361
362
363}}