1ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall/*
2ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall* Copyright (C) 2011 The Android Open Source Project
3ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall*
4ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall* Licensed under the Apache License, Version 2.0 (the "License");
5ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall* you may not use this file except in compliance with the License.
6ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall* You may obtain a copy of the License at
7ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall*
8ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall* http://www.apache.org/licenses/LICENSE-2.0
9ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall*
10ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall* Unless required by applicable law or agreed to in writing, software
11ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall* distributed under the License is distributed on an "AS IS" BASIS,
12ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall* See the License for the specific language governing permissions and
14ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall* limitations under the License.
15ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall*/
16ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall#include "GLClientState.h"
17ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall#include "ErrorLog.h"
18ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall#include <stdio.h>
19ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall#include <stdlib.h>
20ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall#include <string.h>
21ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall#include "glUtils.h"
22ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall#include <cutils/log.h>
23ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
24ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall#ifndef MAX
25ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall#define MAX(a, b) ((a) < (b) ? (b) : (a))
26ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall#endif
27ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
28ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse HallGLClientState::GLClientState(int nLocations)
29ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
30ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (nLocations < LAST_LOCATION) {
31ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        nLocations = LAST_LOCATION;
32ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
33ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_nLocations = nLocations;
34ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states = new VertexAttribState[m_nLocations];
35ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    for (int i = 0; i < m_nLocations; i++) {
36ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        m_states[i].enabled = 0;
37ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        m_states[i].enableDirty = false;
38ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
39ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_currentArrayVbo = 0;
40ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_currentIndexVbo = 0;
41ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    // init gl constans;
42ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[VERTEX_LOCATION].glConst = GL_VERTEX_ARRAY;
43ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[NORMAL_LOCATION].glConst = GL_NORMAL_ARRAY;
44ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[COLOR_LOCATION].glConst = GL_COLOR_ARRAY;
45ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[POINTSIZE_LOCATION].glConst = GL_POINT_SIZE_ARRAY_OES;
46ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[TEXCOORD0_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
47ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[TEXCOORD1_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
48ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[TEXCOORD2_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
49ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[TEXCOORD3_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
50ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[TEXCOORD4_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
51ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[TEXCOORD5_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
52ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[TEXCOORD6_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
53ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[TEXCOORD7_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
54ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[MATRIXINDEX_LOCATION].glConst = GL_MATRIX_INDEX_ARRAY_OES;
55ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[WEIGHT_LOCATION].glConst = GL_WEIGHT_ARRAY_OES;
56ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_activeTexture = 0;
57ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_currentProgram = 0;
58ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
59ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_pixelStore.unpack_alignment = 4;
60ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_pixelStore.pack_alignment = 4;
61ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
62ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    memset(m_tex.unit, 0, sizeof(m_tex.unit));
63ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_tex.activeUnit = &m_tex.unit[0];
64ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_tex.textures = NULL;
65ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_tex.numTextures = 0;
66ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_tex.allocTextures = 0;
67ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
68ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
69ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse HallGLClientState::~GLClientState()
70ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
71ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    delete m_states;
72ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
73ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
74ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallvoid GLClientState::enable(int location, int state)
75ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
76ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (!validLocation(location)) {
77ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return;
78ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
79ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
80ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].enableDirty |= (state != m_states[location].enabled);
81ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].enabled = state;
82ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
83ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
84ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallvoid GLClientState::setState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data)
85ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
86ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (!validLocation(location)) {
87ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return;
88ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
89ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].size = size;
90ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].type = type;
91ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].stride = stride;
92ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].data = (void*)data;
93ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].bufferObject = m_currentArrayVbo;
94ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].elementSize = glSizeof(type) * size;
95ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].normalized = normalized;
96ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
97ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
98ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallvoid GLClientState::setBufferObject(int location, GLuint id)
99ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
100ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (!validLocation(location)) {
101ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return;
102ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
103ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
104ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].bufferObject = id;
105ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
106ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
107ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallconst GLClientState::VertexAttribState * GLClientState::getState(int location)
108ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
109ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (!validLocation(location)) {
110ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return NULL;
111ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
112ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    return & m_states[location];
113ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
114ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
115ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallconst GLClientState::VertexAttribState * GLClientState::getStateAndEnableDirty(int location, bool *enableChanged)
116ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
117ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (!validLocation(location)) {
118ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return NULL;
119ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
120ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
121ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (enableChanged) {
122ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        *enableChanged = m_states[location].enableDirty;
123ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
124ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
125ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_states[location].enableDirty = false;
126ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    return & m_states[location];
127ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
128ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
129ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallint GLClientState::getLocation(GLenum loc)
130ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
131ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    int retval;
132ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
133ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    switch(loc) {
134ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_VERTEX_ARRAY:
135ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        retval = int(VERTEX_LOCATION);
136ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
137ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_NORMAL_ARRAY:
138ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        retval = int(NORMAL_LOCATION);
139ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
140ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_COLOR_ARRAY:
141ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        retval = int(COLOR_LOCATION);
142ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
143ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_POINT_SIZE_ARRAY_OES:
144ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        retval = int(POINTSIZE_LOCATION);
145ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
146ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_TEXTURE_COORD_ARRAY:
147ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        retval = int (TEXCOORD0_LOCATION + m_activeTexture);
148ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
149ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_MATRIX_INDEX_ARRAY_OES:
150ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        retval = int (MATRIXINDEX_LOCATION);
151ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
152ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_WEIGHT_ARRAY_OES:
153ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        retval = int (WEIGHT_LOCATION);
154ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
155ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    default:
156ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        retval = loc;
157ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
158ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    return retval;
159ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
160ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
161ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallvoid GLClientState::getClientStatePointer(GLenum pname, GLvoid** params)
162ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
163ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    const GLClientState::VertexAttribState *state = NULL;
164ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    switch (pname) {
165ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_VERTEX_ARRAY_POINTER: {
166ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        state = getState(GLClientState::VERTEX_LOCATION);
167ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
168ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
169ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_NORMAL_ARRAY_POINTER: {
170ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        state = getState(GLClientState::NORMAL_LOCATION);
171ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
172ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
173ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_COLOR_ARRAY_POINTER: {
174ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        state = getState(GLClientState::COLOR_LOCATION);
175ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
176ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
177ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_TEXTURE_COORD_ARRAY_POINTER: {
178ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
179ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
180ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
181ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_POINT_SIZE_ARRAY_POINTER_OES: {
182ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        state = getState(GLClientState::POINTSIZE_LOCATION);
183ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
184ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
185ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_MATRIX_INDEX_ARRAY_POINTER_OES: {
186ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        state = getState(GLClientState::MATRIXINDEX_LOCATION);
187ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
188ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
189ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_WEIGHT_ARRAY_POINTER_OES: {
190ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        state = getState(GLClientState::WEIGHT_LOCATION);
191ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
192ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
193ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
194ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (state && params)
195ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        *params = state->data;
196ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
197ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
198ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallint GLClientState::setPixelStore(GLenum param, GLint value)
199ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
200ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    int retval = 0;
201ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    switch(param) {
202ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_UNPACK_ALIGNMENT:
203ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        if (value == 1 || value == 2 || value == 4 || value == 8) {
204ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            m_pixelStore.unpack_alignment = value;
205ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        } else {
206ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            retval =  GL_INVALID_VALUE;
207ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
208ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
209ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_PACK_ALIGNMENT:
210ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        if (value == 1 || value == 2 || value == 4 || value == 8) {
211ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            m_pixelStore.pack_alignment = value;
212ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        } else {
213ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            retval =  GL_INVALID_VALUE;
214ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
215ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
216ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        default:
217ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            retval = GL_INVALID_ENUM;
218ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
219ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    return retval;
220ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
221ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
222ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
223ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
224ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
225ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallsize_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const
226ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
227ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    int pixelsize = glUtilsPixelBitSize(format, type) >> 3;
228ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
229ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    int alignment = pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment;
230ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
231ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (pixelsize == 0 ) {
232ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        ERR("unknown pixel size: width: %d height: %d format: %d type: %d pack: %d align: %d\n",
233ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall             width, height, format, type, pack, alignment);
234ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
235ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    size_t linesize = pixelsize * width;
236ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    size_t aligned_linesize = int(linesize / alignment) * alignment;
237ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (aligned_linesize < linesize) {
238ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        aligned_linesize += alignment;
239ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
240ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    return aligned_linesize * height;
241ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
242ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
243ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse HallGLenum GLClientState::setActiveTextureUnit(GLenum texture)
244ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
245ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    GLuint unit = texture - GL_TEXTURE0;
246ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (unit >= MAX_TEXTURE_UNITS) {
247ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return GL_INVALID_OPERATION;
248ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
249ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_tex.activeUnit = &m_tex.unit[unit];
250ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    return GL_NO_ERROR;
251ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
252ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
253ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse HallGLenum GLClientState::getActiveTextureUnit() const
254ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
255ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    return GL_TEXTURE0 + (m_tex.activeUnit - &m_tex.unit[0]);
256ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
257ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
258ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallvoid GLClientState::enableTextureTarget(GLenum target)
259ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
260ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    switch (target) {
261ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_TEXTURE_2D:
262ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        m_tex.activeUnit->enables |= (1u << TEXTURE_2D);
263ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
264ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_TEXTURE_EXTERNAL_OES:
265ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        m_tex.activeUnit->enables |= (1u << TEXTURE_EXTERNAL);
266ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
267ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
268ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
269ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
270ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallvoid GLClientState::disableTextureTarget(GLenum target)
271ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
272ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    switch (target) {
273ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_TEXTURE_2D:
274ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        m_tex.activeUnit->enables &= ~(1u << TEXTURE_2D);
275ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
276ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_TEXTURE_EXTERNAL_OES:
277ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        m_tex.activeUnit->enables &= ~(1u << TEXTURE_EXTERNAL);
278ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
279ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
280ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
281ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
282ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse HallGLenum GLClientState::getPriorityEnabledTarget(GLenum allDisabled) const
283ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
284ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    unsigned int enables = m_tex.activeUnit->enables;
285ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (enables & (1u << TEXTURE_EXTERNAL)) {
286ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return GL_TEXTURE_EXTERNAL_OES;
287ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    } else if (enables & (1u << TEXTURE_2D)) {
288ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return GL_TEXTURE_2D;
289ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    } else {
290ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return allDisabled;
291ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
292ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
293ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
294ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallint GLClientState::compareTexId(const void* pid, const void* prec)
295ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
296ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    const GLuint* id = (const GLuint*)pid;
297ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    const TextureRec* rec = (const TextureRec*)prec;
298ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    return (GLint)(*id) - (GLint)rec->id;
299ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
300ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
301ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse HallGLenum GLClientState::bindTexture(GLenum target, GLuint texture,
302ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        GLboolean* firstUse)
303ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
304ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    GLboolean first = GL_FALSE;
305ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    TextureRec* texrec = NULL;
306ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (texture != 0) {
307ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        if (m_tex.textures) {
308ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            texrec = (TextureRec*)bsearch(&texture, m_tex.textures,
309ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                    m_tex.numTextures, sizeof(TextureRec), compareTexId);
310ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
311ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        if (!texrec) {
312ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            if (!(texrec = addTextureRec(texture, target))) {
313ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                return GL_OUT_OF_MEMORY;
314ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            }
315ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            first = GL_TRUE;
316ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
317ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        if (target != texrec->target) {
318ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            return GL_INVALID_OPERATION;
319ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
320ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
321ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
322ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    switch (target) {
323ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_TEXTURE_2D:
324ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        m_tex.activeUnit->texture[TEXTURE_2D] = texture;
325ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
326ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_TEXTURE_EXTERNAL_OES:
327ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        m_tex.activeUnit->texture[TEXTURE_EXTERNAL] = texture;
328ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        break;
329ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
330ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
331ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (firstUse) {
332ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        *firstUse = first;
333ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
334ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
335ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    return GL_NO_ERROR;
336ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
337ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
338ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse HallGLClientState::TextureRec* GLClientState::addTextureRec(GLuint id,
339ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        GLenum target)
340ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
341ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    if (m_tex.numTextures == m_tex.allocTextures) {
342ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        const GLuint MAX_TEXTURES = 0xFFFFFFFFu;
343ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
344ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        GLuint newAlloc;
345ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        if (MAX_TEXTURES - m_tex.allocTextures >= m_tex.allocTextures) {
346ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            newAlloc = MAX(4, 2 * m_tex.allocTextures);
347ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        } else {
348ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            if (m_tex.allocTextures == MAX_TEXTURES) {
349ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                return NULL;
350ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            }
351ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            newAlloc = MAX_TEXTURES;
352ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
353ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
354ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        TextureRec* newTextures = (TextureRec*)realloc(m_tex.textures,
355ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                newAlloc * sizeof(TextureRec));
356ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        if (!newTextures) {
357ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            return NULL;
358ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
359ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
360ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        m_tex.textures = newTextures;
361ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        m_tex.allocTextures = newAlloc;
362ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
363ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
364ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    TextureRec* tex = m_tex.textures + m_tex.numTextures;
365ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    TextureRec* prev = tex - 1;
366ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    while (tex != m_tex.textures && id < prev->id) {
367ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        *tex-- = *prev--;
368ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
369ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    tex->id = id;
370ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    tex->target = target;
371ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    m_tex.numTextures++;
372ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
373ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    return tex;
374ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
375ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
376ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse HallGLuint GLClientState::getBoundTexture(GLenum target) const
377ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
378ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    switch (target) {
379ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_TEXTURE_2D:
380ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return m_tex.activeUnit->texture[TEXTURE_2D];
381ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    case GL_TEXTURE_EXTERNAL_OES:
382ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return m_tex.activeUnit->texture[TEXTURE_EXTERNAL];
383ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    default:
384ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        return 0;
385ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
386ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
387ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
388ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hallvoid GLClientState::deleteTextures(GLsizei n, const GLuint* textures)
389ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall{
390ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    // Updating the textures array could be made more efficient when deleting
391ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    // several textures:
392ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    // - compacting the array could be done in a single pass once the deleted
393ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    //   textures are marked, or
394ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    // - could swap deleted textures to the end and re-sort.
395ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    TextureRec* texrec;
396ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    for (const GLuint* texture = textures; texture != textures + n; texture++) {
397ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        texrec = (TextureRec*)bsearch(texture, m_tex.textures,
398ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                m_tex.numTextures, sizeof(TextureRec), compareTexId);
399ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        if (texrec) {
400ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            const TextureRec* end = m_tex.textures + m_tex.numTextures;
401ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            memmove(texrec, texrec + 1,
402ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                    (end - texrec - 1) * sizeof(TextureRec));
403ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            m_tex.numTextures--;
404ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall
405ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            for (TextureUnit* unit = m_tex.unit;
406ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                 unit != m_tex.unit + MAX_TEXTURE_UNITS;
407ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                 unit++)
408ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            {
409ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                if (unit->texture[TEXTURE_2D] == *texture) {
410ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                    unit->texture[TEXTURE_2D] = 0;
411ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                } else if (unit->texture[TEXTURE_EXTERNAL] == *texture) {
412ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                    unit->texture[TEXTURE_EXTERNAL] = 0;
413ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall                }
414ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall            }
415ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall        }
416ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall    }
417ce6c3389061fb9fcdefc94fab2044a8e11600b52Jesse Hall}
418