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 #include "GLClientState.h"
17 #include "ErrorLog.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "glUtils.h"
22 #include <cutils/log.h>
23
GLClientState(int nLocations)24 GLClientState::GLClientState(int nLocations)
25 {
26 if (nLocations < LAST_LOCATION) {
27 nLocations = LAST_LOCATION;
28 }
29 m_nLocations = nLocations;
30 m_states = new VertexAttribState[m_nLocations];
31 for (int i = 0; i < m_nLocations; i++) {
32 m_states[i].enabled = 0;
33 m_states[i].enableDirty = false;
34 }
35 m_currentArrayVbo = 0;
36 m_currentIndexVbo = 0;
37 // init gl constans;
38 m_states[VERTEX_LOCATION].glConst = GL_VERTEX_ARRAY;
39 m_states[NORMAL_LOCATION].glConst = GL_NORMAL_ARRAY;
40 m_states[COLOR_LOCATION].glConst = GL_COLOR_ARRAY;
41 m_states[POINTSIZE_LOCATION].glConst = GL_POINT_SIZE_ARRAY_OES;
42 m_states[TEXCOORD0_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
43 m_states[TEXCOORD1_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
44 m_states[TEXCOORD2_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
45 m_states[TEXCOORD3_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
46 m_states[TEXCOORD4_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
47 m_states[TEXCOORD5_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
48 m_states[TEXCOORD6_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
49 m_states[TEXCOORD7_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
50 m_states[MATRIXINDEX_LOCATION].glConst = GL_MATRIX_INDEX_ARRAY_OES;
51 m_states[WEIGHT_LOCATION].glConst = GL_WEIGHT_ARRAY_OES;
52 m_activeTexture = 0;
53 m_currentProgram = 0;
54
55 m_pixelStore.unpack_alignment = 4;
56 m_pixelStore.pack_alignment = 4;
57 }
58
~GLClientState()59 GLClientState::~GLClientState()
60 {
61 delete m_states;
62 }
63
enable(int location,int state)64 void GLClientState::enable(int location, int state)
65 {
66 if (!validLocation(location)) {
67 return;
68 }
69
70 m_states[location].enableDirty |= (state != m_states[location].enabled);
71 m_states[location].enabled = state;
72 }
73
setState(int location,int size,GLenum type,GLboolean normalized,GLsizei stride,const void * data)74 void GLClientState::setState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data)
75 {
76 if (!validLocation(location)) {
77 return;
78 }
79 m_states[location].size = size;
80 m_states[location].type = type;
81 m_states[location].stride = stride;
82 m_states[location].data = (void*)data;
83 m_states[location].bufferObject = m_currentArrayVbo;
84 m_states[location].elementSize = glSizeof(type) * size;
85 m_states[location].normalized = normalized;
86 }
87
setBufferObject(int location,GLuint id)88 void GLClientState::setBufferObject(int location, GLuint id)
89 {
90 if (!validLocation(location)) {
91 return;
92 }
93
94 m_states[location].bufferObject = id;
95 }
96
getState(int location)97 const GLClientState::VertexAttribState * GLClientState::getState(int location)
98 {
99 if (!validLocation(location)) {
100 return NULL;
101 }
102 return & m_states[location];
103 }
104
getStateAndEnableDirty(int location,bool * enableChanged)105 const GLClientState::VertexAttribState * GLClientState::getStateAndEnableDirty(int location, bool *enableChanged)
106 {
107 if (!validLocation(location)) {
108 return NULL;
109 }
110
111 if (enableChanged) {
112 *enableChanged = m_states[location].enableDirty;
113 }
114
115 m_states[location].enableDirty = false;
116 return & m_states[location];
117 }
118
getLocation(GLenum loc)119 int GLClientState::getLocation(GLenum loc)
120 {
121 int retval;
122
123 switch(loc) {
124 case GL_VERTEX_ARRAY:
125 retval = int(VERTEX_LOCATION);
126 break;
127 case GL_NORMAL_ARRAY:
128 retval = int(NORMAL_LOCATION);
129 break;
130 case GL_COLOR_ARRAY:
131 retval = int(COLOR_LOCATION);
132 break;
133 case GL_POINT_SIZE_ARRAY_OES:
134 retval = int(POINTSIZE_LOCATION);
135 break;
136 case GL_TEXTURE_COORD_ARRAY:
137 retval = int (TEXCOORD0_LOCATION + m_activeTexture);
138 break;
139 case GL_MATRIX_INDEX_ARRAY_OES:
140 retval = int (MATRIXINDEX_LOCATION);
141 break;
142 case GL_WEIGHT_ARRAY_OES:
143 retval = int (WEIGHT_LOCATION);
144 break;
145 default:
146 retval = loc;
147 }
148 return retval;
149 }
150
getClientStatePointer(GLenum pname,GLvoid ** params)151 void GLClientState::getClientStatePointer(GLenum pname, GLvoid** params)
152 {
153 const GLClientState::VertexAttribState *state = NULL;
154 switch (pname) {
155 case GL_VERTEX_ARRAY_POINTER: {
156 state = getState(GLClientState::VERTEX_LOCATION);
157 break;
158 }
159 case GL_NORMAL_ARRAY_POINTER: {
160 state = getState(GLClientState::NORMAL_LOCATION);
161 break;
162 }
163 case GL_COLOR_ARRAY_POINTER: {
164 state = getState(GLClientState::COLOR_LOCATION);
165 break;
166 }
167 case GL_TEXTURE_COORD_ARRAY_POINTER: {
168 state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
169 break;
170 }
171 case GL_POINT_SIZE_ARRAY_POINTER_OES: {
172 state = getState(GLClientState::POINTSIZE_LOCATION);
173 break;
174 }
175 case GL_MATRIX_INDEX_ARRAY_POINTER_OES: {
176 state = getState(GLClientState::MATRIXINDEX_LOCATION);
177 break;
178 }
179 case GL_WEIGHT_ARRAY_POINTER_OES: {
180 state = getState(GLClientState::WEIGHT_LOCATION);
181 break;
182 }
183 }
184 if (state && params)
185 *params = state->data;
186 }
187
setPixelStore(GLenum param,GLint value)188 int GLClientState::setPixelStore(GLenum param, GLint value)
189 {
190 int retval = 0;
191 switch(param) {
192 case GL_UNPACK_ALIGNMENT:
193 if (value == 1 || value == 2 || value == 4 || value == 8) {
194 m_pixelStore.unpack_alignment = value;
195 } else {
196 retval = GL_INVALID_VALUE;
197 }
198 break;
199 case GL_PACK_ALIGNMENT:
200 if (value == 1 || value == 2 || value == 4 || value == 8) {
201 m_pixelStore.pack_alignment = value;
202 } else {
203 retval = GL_INVALID_VALUE;
204 }
205 break;
206 default:
207 retval = GL_INVALID_ENUM;
208 }
209 return retval;
210 }
211
212
213
214
pixelDataSize(GLsizei width,GLsizei height,GLenum format,GLenum type,int pack) const215 size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const
216 {
217 int pixelsize = glUtilsPixelBitSize(format, type) >> 3;
218
219 int alignment = pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment;
220
221 if (pixelsize == 0 ) {
222 ERR("unknown pixel size: width: %d height: %d format: %d type: %d pack: %d align: %d\n",
223 width, height, format, type, pack, alignment);
224 }
225 size_t linesize = pixelsize * width;
226 size_t aligned_linesize = int(linesize / alignment) * alignment;
227 if (aligned_linesize < linesize) {
228 aligned_linesize += alignment;
229 }
230 return aligned_linesize * height;
231 }
232
233