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