rsdMeshObj.cpp revision a04e30dbb5ab11592b03666bb3d102070759c58e
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 "rsdMeshObj.h" 26 27using namespace android; 28using namespace android::renderscript; 29 30RsdMeshObj::RsdMeshObj(const Context *rsc, const Mesh *rsMesh) { 31 mRSMesh = rsMesh; 32 33 mAttribs = NULL; 34 mAttribAllocationIndex = NULL; 35 mGLPrimitives = NULL; 36 37 mAttribCount = 0; 38} 39 40RsdMeshObj::~RsdMeshObj() { 41 if (mAttribs) { 42 delete[] mAttribs; 43 delete[] mAttribAllocationIndex; 44 } 45 if (mGLPrimitives) { 46 delete[] mGLPrimitives; 47 } 48} 49 50bool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) { 51 // Do not create attribs for padding 52 if (elem->getFieldName(fieldIdx)[0] == '#') { 53 return false; 54 } 55 56 // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted. 57 // Filter rs types accordingly 58 RsDataType dt = elem->getField(fieldIdx)->getComponent().getType(); 59 if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 && 60 dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 && 61 dt != RS_TYPE_SIGNED_16) { 62 return false; 63 } 64 65 // Now make sure they are not arrays 66 uint32_t arraySize = elem->getFieldArraySize(fieldIdx); 67 if (arraySize != 1) { 68 return false; 69 } 70 71 return true; 72} 73 74bool RsdMeshObj::init() { 75 76 updateGLPrimitives(); 77 78 // Count the number of gl attrs to initialize 79 mAttribCount = 0; 80 for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { 81 const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement(); 82 for (uint32_t ct=0; ct < elem->getFieldCount(); ct++) { 83 if (isValidGLComponent(elem, ct)) { 84 mAttribCount ++; 85 } 86 } 87 } 88 89 if (mAttribs) { 90 delete [] mAttribs; 91 delete [] mAttribAllocationIndex; 92 mAttribs = NULL; 93 mAttribAllocationIndex = NULL; 94 } 95 if (!mAttribCount) { 96 return false; 97 } 98 99 mAttribs = new RsdVertexArray::Attrib[mAttribCount]; 100 mAttribAllocationIndex = new uint32_t[mAttribCount]; 101 102 uint32_t userNum = 0; 103 for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { 104 const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement(); 105 uint32_t stride = elem->getSizeBytes(); 106 for (uint32_t fieldI=0; fieldI < elem->getFieldCount(); fieldI++) { 107 const Component &c = elem->getField(fieldI)->getComponent(); 108 109 if (!isValidGLComponent(elem, fieldI)) { 110 continue; 111 } 112 113 mAttribs[userNum].size = c.getVectorSize(); 114 mAttribs[userNum].offset = elem->getFieldOffsetBytes(fieldI); 115 mAttribs[userNum].type = c.getGLType(); 116 mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized(); 117 mAttribs[userNum].stride = stride; 118 String8 tmp(RS_SHADER_ATTR); 119 tmp.append(elem->getFieldName(fieldI)); 120 mAttribs[userNum].name.setTo(tmp.string()); 121 122 // Remember which allocation this attribute came from 123 mAttribAllocationIndex[userNum] = ct; 124 userNum ++; 125 } 126 } 127 128 return true; 129} 130 131void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const { 132 if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) { 133 LOGE("Invalid mesh or parameters"); 134 return; 135 } 136 137 rsc->checkError("Mesh::renderPrimitiveRange 1"); 138 // update attributes with either buffer information or data ptr based on their current state 139 for (uint32_t ct=0; ct < mAttribCount; ct++) { 140 uint32_t allocIndex = mAttribAllocationIndex[ct]; 141 Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex].get(); 142 if (alloc->getIsBufferObject() && alloc->getBufferObjectID()) { 143 mAttribs[ct].buffer = alloc->getBufferObjectID(); 144 mAttribs[ct].ptr = NULL; 145 } else { 146 mAttribs[ct].buffer = 0; 147 mAttribs[ct].ptr = (const uint8_t*)alloc->getPtr(); 148 } 149 } 150 151 RsdVertexArray va(mAttribs, mAttribCount); 152 va.setupGL2(rsc); 153 154 rsc->checkError("Mesh::renderPrimitiveRange 2"); 155 Mesh::Primitive_t *prim = mRSMesh->mHal.state.primitives[primIndex]; 156 if (prim->mIndexBuffer.get()) { 157 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prim->mIndexBuffer->getBufferObjectID()); 158 glDrawElements(mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2)); 159 } else { 160 glDrawArrays(mGLPrimitives[primIndex], start, len); 161 } 162 163 rsc->checkError("Mesh::renderPrimitiveRange"); 164} 165 166void RsdMeshObj::updateGLPrimitives() { 167 mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount]; 168 for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) { 169 switch (mRSMesh->mHal.state.primitives[i]->mPrimitive) { 170 case RS_PRIMITIVE_POINT: mGLPrimitives[i] = GL_POINTS; break; 171 case RS_PRIMITIVE_LINE: mGLPrimitives[i] = GL_LINES; break; 172 case RS_PRIMITIVE_LINE_STRIP: mGLPrimitives[i] = GL_LINE_STRIP; break; 173 case RS_PRIMITIVE_TRIANGLE: mGLPrimitives[i] = GL_TRIANGLES; break; 174 case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break; 175 case RS_PRIMITIVE_TRIANGLE_FAN: mGLPrimitives[i] = GL_TRIANGLE_FAN; break; 176 } 177 } 178} 179