blob: 8f072a59413b04558040c5dbb74ad45daf3b9b95 [file] [log] [blame]
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -07001/*
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
Jason Samseb4fe182011-05-26 16:33:01 -070025#include "rsdAllocation.h"
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070026#include "rsdMeshObj.h"
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -070027#include "rsdGL.h"
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070028
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) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070053 // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
54 // Filter rs types accordingly
Alex Sakhartchouk4a43e3e2011-12-28 13:47:05 -080055 RsDataType dt = elem->mHal.state.fields[fieldIdx]->mHal.state.dataType;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070056 if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
57 dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
58 dt != RS_TYPE_SIGNED_16) {
59 return false;
60 }
61
62 // Now make sure they are not arrays
Alex Sakhartchouk4a43e3e2011-12-28 13:47:05 -080063 uint32_t arraySize = elem->mHal.state.fieldArraySizes[fieldIdx];
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070064 if (arraySize != 1) {
65 return false;
66 }
67
68 return true;
69}
70
Alex Sakhartchoukc0a65422012-01-05 14:55:11 -080071bool RsdMeshObj::init(const Context *rsc) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070072
Alex Sakhartchoukc0a65422012-01-05 14:55:11 -080073 updateGLPrimitives(rsc);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070074
75 // Count the number of gl attrs to initialize
76 mAttribCount = 0;
77 for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
78 const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
Alex Sakhartchouk4a43e3e2011-12-28 13:47:05 -080079 for (uint32_t ct=0; ct < elem->mHal.state.fieldsCount; ct++) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070080 if (isValidGLComponent(elem, ct)) {
81 mAttribCount ++;
82 }
83 }
84 }
85
86 if (mAttribs) {
87 delete [] mAttribs;
88 delete [] mAttribAllocationIndex;
89 mAttribs = NULL;
90 mAttribAllocationIndex = NULL;
91 }
92 if (!mAttribCount) {
93 return false;
94 }
95
96 mAttribs = new RsdVertexArray::Attrib[mAttribCount];
97 mAttribAllocationIndex = new uint32_t[mAttribCount];
98
99 uint32_t userNum = 0;
100 for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
101 const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
Alex Sakhartchouk4a43e3e2011-12-28 13:47:05 -0800102 uint32_t stride = elem->mHal.state.elementSizeBytes;
103 for (uint32_t fieldI=0; fieldI < elem->mHal.state.fieldsCount; fieldI++) {
104 const Element *f = elem->mHal.state.fields[fieldI];
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700105
106 if (!isValidGLComponent(elem, fieldI)) {
107 continue;
108 }
109
Alex Sakhartchouk4a43e3e2011-12-28 13:47:05 -0800110 mAttribs[userNum].size = f->mHal.state.vectorSize;
111 mAttribs[userNum].offset = elem->mHal.state.fieldOffsetBytes[fieldI];
112 mAttribs[userNum].type = rsdTypeToGLType(f->mHal.state.dataType);
113 mAttribs[userNum].normalized = f->mHal.state.dataType != RS_TYPE_FLOAT_32;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700114 mAttribs[userNum].stride = stride;
Chris Wailes6847e732014-08-11 17:30:51 -0700115 std::string tmp(RS_SHADER_ATTR);
Alex Sakhartchouk4a43e3e2011-12-28 13:47:05 -0800116 tmp.append(elem->mHal.state.fieldNames[fieldI]);
Chris Wailes6847e732014-08-11 17:30:51 -0700117 mAttribs[userNum].name = tmp.c_str();
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700118
119 // Remember which allocation this attribute came from
120 mAttribAllocationIndex[userNum] = ct;
121 userNum ++;
122 }
123 }
124
125 return true;
126}
127
Jason Sams2382aba2011-09-13 15:41:01 -0700128void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex,
Tim Murraye195a3f2014-03-13 15:04:58 -0700129 size_t start, uint32_t len) const {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700130 if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) {
Alex Sakhartchoukc0a65422012-01-05 14:55:11 -0800131 rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh or parameters");
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700132 return;
133 }
134
Jason Samseb4fe182011-05-26 16:33:01 -0700135 for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700136 const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct];
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700137 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
138 if (drv->uploadDeferred) {
139 rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT);
140 }
Jason Samseb4fe182011-05-26 16:33:01 -0700141 }
142
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700143 // update attributes with either buffer information or data ptr based on their current state
144 for (uint32_t ct=0; ct < mAttribCount; ct++) {
145 uint32_t allocIndex = mAttribAllocationIndex[ct];
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700146 Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex];
Jason Samseb4fe182011-05-26 16:33:01 -0700147 DrvAllocation *drvAlloc = (DrvAllocation *)alloc->mHal.drv;
148
149 if (drvAlloc->bufferID) {
150 mAttribs[ct].buffer = drvAlloc->bufferID;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700151 mAttribs[ct].ptr = NULL;
152 } else {
153 mAttribs[ct].buffer = 0;
Jason Sams709a0972012-11-15 18:18:04 -0800154 mAttribs[ct].ptr = (const uint8_t*)alloc->mHal.drvState.lod[0].mallocPtr;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700155 }
156 }
157
158 RsdVertexArray va(mAttribs, mAttribCount);
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -0700159 va.setup(rsc);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700160
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700161 const Allocation *idxAlloc = mRSMesh->mHal.state.indexBuffers[primIndex];
Jason Samseb4fe182011-05-26 16:33:01 -0700162 if (idxAlloc) {
163 DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv;
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700164 if (drvAlloc->uploadDeferred) {
165 rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT);
166 }
Jason Samseb4fe182011-05-26 16:33:01 -0700167
168 if (drvAlloc->bufferID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700169 RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID);
170 RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT,
171 (uint16_t *)(start * 2));
Jason Samseb4fe182011-05-26 16:33:01 -0700172 } else {
Jason Sams2382aba2011-09-13 15:41:01 -0700173 RSD_CALL_GL(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER, 0);
174 RSD_CALL_GL(glDrawElements, mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT,
Jason Sams709a0972012-11-15 18:18:04 -0800175 idxAlloc->mHal.drvState.lod[0].mallocPtr);
Jason Samseb4fe182011-05-26 16:33:01 -0700176 }
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700177 } else {
Jason Sams2382aba2011-09-13 15:41:01 -0700178 RSD_CALL_GL(glDrawArrays, mGLPrimitives[primIndex], start, len);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700179 }
180
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -0700181 rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange");
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700182}
183
Alex Sakhartchoukc0a65422012-01-05 14:55:11 -0800184void RsdMeshObj::updateGLPrimitives(const Context *rsc) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700185 mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount];
186 for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) {
Alex Sakhartchouk064aa7e2011-10-18 10:54:29 -0700187 switch (mRSMesh->mHal.state.primitives[i]) {
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700188 case RS_PRIMITIVE_POINT: mGLPrimitives[i] = GL_POINTS; break;
189 case RS_PRIMITIVE_LINE: mGLPrimitives[i] = GL_LINES; break;
190 case RS_PRIMITIVE_LINE_STRIP: mGLPrimitives[i] = GL_LINE_STRIP; break;
191 case RS_PRIMITIVE_TRIANGLE: mGLPrimitives[i] = GL_TRIANGLES; break;
192 case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break;
193 case RS_PRIMITIVE_TRIANGLE_FAN: mGLPrimitives[i] = GL_TRIANGLE_FAN; break;
Alex Sakhartchoukc0a65422012-01-05 14:55:11 -0800194 default: rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh primitive"); break;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700195 }
196 }
197}