1 /*
2 * Copyright (C) 2011 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
17 #include <GLES/gl.h>
18 #include <GLES2/gl2.h>
19 #include <GLES/glext.h>
20
21 #include <rs_hal.h>
22 #include <rsContext.h>
23 #include <rsMesh.h>
24
25 #include "rsdAllocation.h"
26 #include "rsdMeshObj.h"
27 #include "rsdGL.h"
28
29 using namespace android;
30 using namespace android::renderscript;
31
RsdMeshObj(const Context * rsc,const Mesh * rsMesh)32 RsdMeshObj::RsdMeshObj(const Context *rsc, const Mesh *rsMesh) {
33 mRSMesh = rsMesh;
34
35 mAttribs = nullptr;
36 mAttribAllocationIndex = nullptr;
37 mGLPrimitives = nullptr;
38
39 mAttribCount = 0;
40 }
41
~RsdMeshObj()42 RsdMeshObj::~RsdMeshObj() {
43 if (mAttribs) {
44 delete[] mAttribs;
45 delete[] mAttribAllocationIndex;
46 }
47 if (mGLPrimitives) {
48 delete[] mGLPrimitives;
49 }
50 }
51
isValidGLComponent(const Element * elem,uint32_t fieldIdx)52 bool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) {
53 // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
54 // Filter rs types accordingly
55 RsDataType dt = elem->mHal.state.fields[fieldIdx]->mHal.state.dataType;
56 if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
57 dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
58 dt != RS_TYPE_SIGNED_16) {
59 return false;
60 }
61
62 // Now make sure they are not arrays
63 uint32_t arraySize = elem->mHal.state.fieldArraySizes[fieldIdx];
64 if (arraySize != 1) {
65 return false;
66 }
67
68 return true;
69 }
70
init(const Context * rsc)71 bool RsdMeshObj::init(const Context *rsc) {
72
73 updateGLPrimitives(rsc);
74
75 // Count the number of gl attrs to initialize
76 mAttribCount = 0;
77 for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
78 const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
79 for (uint32_t ct=0; ct < elem->mHal.state.fieldsCount; ct++) {
80 if (isValidGLComponent(elem, ct)) {
81 mAttribCount ++;
82 }
83 }
84 }
85
86 if (mAttribs) {
87 delete [] mAttribs;
88 delete [] mAttribAllocationIndex;
89 mAttribs = nullptr;
90 mAttribAllocationIndex = nullptr;
91 }
92 if (!mAttribCount) {
93 return false;
94 }
95
96 mAttribs = new RsdVertexArray::Attrib[mAttribCount];
97 mAttribAllocationIndex = new uint32_t[mAttribCount];
98
99 uint32_t userNum = 0;
100 for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
101 const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
102 uint32_t stride = elem->mHal.state.elementSizeBytes;
103 for (uint32_t fieldI=0; fieldI < elem->mHal.state.fieldsCount; fieldI++) {
104 const Element *f = elem->mHal.state.fields[fieldI];
105
106 if (!isValidGLComponent(elem, fieldI)) {
107 continue;
108 }
109
110 mAttribs[userNum].size = f->mHal.state.vectorSize;
111 mAttribs[userNum].offset = elem->mHal.state.fieldOffsetBytes[fieldI];
112 mAttribs[userNum].type = rsdTypeToGLType(f->mHal.state.dataType);
113 mAttribs[userNum].normalized = f->mHal.state.dataType != RS_TYPE_FLOAT_32;
114 mAttribs[userNum].stride = stride;
115 String8 tmp(RS_SHADER_ATTR);
116 tmp.append(elem->mHal.state.fieldNames[fieldI]);
117 mAttribs[userNum].name = tmp.string();
118
119 // Remember which allocation this attribute came from
120 mAttribAllocationIndex[userNum] = ct;
121 userNum ++;
122 }
123 }
124
125 return true;
126 }
127
renderPrimitiveRange(const Context * rsc,uint32_t primIndex,size_t start,uint32_t len) const128 void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex,
129 size_t start, uint32_t len) const {
130 if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) {
131 rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh or parameters");
132 return;
133 }
134
135 for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
136 const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct];
137 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
138 if (drv->uploadDeferred) {
139 rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT);
140 }
141 }
142
143 // update attributes with either buffer information or data ptr based on their current state
144 for (uint32_t ct=0; ct < mAttribCount; ct++) {
145 uint32_t allocIndex = mAttribAllocationIndex[ct];
146 Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex];
147 DrvAllocation *drvAlloc = (DrvAllocation *)alloc->mHal.drv;
148
149 if (drvAlloc->bufferID) {
150 mAttribs[ct].buffer = drvAlloc->bufferID;
151 mAttribs[ct].ptr = nullptr;
152 } else {
153 mAttribs[ct].buffer = 0;
154 mAttribs[ct].ptr = (const uint8_t*)alloc->mHal.drvState.lod[0].mallocPtr;
155 }
156 }
157
158 RsdVertexArray va(mAttribs, mAttribCount);
159 va.setup(rsc);
160
161 const Allocation *idxAlloc = mRSMesh->mHal.state.indexBuffers[primIndex];
162 if (idxAlloc) {
163 DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv;
164 if (drvAlloc->uploadDeferred) {
165 rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT);
166 }
167
168 if (drvAlloc->bufferID) {
169 RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID);
170 RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT,
171 (uint16_t *)(start * 2));
172 } else {
173 RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, 0);
174 RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT,
175 idxAlloc->mHal.drvState.lod[0].mallocPtr);
176 }
177 } else {
178 RSD_CALL_GL(glDrawArrays, mGLPrimitives[primIndex], start, len);
179 }
180
181 rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange");
182 }
183
updateGLPrimitives(const Context * rsc)184 void RsdMeshObj::updateGLPrimitives(const Context *rsc) {
185 mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount];
186 for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) {
187 switch (mRSMesh->mHal.state.primitives[i]) {
188 case RS_PRIMITIVE_POINT: mGLPrimitives[i] = GL_POINTS; break;
189 case RS_PRIMITIVE_LINE: mGLPrimitives[i] = GL_LINES; break;
190 case RS_PRIMITIVE_LINE_STRIP: mGLPrimitives[i] = GL_LINE_STRIP; break;
191 case RS_PRIMITIVE_TRIANGLE: mGLPrimitives[i] = GL_TRIANGLES; break;
192 case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break;
193 case RS_PRIMITIVE_TRIANGLE_FAN: mGLPrimitives[i] = GL_TRIANGLE_FAN; break;
194 default: rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh primitive"); break;
195 }
196 }
197 }
198