1a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk/*
2a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * Copyright (C) 2011 The Android Open Source Project
3a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk *
4a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License");
5a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * you may not use this file except in compliance with the License.
6a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * You may obtain a copy of the License at
7a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk *
8a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk *      http://www.apache.org/licenses/LICENSE-2.0
9a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk *
10a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * Unless required by applicable law or agreed to in writing, software
11a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS,
12a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * See the License for the specific language governing permissions and
14a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * limitations under the License.
15a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk */
16a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
17a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <GLES/gl.h>
18a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <GLES2/gl2.h>
19a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <GLES/glext.h>
20a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
21a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <rs_hal.h>
22a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <rsContext.h>
23a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include <rsMesh.h>
24a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
25eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdAllocation.h"
26a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdMeshObj.h"
27c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk#include "rsdGL.h"
28a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
2982e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wang#include <string>
3082e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wang
31e939ce7e3b609ee53d73c2b48c5ff8f03b4579a3Chih-Hung Hsiehusing android::renderscript::Allocation;
32e939ce7e3b609ee53d73c2b48c5ff8f03b4579a3Chih-Hung Hsiehusing android::renderscript::Context;
33e939ce7e3b609ee53d73c2b48c5ff8f03b4579a3Chih-Hung Hsiehusing android::renderscript::Element;
34e939ce7e3b609ee53d73c2b48c5ff8f03b4579a3Chih-Hung Hsiehusing android::renderscript::Mesh;
35a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
36a04e30dbb5ab11592b03666bb3d102070759c58eAlex SakhartchoukRsdMeshObj::RsdMeshObj(const Context *rsc, const Mesh *rsMesh) {
37a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mRSMesh = rsMesh;
38a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
3944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mAttribs = nullptr;
4044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mAttribAllocationIndex = nullptr;
4144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mGLPrimitives = nullptr;
42a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
43a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mAttribCount = 0;
44a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk}
45a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
46a04e30dbb5ab11592b03666bb3d102070759c58eAlex SakhartchoukRsdMeshObj::~RsdMeshObj() {
47a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (mAttribs) {
48a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] mAttribs;
49a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] mAttribAllocationIndex;
50a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
51a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (mGLPrimitives) {
52a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete[] mGLPrimitives;
53a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
54a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk}
55a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
56a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchoukbool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) {
57a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
58a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    // Filter rs types accordingly
594a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk    RsDataType dt = elem->mHal.state.fields[fieldIdx]->mHal.state.dataType;
60a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
61a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
62a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        dt != RS_TYPE_SIGNED_16) {
63a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        return false;
64a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
65a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
66a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    // Now make sure they are not arrays
674a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk    uint32_t arraySize = elem->mHal.state.fieldArraySizes[fieldIdx];
68a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (arraySize != 1) {
69a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        return false;
70a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
71a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
72a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    return true;
73a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk}
74a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
75c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchoukbool RsdMeshObj::init(const Context *rsc) {
76a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
77c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchouk    updateGLPrimitives(rsc);
78a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
79a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    // Count the number of gl attrs to initialize
80a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mAttribCount = 0;
81a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
82a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
834a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk        for (uint32_t ct=0; ct < elem->mHal.state.fieldsCount; ct++) {
84a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            if (isValidGLComponent(elem, ct)) {
85a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk                mAttribCount ++;
86a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            }
87a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        }
88a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
89a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
90a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (mAttribs) {
91a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete [] mAttribs;
92a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        delete [] mAttribAllocationIndex;
9344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        mAttribs = nullptr;
9444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        mAttribAllocationIndex = nullptr;
95a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
96a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (!mAttribCount) {
97a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        return false;
98a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
99a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
100a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mAttribs = new RsdVertexArray::Attrib[mAttribCount];
101a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mAttribAllocationIndex = new uint32_t[mAttribCount];
102a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
103a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    uint32_t userNum = 0;
104a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
105a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
1064a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk        uint32_t stride = elem->mHal.state.elementSizeBytes;
1074a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk        for (uint32_t fieldI=0; fieldI < elem->mHal.state.fieldsCount; fieldI++) {
1084a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk            const Element *f = elem->mHal.state.fields[fieldI];
109a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
110a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            if (!isValidGLComponent(elem, fieldI)) {
111a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk                continue;
112a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            }
113a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
1144a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk            mAttribs[userNum].size = f->mHal.state.vectorSize;
1154a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk            mAttribs[userNum].offset = elem->mHal.state.fieldOffsetBytes[fieldI];
1164a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk            mAttribs[userNum].type = rsdTypeToGLType(f->mHal.state.dataType);
1174a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk            mAttribs[userNum].normalized = f->mHal.state.dataType != RS_TYPE_FLOAT_32;
118a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            mAttribs[userNum].stride = stride;
11982e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wang            std::string tmp(RS_SHADER_ATTR);
1204a43e3ea8a0328c56ace0af1869b4c8c781a7b26Alex Sakhartchouk            tmp.append(elem->mHal.state.fieldNames[fieldI]);
12182e135c4bbe18855d8ed02632bb074f8da0b96e0Miao Wang            mAttribs[userNum].name = tmp;
122a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
123a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            // Remember which allocation this attribute came from
124a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            mAttribAllocationIndex[userNum] = ct;
125a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            userNum ++;
126a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        }
127a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
128a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
129a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    return true;
130a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk}
131a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
1322382aba4a55c6ae74789c478eead8fbd96593321Jason Samsvoid RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex,
133e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray                                      size_t start, uint32_t len) const {
134a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) {
135c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchouk        rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh or parameters");
136a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        return;
137a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
138a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
139eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
140064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct];
141a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
142a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        if (drv->uploadDeferred) {
143a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT);
144a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        }
145eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
146eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
147a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    // update attributes with either buffer information or data ptr based on their current state
148a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct=0; ct < mAttribCount; ct++) {
149a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        uint32_t allocIndex = mAttribAllocationIndex[ct];
150064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex];
151eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        DrvAllocation *drvAlloc = (DrvAllocation *)alloc->mHal.drv;
152eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
153eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (drvAlloc->bufferID) {
154eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            mAttribs[ct].buffer = drvAlloc->bufferID;
15544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes            mAttribs[ct].ptr = nullptr;
156a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        } else {
157a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            mAttribs[ct].buffer = 0;
158709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mAttribs[ct].ptr = (const uint8_t*)alloc->mHal.drvState.lod[0].mallocPtr;
159a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        }
160a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
161a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
162a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    RsdVertexArray va(mAttribs, mAttribCount);
163c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk    va.setup(rsc);
164a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
165064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    const Allocation *idxAlloc = mRSMesh->mHal.state.indexBuffers[primIndex];
166eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (idxAlloc) {
167eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv;
168a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        if (drvAlloc->uploadDeferred) {
169a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT);
170a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        }
171eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
172eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (drvAlloc->bufferID) {
1732382aba4a55c6ae74789c478eead8fbd96593321Jason Sams            RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID);
1742382aba4a55c6ae74789c478eead8fbd96593321Jason Sams            RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT,
1752382aba4a55c6ae74789c478eead8fbd96593321Jason Sams                        (uint16_t *)(start * 2));
176eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        } else {
1772382aba4a55c6ae74789c478eead8fbd96593321Jason Sams            RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, 0);
1782382aba4a55c6ae74789c478eead8fbd96593321Jason Sams            RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT,
179709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                        idxAlloc->mHal.drvState.lod[0].mallocPtr);
180eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
181a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    } else {
1822382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glDrawArrays, mGLPrimitives[primIndex], start, len);
183a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
184a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
185c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk    rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange");
186a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk}
187a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
188c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchoukvoid RsdMeshObj::updateGLPrimitives(const Context *rsc) {
189a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount];
190a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) {
191064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        switch (mRSMesh->mHal.state.primitives[i]) {
192a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            case RS_PRIMITIVE_POINT:          mGLPrimitives[i] = GL_POINTS; break;
193a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            case RS_PRIMITIVE_LINE:           mGLPrimitives[i] = GL_LINES; break;
194a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            case RS_PRIMITIVE_LINE_STRIP:     mGLPrimitives[i] = GL_LINE_STRIP; break;
195a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            case RS_PRIMITIVE_TRIANGLE:       mGLPrimitives[i] = GL_TRIANGLES; break;
196a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break;
197a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk            case RS_PRIMITIVE_TRIANGLE_FAN:   mGLPrimitives[i] = GL_TRIANGLE_FAN; break;
198c0a65425f8eb3573b1abd2a48292ca953c0a8590Alex Sakhartchouk            default: rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh primitive"); break;
199a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        }
200a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    }
201a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk}
202