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