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