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 <rs_hal.h>
18#include <rsContext.h>
19
20#include <GLES/gl.h>
21#include <GLES2/gl2.h>
22
23#include "rsdGL.h"
24#include "rsdCore.h"
25#include "rsdVertexArray.h"
26#include "rsdShaderCache.h"
27
28using android::renderscript::Context;
29
30RsdVertexArray::RsdVertexArray(const Attrib *attribs, uint32_t numAttribs) {
31    mAttribs = attribs;
32    mCount = numAttribs;
33}
34
35RsdVertexArray::~RsdVertexArray() {
36}
37
38RsdVertexArray::Attrib::Attrib() {
39    clear();
40}
41
42void RsdVertexArray::Attrib::clear() {
43    buffer = 0;
44    offset = 0;
45    type = 0;
46    size = 0;
47    stride = 0;
48    ptr = nullptr;
49    normalized = false;
50    name.assign("");
51}
52
53void RsdVertexArray::Attrib::set(uint32_t type, uint32_t size, uint32_t stride,
54                              bool normalized, size_t offset,
55                              const char *name) {
56    clear();
57    this->type = type;
58    this->size = size;
59    this->offset = offset;
60    this->normalized = normalized;
61    this->stride = stride;
62    this->name.assign(name);
63}
64
65void RsdVertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
66    if (idx == 0) {
67        ALOGV("Starting vertex attribute binding");
68    }
69    ALOGV("va %i: slot=%i name=%s buf=%i ptr=%p size=%i  type=0x%x  stride=0x%x  norm=%i  offset=0x%p",
70          idx, slot,
71          mAttribs[idx].name.c_str(),
72          mAttribs[idx].buffer,
73          mAttribs[idx].ptr,
74          mAttribs[idx].size,
75          mAttribs[idx].type,
76          mAttribs[idx].stride,
77          mAttribs[idx].normalized,
78          (void*)mAttribs[idx].offset);
79}
80
81void RsdVertexArray::setup(const Context *rsc) const {
82
83    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
84    RsdVertexArrayState *state = dc->gl.vertexArrayState;
85    RsdShaderCache *sc = dc->gl.shaderCache;
86
87    rsdGLCheckError(rsc, "RsdVertexArray::setup start");
88    uint32_t maxAttrs = state->mAttrsEnabledSize;
89
90    for (uint32_t ct=1; ct < maxAttrs; ct++) {
91        if(state->mAttrsEnabled[ct]) {
92            glDisableVertexAttribArray(ct);
93            state->mAttrsEnabled[ct] = false;
94        }
95    }
96
97    rsdGLCheckError(rsc, "RsdVertexArray::setup disabled");
98    for (uint32_t ct=0; ct < mCount; ct++) {
99        int32_t slot = sc->vtxAttribSlot(mAttribs[ct].name);
100        if (rsc->props.mLogShadersAttr) {
101            logAttrib(ct, slot);
102        }
103        if (slot < 0 || slot >= (int32_t)maxAttrs) {
104            continue;
105        }
106        glEnableVertexAttribArray(slot);
107        state->mAttrsEnabled[slot] = true;
108        glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer);
109        glVertexAttribPointer(slot,
110                              mAttribs[ct].size,
111                              mAttribs[ct].type,
112                              mAttribs[ct].normalized,
113                              mAttribs[ct].stride,
114                              mAttribs[ct].ptr + mAttribs[ct].offset);
115    }
116    rsdGLCheckError(rsc, "RsdVertexArray::setup done");
117}
118////////////////////////////////////////////
119RsdVertexArrayState::RsdVertexArrayState() {
120    mAttrsEnabled = nullptr;
121    mAttrsEnabledSize = 0;
122}
123
124RsdVertexArrayState::~RsdVertexArrayState() {
125    if (mAttrsEnabled) {
126        delete[] mAttrsEnabled;
127        mAttrsEnabled = nullptr;
128    }
129}
130void RsdVertexArrayState::init(uint32_t maxAttrs) {
131    mAttrsEnabledSize = maxAttrs;
132    mAttrsEnabled = new bool[mAttrsEnabledSize];
133    for (uint32_t ct = 0; ct < mAttrsEnabledSize; ct++) {
134        mAttrsEnabled[ct] = false;
135    }
136}
137