Home | History | Annotate | Download | only in driver
      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 #include <string>
     30 
     31 using android::renderscript::Allocation;
     32 using android::renderscript::Context;
     33 using android::renderscript::Element;
     34 using android::renderscript::Mesh;
     35 
     36 RsdMeshObj::RsdMeshObj(const Context *rsc, const Mesh *rsMesh) {
     37     mRSMesh = rsMesh;
     38 
     39     mAttribs = nullptr;
     40     mAttribAllocationIndex = nullptr;
     41     mGLPrimitives = nullptr;
     42 
     43     mAttribCount = 0;
     44 }
     45 
     46 RsdMeshObj::~RsdMeshObj() {
     47     if (mAttribs) {
     48         delete[] mAttribs;
     49         delete[] mAttribAllocationIndex;
     50     }
     51     if (mGLPrimitives) {
     52         delete[] mGLPrimitives;
     53     }
     54 }
     55 
     56 bool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) {
     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->mHal.state.fields[fieldIdx]->mHal.state.dataType;
     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->mHal.state.fieldArraySizes[fieldIdx];
     68     if (arraySize != 1) {
     69         return false;
     70     }
     71 
     72     return true;
     73 }
     74 
     75 bool RsdMeshObj::init(const Context *rsc) {
     76 
     77     updateGLPrimitives(rsc);
     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->mHal.state.fieldsCount; ct++) {
     84             if (isValidGLComponent(elem, ct)) {
     85                 mAttribCount ++;
     86             }
     87         }
     88     }
     89 
     90     if (mAttribs) {
     91         delete [] mAttribs;
     92         delete [] mAttribAllocationIndex;
     93         mAttribs = nullptr;
     94         mAttribAllocationIndex = nullptr;
     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->mHal.state.elementSizeBytes;
    107         for (uint32_t fieldI=0; fieldI < elem->mHal.state.fieldsCount; fieldI++) {
    108             const Element *f = elem->mHal.state.fields[fieldI];
    109 
    110             if (!isValidGLComponent(elem, fieldI)) {
    111                 continue;
    112             }
    113 
    114             mAttribs[userNum].size = f->mHal.state.vectorSize;
    115             mAttribs[userNum].offset = elem->mHal.state.fieldOffsetBytes[fieldI];
    116             mAttribs[userNum].type = rsdTypeToGLType(f->mHal.state.dataType);
    117             mAttribs[userNum].normalized = f->mHal.state.dataType != RS_TYPE_FLOAT_32;
    118             mAttribs[userNum].stride = stride;
    119             std::string tmp(RS_SHADER_ATTR);
    120             tmp.append(elem->mHal.state.fieldNames[fieldI]);
    121             mAttribs[userNum].name = tmp;
    122 
    123             // Remember which allocation this attribute came from
    124             mAttribAllocationIndex[userNum] = ct;
    125             userNum ++;
    126         }
    127     }
    128 
    129     return true;
    130 }
    131 
    132 void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex,
    133                                       size_t start, uint32_t len) const {
    134     if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) {
    135         rsc->setError(RS_ERROR_FATAL_DRIVER, "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];
    141         DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
    142         if (drv->uploadDeferred) {
    143             rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT);
    144         }
    145     }
    146 
    147     // update attributes with either buffer information or data ptr based on their current state
    148     for (uint32_t ct=0; ct < mAttribCount; ct++) {
    149         uint32_t allocIndex = mAttribAllocationIndex[ct];
    150         Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex];
    151         DrvAllocation *drvAlloc = (DrvAllocation *)alloc->mHal.drv;
    152 
    153         if (drvAlloc->bufferID) {
    154             mAttribs[ct].buffer = drvAlloc->bufferID;
    155             mAttribs[ct].ptr = nullptr;
    156         } else {
    157             mAttribs[ct].buffer = 0;
    158             mAttribs[ct].ptr = (const uint8_t*)alloc->mHal.drvState.lod[0].mallocPtr;
    159         }
    160     }
    161 
    162     RsdVertexArray va(mAttribs, mAttribCount);
    163     va.setup(rsc);
    164 
    165     const Allocation *idxAlloc = mRSMesh->mHal.state.indexBuffers[primIndex];
    166     if (idxAlloc) {
    167         DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv;
    168         if (drvAlloc->uploadDeferred) {
    169             rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT);
    170         }
    171 
    172         if (drvAlloc->bufferID) {
    173             RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID);
    174             RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT,
    175                         (uint16_t *)(start * 2));
    176         } else {
    177             RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, 0);
    178             RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT,
    179                         idxAlloc->mHal.drvState.lod[0].mallocPtr);
    180         }
    181     } else {
    182         RSD_CALL_GL(glDrawArrays, mGLPrimitives[primIndex], start, len);
    183     }
    184 
    185     rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange");
    186 }
    187 
    188 void RsdMeshObj::updateGLPrimitives(const Context *rsc) {
    189     mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount];
    190     for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) {
    191         switch (mRSMesh->mHal.state.primitives[i]) {
    192             case RS_PRIMITIVE_POINT:          mGLPrimitives[i] = GL_POINTS; break;
    193             case RS_PRIMITIVE_LINE:           mGLPrimitives[i] = GL_LINES; break;
    194             case RS_PRIMITIVE_LINE_STRIP:     mGLPrimitives[i] = GL_LINE_STRIP; break;
    195             case RS_PRIMITIVE_TRIANGLE:       mGLPrimitives[i] = GL_TRIANGLES; break;
    196             case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break;
    197             case RS_PRIMITIVE_TRIANGLE_FAN:   mGLPrimitives[i] = GL_TRIANGLE_FAN; break;
    198             default: rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh primitive"); break;
    199         }
    200     }
    201 }
    202