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