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"
184edf030cbb7c6ac08dc563335c2af73c20f6e2e5Alex Sakhartchouk#include "rsMesh.h"
19e23d239828a229eb7d4d33c9630070f0a87833e1Alex Sakhartchouk#include "rs.h"
20fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
2111496ac131bb691edf5bdcab3029dceef5c1e4e1Chih-Hung Hsiehnamespace android {
2211496ac131bb691edf5bdcab3029dceef5c1e4e1Chih-Hung Hsiehnamespace renderscript {
23a89371c6f144b9049efe7689105feee2c4a38384Jason Sams
24afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukMesh::Mesh(Context *rsc) : ObjectBase(rsc) {
2544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mHal.drv = nullptr;
2644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mHal.state.primitives = nullptr;
27a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.primitivesCount = 0;
2844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mHal.state.indexBuffers = nullptr;
29064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    mHal.state.indexBuffersCount = 0;
3044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mHal.state.vertexBuffers = nullptr;
31a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.vertexBuffersCount = 0;
32a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mInitialized = false;
33064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk
3444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mVertexBuffers = nullptr;
3544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mIndexBuffers = nullptr;
36a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk}
3754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
38a04e30dbb5ab11592b03666bb3d102070759c58eAlex SakhartchoukMesh::Mesh(Context *rsc,
39a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk           uint32_t vertexBuffersCount,
40a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk           uint32_t primitivesCount) : ObjectBase(rsc) {
4144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mHal.drv = nullptr;
42a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.primitivesCount = primitivesCount;
43064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    mHal.state.indexBuffersCount = primitivesCount;
44064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    mHal.state.primitives = new RsPrimitive[mHal.state.primitivesCount];
45064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    mHal.state.indexBuffers = new Allocation *[mHal.state.indexBuffersCount];
46a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
47064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        mHal.state.primitives[i] = RS_PRIMITIVE_POINT;
48064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    }
49064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    for (uint32_t i = 0; i < mHal.state.indexBuffersCount; i ++) {
5044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        mHal.state.indexBuffers[i] = nullptr;
51a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
52a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mHal.state.vertexBuffersCount = vertexBuffersCount;
53064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    mHal.state.vertexBuffers = new Allocation *[mHal.state.vertexBuffersCount];
54064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    for (uint32_t i = 0; i < mHal.state.vertexBuffersCount; i ++) {
5544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        mHal.state.vertexBuffers[i] = nullptr;
56064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    }
57064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk
58064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    mVertexBuffers = new ObjectBaseRef<Allocation>[mHal.state.vertexBuffersCount];
59064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    mIndexBuffers = new ObjectBaseRef<Allocation>[mHal.state.primitivesCount];
60a89371c6f144b9049efe7689105feee2c4a38384Jason Sams}
61a89371c6f144b9049efe7689105feee2c4a38384Jason Sams
62afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukMesh::~Mesh() {
63a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
64a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mRSC->mHal.funcs.mesh.destroy(mRSC, this);
65a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#endif
66a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
67064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    delete[] mHal.state.vertexBuffers;
68064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    delete[] mHal.state.primitives;
69064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    delete[] mHal.state.indexBuffers;
704e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
71064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    delete[] mVertexBuffers;
72064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    delete[] mIndexBuffers;
73a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk}
7454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
75a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchoukvoid Mesh::init() {
7677d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
77a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mRSC->mHal.funcs.mesh.init(mRSC, this);
78099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk#endif
79099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk}
80099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
81e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid Mesh::serialize(Context *rsc, OStream *stream) const {
82099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    // Need to identify ourselves
83099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    stream->addU32((uint32_t)getClassId());
8448ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    stream->addString(getName());
85099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
86099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    // Store number of vertex streams
87a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    stream->addU32(mHal.state.vertexBuffersCount);
88a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t vCount = 0; vCount < mHal.state.vertexBuffersCount; vCount ++) {
89e3150cfb3edb028407669e4a65e087eae77e718cJason Sams        mHal.state.vertexBuffers[vCount]->serialize(rsc, stream);
90099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    }
91099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
92a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    stream->addU32(mHal.state.primitivesCount);
93099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    // Store the primitives
94a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t pCount = 0; pCount < mHal.state.primitivesCount; pCount ++) {
95064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        stream->addU8((uint8_t)mHal.state.primitives[pCount]);
96099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
97064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        if (mHal.state.indexBuffers[pCount]) {
98099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            stream->addU32(1);
99e3150cfb3edb028407669e4a65e087eae77e718cJason Sams            mHal.state.indexBuffers[pCount]->serialize(rsc, stream);
100099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        } else {
101099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            stream->addU32(0);
102099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        }
103099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    }
104099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk}
105099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
106099d7d33e55afeb3399f6e8cf8d665223ca94939Alex SakhartchoukMesh *Mesh::createFromStream(Context *rsc, IStream *stream) {
107099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    // First make sure we are reading the correct object
108099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
109099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_MESH) {
110af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("mesh loading skipped due to invalid class id");
11144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
112099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    }
113099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
11448ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    const char *name = stream->loadString();
115099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
116a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    uint32_t vertexBuffersCount = stream->loadU32();
11744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    ObjectBaseRef<Allocation> *vertexBuffers = nullptr;
118a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (vertexBuffersCount) {
119a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        vertexBuffers = new ObjectBaseRef<Allocation>[vertexBuffersCount];
120099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
121a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
122099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
123a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            vertexBuffers[vCount].set(vertexAlloc);
124099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        }
125099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    }
126099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
127a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    uint32_t primitivesCount = stream->loadU32();
12844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    ObjectBaseRef<Allocation> *indexBuffers = nullptr;
12944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    RsPrimitive *primitives = nullptr;
130a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (primitivesCount) {
131a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        indexBuffers = new ObjectBaseRef<Allocation>[primitivesCount];
132a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        primitives = new RsPrimitive[primitivesCount];
133099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
134099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        // load all primitives
135a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
136a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            primitives[pCount] = (RsPrimitive)stream->loadU8();
137099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
138099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            // Check to see if the index buffer was stored
139099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            uint32_t isIndexPresent = stream->loadU32();
140099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            if (isIndexPresent) {
141099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk                Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
142a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk                indexBuffers[pCount].set(indexAlloc);
143099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk            }
144099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        }
145099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    }
146099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
147a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    Mesh *mesh = new Mesh(rsc, vertexBuffersCount, primitivesCount);
14848ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    mesh->assignName(name);
149a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
150a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        mesh->setVertexBuffer(vertexBuffers[vCount].get(), vCount);
15154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
152a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
153a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        mesh->setPrimitive(indexBuffers[pCount].get(), primitives[pCount], pCount);
15454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
15554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
156a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    // Cleanup
157a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (vertexBuffersCount) {
158a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] vertexBuffers;
15954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
160a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (primitivesCount) {
161a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] indexBuffers;
162a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] primitives;
16354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
16454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
165a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
166a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mesh->init();
167a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mesh->uploadAll(rsc);
168a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#endif
169a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    return mesh;
170a89371c6f144b9049efe7689105feee2c4a38384Jason Sams}
171a89371c6f144b9049efe7689105feee2c4a38384Jason Sams
172afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Mesh::render(Context *rsc) const {
173a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
1744e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        renderPrimitive(rsc, ct);
1754e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
1764e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
177fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
1784e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchoukvoid Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
179a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (primIndex >= mHal.state.primitivesCount) {
180af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Invalid primitive index");
1814e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        return;
1824e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
183fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
184064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    if (mHal.state.indexBuffers[primIndex]) {
185064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        renderPrimitiveRange(rsc, primIndex, 0, mHal.state.indexBuffers[primIndex]->getType()->getDimX());
1864e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        return;
1874e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
188fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
189a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    renderPrimitiveRange(rsc, primIndex, 0, mHal.state.vertexBuffers[0]->getType()->getDimX());
1904e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
191fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
192afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
193a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (len < 1 || primIndex >= mHal.state.primitivesCount) {
194af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Invalid mesh or parameters");
1954e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        return;
1964e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
1974e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
198a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mRSC->mHal.funcs.mesh.draw(mRSC, this, primIndex, start, len);
1994e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
200fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
201afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Mesh::uploadAll(Context *rsc) {
202a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct = 0; ct < mHal.state.vertexBuffersCount; ct ++) {
203064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        if (mHal.state.vertexBuffers[ct]) {
204064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk            rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.vertexBuffers[ct]);
2054e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        }
2064e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
2074e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
208a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
209064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        if (mHal.state.indexBuffers[ct]) {
210064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk            rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.indexBuffers[ct]);
2114e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk        }
2124e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    }
2134e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk}
2144e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
215e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid Mesh::computeBBox(Context *rsc) {
21644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    float *posPtr = nullptr;
217ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    uint32_t vectorSize = 0;
218ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    uint32_t stride = 0;
219ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    uint32_t numVerts = 0;
22044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    Allocation *posAlloc = nullptr;
221ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    // First we need to find the position ptr and stride
222a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
223a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        const Type *bufferType = mHal.state.vertexBuffers[ct]->getType();
224ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        const Element *bufferElem = bufferType->getElement();
225ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk
226ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
227afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (strcmp(bufferElem->getFieldName(ct), "position") == 0) {
228ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk                vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
229ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk                stride = bufferElem->getSizeBytes() / sizeof(float);
230ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk                uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
231807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams                posAlloc = mHal.state.vertexBuffers[ct];
232807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams                const uint8_t *bp = (const uint8_t *)rsc->mHal.funcs.allocation.lock1D(
233807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams                        rsc, posAlloc);
234807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams                posPtr = (float*)(bp + offset);
235ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk                numVerts = bufferType->getDimX();
236ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk                break;
237ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk            }
238ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        }
239afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        if (posPtr) {
240ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk            break;
241ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        }
242ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    }
243ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk
244ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
245ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
246afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!posPtr) {
247af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Unable to compute bounding box");
248ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
249ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
250ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        return;
251ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    }
252ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk
253afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    for (uint32_t i = 0; i < numVerts; i ++) {
254afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        for (uint32_t v = 0; v < vectorSize; v ++) {
255ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk            mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
256ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk            mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
257ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        }
258ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk        posPtr += stride;
259ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk    }
260807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
261807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    if (posAlloc) {
262807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsc->mHal.funcs.allocation.unlock1D(rsc, posAlloc);
263807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
264ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk}
265ba4aa5c768a498bc3fbb8cb5547b7a9ad6f4b771Alex Sakhartchouk
2669003e5674fb3b2a1442cd0cca899fdc3246debf8Alex SakhartchoukRsMesh rsi_MeshCreate(Context *rsc,
267b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                      RsAllocation * vtx, size_t vtxCount,
268b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                      RsAllocation * idx, size_t idxCount,
269b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                      uint32_t * primType, size_t primTypeCount) {
2709003e5674fb3b2a1442cd0cca899fdc3246debf8Alex Sakhartchouk    rsAssert(idxCount == primTypeCount);
271a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    Mesh *sm = new Mesh(rsc, vtxCount, idxCount);
2724e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk    sm->incUserRef();
2734e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
2749003e5674fb3b2a1442cd0cca899fdc3246debf8Alex Sakhartchouk    for (uint32_t i = 0; i < vtxCount; i ++) {
2759003e5674fb3b2a1442cd0cca899fdc3246debf8Alex Sakhartchouk        sm->setVertexBuffer((Allocation*)vtx[i], i);
2769003e5674fb3b2a1442cd0cca899fdc3246debf8Alex Sakhartchouk    }
2774e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
2789003e5674fb3b2a1442cd0cca899fdc3246debf8Alex Sakhartchouk    for (uint32_t i = 0; i < idxCount; i ++) {
2799003e5674fb3b2a1442cd0cca899fdc3246debf8Alex Sakhartchouk        sm->setPrimitive((Allocation*)idx[i], (RsPrimitive)primType[i], i);
2809003e5674fb3b2a1442cd0cca899fdc3246debf8Alex Sakhartchouk    }
2814e9a7a8ded109e16b163789274899447cef02642Alex Sakhartchouk
282a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    sm->init();
2839003e5674fb3b2a1442cd0cca899fdc3246debf8Alex Sakhartchouk
2849003e5674fb3b2a1442cd0cca899fdc3246debf8Alex Sakhartchouk    return sm;
28554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk}
28654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
28711496ac131bb691edf5bdcab3029dceef5c1e4e1Chih-Hung Hsieh} // namespace renderscript
28811496ac131bb691edf5bdcab3029dceef5c1e4e1Chih-Hung Hsieh} // namespace android
289