rsMesh.cpp revision a04e30dbb5ab11592b03666bb3d102070759c58e
1a89371c6f144b9049efe7689105feee2c4a38384Jason Sams/*
2a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * Copyright (C) 2011 The Android Open Source Project
3a89371c6f144b9049efe7689105feee2c4a38384Jason Sams *
4a89371c6f144b9049efe7689105feee2c4a38384Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5a89371c6f144b9049efe7689105feee2c4a38384Jason Sams * you may not use this file except in compliance with the License.
6a89371c6f144b9049efe7689105feee2c4a38384Jason Sams * You may obtain a copy of the License at
7a89371c6f144b9049efe7689105feee2c4a38384Jason Sams *
8a89371c6f144b9049efe7689105feee2c4a38384Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9a89371c6f144b9049efe7689105feee2c4a38384Jason Sams *
10a89371c6f144b9049efe7689105feee2c4a38384Jason Sams * Unless required by applicable law or agreed to in writing, software
11a89371c6f144b9049efe7689105feee2c4a38384Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12a89371c6f144b9049efe7689105feee2c4a38384Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a89371c6f144b9049efe7689105feee2c4a38384Jason Sams * See the License for the specific language governing permissions and
14a89371c6f144b9049efe7689105feee2c4a38384Jason Sams * limitations under the License.
15a89371c6f144b9049efe7689105feee2c4a38384Jason Sams */
16a89371c6f144b9049efe7689105feee2c4a38384Jason Sams
17a89371c6f144b9049efe7689105feee2c4a38384Jason Sams#include "rsContext.h"
18fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
19fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchoukusing namespace android;
20fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchoukusing namespace android::renderscript;
21a89371c6f144b9049efe7689105feee2c4a38384Jason Sams
22afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukMesh::Mesh(Context *rsc) : ObjectBase(rsc) {
23a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.drv = NULL;
24a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.primitives = NULL;
25a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.primitivesCount = 0;
26a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.vertexBuffers = NULL;
27a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.vertexBuffersCount = 0;
28a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mInitialized = false;
29a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk}
3054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
31a04e30dbb5ab11592b03666bb3d102070759c58eAlex SakhartchoukMesh::Mesh(Context *rsc,
32a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk           uint32_t vertexBuffersCount,
33a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk           uint32_t primitivesCount) : ObjectBase(rsc) {
34a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.drv = NULL;
35a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.primitivesCount = primitivesCount;
36a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.primitives = new Primitive_t *[mHal.state.primitivesCount];
37a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
38a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        mHal.state.primitives[i] = new Primitive_t;
39a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
40a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.vertexBuffersCount = vertexBuffersCount;
41a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.vertexBuffers = new ObjectBaseRef<Allocation>[mHal.state.vertexBuffersCount];
42a89371c6f144b9049efe7689105feee2c4a38384Jason Sams}
43a89371c6f144b9049efe7689105feee2c4a38384Jason Sams
44afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukMesh::~Mesh() {
45a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
46a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mRSC->mHal.funcs.mesh.destroy(mRSC, this);
47a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#endif
48a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
49a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (mHal.state.vertexBuffers) {
50a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] mHal.state.vertexBuffers;
514e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
524e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
53a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (mHal.state.primitives) {
54a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
55a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            mHal.state.primitives[i]->mIndexBuffer.clear();
56a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            delete mHal.state.primitives[i];
574e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        }
58a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] mHal.state.primitives;
594e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
60a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk}
6154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
62a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchoukvoid Mesh::init() {
6377d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
64a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mRSC->mHal.funcs.mesh.init(mRSC, this);
65099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk#endif
66099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk}
67099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
68099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchoukvoid Mesh::serialize(OStream *stream) const {
69099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    // Need to identify ourselves
70099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    stream->addU32((uint32_t)getClassId());
71099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
72099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    String8 name(getName());
73099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    stream->addString(&name);
74099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
75099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    // Store number of vertex streams
76a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    stream->addU32(mHal.state.vertexBuffersCount);
77a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t vCount = 0; vCount < mHal.state.vertexBuffersCount; vCount ++) {
78a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        mHal.state.vertexBuffers[vCount]->serialize(stream);
79099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    }
80099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
81a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    stream->addU32(mHal.state.primitivesCount);
82099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    // Store the primitives
83a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t pCount = 0; pCount < mHal.state.primitivesCount; pCount ++) {
84a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        Primitive_t * prim = mHal.state.primitives[pCount];
85099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
86099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        stream->addU8((uint8_t)prim->mPrimitive);
87099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
88099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        if (prim->mIndexBuffer.get()) {
89099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            stream->addU32(1);
90099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            prim->mIndexBuffer->serialize(stream);
91099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        } else {
92099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            stream->addU32(0);
93099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        }
94099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    }
95099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk}
96099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
97099d7d33e55afeb3399f6e8cf8d665223ca94939Alex SakhartchoukMesh *Mesh::createFromStream(Context *rsc, IStream *stream) {
98099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    // First make sure we are reading the correct object
99099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
100099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_MESH) {
101099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        LOGE("mesh loading skipped due to invalid class id");
102099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        return NULL;
103099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    }
104099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
105099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    String8 name;
106099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    stream->loadString(&name);
107099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
108a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    uint32_t vertexBuffersCount = stream->loadU32();
109a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    ObjectBaseRef<Allocation> *vertexBuffers = NULL;
110a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (vertexBuffersCount) {
111a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        vertexBuffers = new ObjectBaseRef<Allocation>[vertexBuffersCount];
112099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
113a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
114099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
115a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            vertexBuffers[vCount].set(vertexAlloc);
116099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        }
117099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    }
118099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
119a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    uint32_t primitivesCount = stream->loadU32();
120a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    ObjectBaseRef<Allocation> *indexBuffers = NULL;
121a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    RsPrimitive *primitives = NULL;
122a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (primitivesCount) {
123a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        indexBuffers = new ObjectBaseRef<Allocation>[primitivesCount];
124a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        primitives = new RsPrimitive[primitivesCount];
125099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
126099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        // load all primitives
127a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
128a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            primitives[pCount] = (RsPrimitive)stream->loadU8();
129099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
130099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            // Check to see if the index buffer was stored
131099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            uint32_t isIndexPresent = stream->loadU32();
132099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            if (isIndexPresent) {
133099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk                Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
134a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk                indexBuffers[pCount].set(indexAlloc);
135099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            }
136099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        }
137099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    }
138099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
139a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    Mesh *mesh = new Mesh(rsc, vertexBuffersCount, primitivesCount);
140a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mesh->setName(name.string(), name.size());
141a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
142a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        mesh->setVertexBuffer(vertexBuffers[vCount].get(), vCount);
14354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
144a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
145a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        mesh->setPrimitive(indexBuffers[pCount].get(), primitives[pCount], pCount);
14654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
14754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
148a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    // Cleanup
149a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (vertexBuffersCount) {
150a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] vertexBuffers;
15154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
152a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (primitivesCount) {
153a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] indexBuffers;
154a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] primitives;
15554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
15654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
157a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
158a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mesh->init();
159a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mesh->uploadAll(rsc);
160a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#endif
161a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    return mesh;
162a89371c6f144b9049efe7689105feee2c4a38384Jason Sams}
163a89371c6f144b9049efe7689105feee2c4a38384Jason Sams
164a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
165a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
166afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Mesh::render(Context *rsc) const {
167a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
1684e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        renderPrimitive(rsc, ct);
1694e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
1704e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
171fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
1724e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchoukvoid Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
173a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (primIndex >= mHal.state.primitivesCount) {
1744e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        LOGE("Invalid primitive index");
1754e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        return;
1764e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
177fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
178a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    Primitive_t *prim = mHal.state.primitives[primIndex];
179fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
1804e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    if (prim->mIndexBuffer.get()) {
1814e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        renderPrimitiveRange(rsc, primIndex, 0, prim->mIndexBuffer->getType()->getDimX());
1824e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        return;
1834e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
184fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
185a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    renderPrimitiveRange(rsc, primIndex, 0, mHal.state.vertexBuffers[0]->getType()->getDimX());
1864e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
187fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
188afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
189a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (len < 1 || primIndex >= mHal.state.primitivesCount) {
19054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        LOGE("Invalid mesh or parameters");
1914e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        return;
1924e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
1934e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
194a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
195a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        mHal.state.vertexBuffers[ct]->uploadCheck(rsc);
19654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
1974e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
198a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    Primitive_t *prim = mHal.state.primitives[primIndex];
1994e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    if (prim->mIndexBuffer.get()) {
2004e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        prim->mIndexBuffer->uploadCheck(rsc);
2014e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
202a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    rsc->checkError("Mesh::renderPrimitiveRange upload check");
2034e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
204a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mRSC->mHal.funcs.mesh.draw(mRSC, this, primIndex, start, len);
205a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    rsc->checkError("Mesh::renderPrimitiveRange draw");
2064e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
207fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
208afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Mesh::uploadAll(Context *rsc) {
209a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct = 0; ct < mHal.state.vertexBuffersCount; ct ++) {
210a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        if (mHal.state.vertexBuffers[ct].get()) {
211a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            mHal.state.vertexBuffers[ct]->deferredUploadToBufferObject(rsc);
2124e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        }
2134e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
2144e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
215a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
216a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        if (mHal.state.primitives[ct]->mIndexBuffer.get()) {
217a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            mHal.state.primitives[ct]->mIndexBuffer->deferredUploadToBufferObject(rsc);
2184e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        }
2194e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
2204e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
2214e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
222ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchoukvoid Mesh::computeBBox() {
223ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    float *posPtr = NULL;
224ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    uint32_t vectorSize = 0;
225ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    uint32_t stride = 0;
226ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    uint32_t numVerts = 0;
227ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    // First we need to find the position ptr and stride
228a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
229a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        const Type *bufferType = mHal.state.vertexBuffers[ct]->getType();
230ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        const Element *bufferElem = bufferType->getElement();
231ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk
232ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
233afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (strcmp(bufferElem->getFieldName(ct), "position") == 0) {
234ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk                vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
235ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk                stride = bufferElem->getSizeBytes() / sizeof(float);
236ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk                uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
237a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk                posPtr = (float*)((uint8_t*)mHal.state.vertexBuffers[ct]->getPtr() + offset);
238ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk                numVerts = bufferType->getDimX();
239ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk                break;
240ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk            }
241ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        }
242afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        if (posPtr) {
243ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk            break;
244ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        }
245ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    }
246ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk
247ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
248ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
249afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!posPtr) {
250ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        LOGE("Unable to compute bounding box");
251ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
252ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
253ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        return;
254ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    }
255ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk
256afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    for (uint32_t i = 0; i < numVerts; i ++) {
257afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        for (uint32_t v = 0; v < vectorSize; v ++) {
258ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk            mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
259ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk            mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
260ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        }
261ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        posPtr += stride;
262ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    }
263ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk}
264ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk
2654e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouknamespace android {
2664e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouknamespace renderscript {
2674e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
268afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukRsMesh rsi_MeshCreate(Context *rsc, uint32_t vtxCount, uint32_t idxCount) {
269a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    Mesh *sm = new Mesh(rsc, vtxCount, idxCount);
2704e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    sm->incUserRef();
2714e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
2724e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    return sm;
2734e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
2744e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
275afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_MeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot) {
2764e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    Mesh *sm = static_cast<Mesh *>(mv);
277a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    rsAssert(slot < sm->mHal.state.vertexBuffersCount);
2784e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
279a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    sm->setVertexBuffer((Allocation *)va, slot);
2804e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
2814e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
282afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_MeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot) {
2834e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    Mesh *sm = static_cast<Mesh *>(mv);
284a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    rsAssert(slot < sm->mHal.state.primitivesCount);
2854e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
286a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    sm->setPrimitive((Allocation *)va, (RsPrimitive)primType, slot);
2874e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
2884e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
289afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_MeshInitVertexAttribs(Context *rsc, RsMesh mv) {
29054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    Mesh *sm = static_cast<Mesh *>(mv);
291a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    sm->init();
29254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk}
29354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
294dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}}
295dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk
296afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsaMeshGetVertexBufferCount(RsContext con, RsMesh mv, int32_t *numVtx) {
297d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    Mesh *sm = static_cast<Mesh *>(mv);
298a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    *numVtx = sm->mHal.state.vertexBuffersCount;
299d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk}
300d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
301afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsaMeshGetIndexCount(RsContext con, RsMesh mv, int32_t *numIdx) {
302d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    Mesh *sm = static_cast<Mesh *>(mv);
303a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    *numIdx = sm->mHal.state.primitivesCount;
304d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk}
305d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
306afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsaMeshGetVertices(RsContext con, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount) {
307d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    Mesh *sm = static_cast<Mesh *>(mv);
308a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    rsAssert(vtxDataCount == sm->mHal.state.vertexBuffersCount);
309d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
310afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    for (uint32_t ct = 0; ct < vtxDataCount; ct ++) {
311a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        vtxData[ct] = sm->mHal.state.vertexBuffers[ct].get();
312a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        sm->mHal.state.vertexBuffers[ct]->incUserRef();
313d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    }
314d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk}
315d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
316afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsaMeshGetIndices(RsContext con, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount) {
317d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    Mesh *sm = static_cast<Mesh *>(mv);
318a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    rsAssert(idxDataCount == sm->mHal.state.primitivesCount);
319d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
320afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    for (uint32_t ct = 0; ct < idxDataCount; ct ++) {
321a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        va[ct] = sm->mHal.state.primitives[ct]->mIndexBuffer.get();
322a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        primType[ct] = sm->mHal.state.primitives[ct]->mPrimitive;
323a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        if (sm->mHal.state.primitives[ct]->mIndexBuffer.get()) {
324a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            sm->mHal.state.primitives[ct]->mIndexBuffer->incUserRef();
325d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk        }
326d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    }
327d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk}
328099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
329099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk#endif
330