rsdMeshObj.cpp revision a614ae175bbf97201b5e18984d814a1d3e86faa8
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 29using namespace android; 30using namespace android::renderscript; 31 32RsdMeshObj::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 42RsdMeshObj::~RsdMeshObj() { 43 if (mAttribs) { 44 delete[] mAttribs; 45 delete[] mAttribAllocationIndex; 46 } 47 if (mGLPrimitives) { 48 delete[] mGLPrimitives; 49 } 50} 51 52bool 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 76bool 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 133void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const { 134 if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) { 135 LOGE("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].get(); 141 rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT); 142 } 143 144 // update attributes with either buffer information or data ptr based on their current state 145 for (uint32_t ct=0; ct < mAttribCount; ct++) { 146 uint32_t allocIndex = mAttribAllocationIndex[ct]; 147 Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex].get(); 148 DrvAllocation *drvAlloc = (DrvAllocation *)alloc->mHal.drv; 149 150 if (drvAlloc->bufferID) { 151 mAttribs[ct].buffer = drvAlloc->bufferID; 152 mAttribs[ct].ptr = NULL; 153 } else { 154 mAttribs[ct].buffer = 0; 155 mAttribs[ct].ptr = (const uint8_t*)drvAlloc->mallocPtr; 156 } 157 } 158 159 RsdVertexArray va(mAttribs, mAttribCount); 160 va.setup(rsc); 161 162 Mesh::Primitive_t *prim = mRSMesh->mHal.state.primitives[primIndex]; 163 const Allocation *idxAlloc = prim->mIndexBuffer.get(); 164 if (idxAlloc) { 165 DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv; 166 rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT); 167 168 if (drvAlloc->bufferID) { 169 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID); 170 glDrawElements(mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2)); 171 } else { 172 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 173 glDrawElements(mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, drvAlloc->mallocPtr); 174 } 175 } else { 176 glDrawArrays(mGLPrimitives[primIndex], start, len); 177 } 178 179 rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange"); 180} 181 182void RsdMeshObj::updateGLPrimitives() { 183 mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount]; 184 for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) { 185 switch (mRSMesh->mHal.state.primitives[i]->mPrimitive) { 186 case RS_PRIMITIVE_POINT: mGLPrimitives[i] = GL_POINTS; break; 187 case RS_PRIMITIVE_LINE: mGLPrimitives[i] = GL_LINES; break; 188 case RS_PRIMITIVE_LINE_STRIP: mGLPrimitives[i] = GL_LINE_STRIP; break; 189 case RS_PRIMITIVE_TRIANGLE: mGLPrimitives[i] = GL_TRIANGLES; break; 190 case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break; 191 case RS_PRIMITIVE_TRIANGLE_FAN: mGLPrimitives[i] = GL_TRIANGLE_FAN; break; 192 } 193 } 194} 195