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 32 RsdMeshObj::RsdMeshObj(const Context *rsc, const Mesh *rsMesh) { 33 mRSMesh = rsMesh; 34 35 mAttribs = NULL; 36 mAttribAllocationIndex = NULL; 37 mGLPrimitives = NULL; 38 39 mAttribCount = 0; 40 } 41 42 RsdMeshObj::~RsdMeshObj() { 43 if (mAttribs) { 44 delete[] mAttribs; 45 delete[] mAttribAllocationIndex; 46 } 47 if (mGLPrimitives) { 48 delete[] mGLPrimitives; 49 } 50 } 51 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 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 = NULL; 90 mAttribAllocationIndex = NULL; 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.setTo(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 128 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 = NULL; 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 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