1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* libs/opengles/texture.cpp
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Copyright 2006, The Android Open Source Project
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
5076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian** Licensed under the Apache License, Version 2.0 (the "License");
6076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian** you may not use this file except in compliance with the License.
7076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian** You may obtain a copy of the License at
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
9076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian**     http://www.apache.org/licenses/LICENSE-2.0
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
11076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian** Unless required by applicable law or agreed to in writing, software
12076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian** distributed under the License is distributed on an "AS IS" BASIS,
13076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian** See the License for the specific language governing permissions and
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** limitations under the License.
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project*/
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "context.h"
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "fp.h"
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "state.h"
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "texture.h"
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "TextureObjectManager.h"
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2618b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian#include <ETC1/etc1.h>
27076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
28c044ae5dfc62031924c2f4c0ecc87b0da72a6b3fDan Stoza#include <ui/GraphicBufferMapper.h>
29c044ae5dfc62031924c2f4c0ecc87b0da72a6b3fDan Stoza#include <ui/Rect.h>
30c044ae5dfc62031924c2f4c0ecc87b0da72a6b3fDan Stoza
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void bindTextureTmu(
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex);
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid generateMipmap(ogles_context_t* c, GLint level);
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Init
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid ogles_init_texture(ogles_context_t* c)
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.packAlignment   = 4;
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.unpackAlignment = 4;
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // each context has a default named (0) texture (not shared)
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.defaultTexture = new EGLTextureObject();
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.defaultTexture->incStrong(c);
56076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // bind the default texture to each texture unit
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        bindTextureTmu(c, i, 0, c->textures.defaultTexture);
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memset(c->current.texture[i].v, 0, sizeof(vec4_t));
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->current.texture[i].Q = 0x10000;
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid ogles_uninit_texture(ogles_context_t* c)
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (c->textures.ggl)
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        gglUninit(c->textures.ggl);
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.defaultTexture->decStrong(c);
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (c->textures.tmu[i].texture)
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->textures.tmu[i].texture->decStrong(c);
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid validate_tmu(ogles_context_t* c, int i)
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texture_unit_t& u(c->textures.tmu[i]);
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (u.dirty) {
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.dirty = 0;
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.activeTexture(c, i);
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texGeni(c, GGL_S,
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texGeni(c, GGL_T,
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_WRAP_S, u.texture->wraps);
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_WRAP_T, u.texture->wrapt);
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // disable this texture unit if it's not complete
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!u.texture->isComplete()) {
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.disable(c, GGL_TEXTURE_2D);
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1040926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid ogles_validate_texture(ogles_context_t* c)
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (c->rasterizer.state.texture[i].enable)
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            validate_tmu(c, i);
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.activeTexture(c, c->textures.active);
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid invalidate_texture(ogles_context_t* c, int tmu, uint8_t flags = 0xFF) {
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.tmu[tmu].dirty = flags;
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1180926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian/*
1190926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian * If the active textures are EGLImage, they need to be locked before
120cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich * they can be used.
121cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich *
1220926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian * FIXME: code below is far from being optimal
123cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich *
1240926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian */
1250926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1260926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid ogles_lock_textures(ogles_context_t* c)
1270926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{
1280926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
1290926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        if (c->rasterizer.state.texture[i].enable) {
1300926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            texture_unit_t& u(c->textures.tmu[i]);
131697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev            ANativeWindowBuffer* native_buffer = u.texture->buffer;
1320926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (native_buffer) {
1330926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.activeTexture(c, i);
13421c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian
135c044ae5dfc62031924c2f4c0ecc87b0da72a6b3fDan Stoza                auto& mapper = GraphicBufferMapper::get();
136e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                void* vaddr;
137c044ae5dfc62031924c2f4c0ecc87b0da72a6b3fDan Stoza                mapper.lock(native_buffer->handle, GRALLOC_USAGE_SW_READ_OFTEN,
138c044ae5dfc62031924c2f4c0ecc87b0da72a6b3fDan Stoza                        Rect(native_buffer->width, native_buffer->height),
139e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                        &vaddr);
1400926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
141e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                u.texture->setImageBits(vaddr);
1420926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
1430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            }
1440926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        }
1450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1460926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian}
1470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid ogles_unlock_textures(ogles_context_t* c)
1490926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{
1500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
1510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        if (c->rasterizer.state.texture[i].enable) {
1520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            texture_unit_t& u(c->textures.tmu[i]);
153697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev            ANativeWindowBuffer* native_buffer = u.texture->buffer;
1540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (native_buffer) {
1550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.activeTexture(c, i);
1560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
157c044ae5dfc62031924c2f4c0ecc87b0da72a6b3fDan Stoza                auto& mapper = GraphicBufferMapper::get();
158c044ae5dfc62031924c2f4c0ecc87b0da72a6b3fDan Stoza                mapper.unlock(native_buffer->handle);
15921c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian
1600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                u.texture->setImageBits(NULL);
1610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
1620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            }
1630926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        }
1640926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1650926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    c->rasterizer.procs.activeTexture(c, c->textures.active);
1660926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian}
1670926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Format conversion
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic uint32_t gl2format_table[6][4] = {
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // BYTE, 565, 4444, 5551
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_A_8,
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0, 0 },                        // GL_ALPHA
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_RGB_888,
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      GGL_PIXEL_FORMAT_RGB_565,
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0 },                           // GL_RGB
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_RGBA_8888,
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0,
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      GGL_PIXEL_FORMAT_RGBA_4444,
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      GGL_PIXEL_FORMAT_RGBA_5551 },     // GL_RGBA
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_L_8,
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0, 0 },                        // GL_LUMINANCE
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_LA_88,
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0, 0 },                        // GL_LUMINANCE_ALPHA
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project};
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic int32_t convertGLPixelFormat(GLint format, GLenum type)
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t fi = -1;
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t ti = -1;
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) {
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_ALPHA:              fi = 0;     break;
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_RGB:                fi = 1;     break;
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_RGBA:               fi = 2;     break;
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_LUMINANCE:          fi = 3;     break;
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_LUMINANCE_ALPHA:    fi = 4;     break;
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (type) {
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_BYTE:          ti = 0; break;
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_SHORT_5_6_5:   ti = 1; break;
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_SHORT_4_4_4_4: ti = 2; break;
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_SHORT_5_5_5_1: ti = 3; break;
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (fi==-1 || ti==-1)
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return gl2format_table[fi][ti];
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic GLenum validFormatType(ogles_context_t* c, GLenum format, GLenum type)
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum error = 0;
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (format<GL_ALPHA || format>GL_LUMINANCE_ALPHA) {
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_ENUM;
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT_4_4_4_4 &&
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type != GL_UNSIGNED_SHORT_5_5_5_1 && type != GL_UNSIGNED_SHORT_5_6_5) {
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_ENUM;
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (type == GL_UNSIGNED_SHORT_5_6_5 && format != GL_RGB) {
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_OPERATION;
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project         type == GL_UNSIGNED_SHORT_5_5_5_1)  && format != GL_RGBA) {
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_OPERATION;
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (error) {
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, error);
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return error;
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGGLContext* getRasterizer(ogles_context_t* c)
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLContext* ggl = c->textures.ggl;
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ggl_unlikely(!ggl)) {
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // this is quite heavy the first time...
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        gglInit(&ggl);
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!ggl) {
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return 0;
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLfixed colors[4] = { 0, 0, 0, 0x10000 };
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->textures.ggl = ggl;
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->activeTexture(ggl, 0);
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->enable(ggl, GGL_TEXTURE_2D);
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->texEnvi(ggl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->disable(ggl, GGL_DITHER);
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->shadeModel(ggl, GGL_FLAT);
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->color4xv(ggl, colors);
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return ggl;
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint copyPixels(
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_context_t* c,
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLSurface& dst,
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint xoffset, GLint yoffset,
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLSurface& src,
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint x, GLint y, GLsizei w, GLsizei h)
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((dst.format == src.format) &&
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.stride == src.stride) &&
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.width == src.width) &&
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.height == src.height) &&
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.stride > 0) &&
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ((x|y) == 0) &&
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ((xoffset|yoffset) == 0))
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // this is a common case...
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLFormat& pixelFormat(c->rasterizer.formats[src.format]);
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t size = src.height * src.stride * pixelFormat.size;
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(dst.data, src.data, size);
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // use pixel-flinger to handle all the conversions
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLContext* ggl = getRasterizer(c);
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!ggl) {
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the only reason this would fail is because we ran out of memory
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return GL_OUT_OF_MEMORY;
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->colorBuffer(ggl, &dst);
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->bindTexture(ggl, &src);
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->texCoord2i(ggl, x-xoffset, y-yoffset);
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->recti(ggl, xoffset, yoffset, xoffset+w, yoffset+h);
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> getAndBindActiveTextureObject(ogles_context_t* c)
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> tex;
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int active = c->textures.active;
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GLuint name = c->textures.tmu[active].name;
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // free the reference to the previously bound object
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texture_unit_t& u(c->textures.tmu[active]);
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (u.texture)
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.texture->decStrong(c);
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (name == 0) {
313076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        // 0 is our local texture object, not shared with anyone.
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // But it affects all bound TMUs immediately.
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // (we need to invalidate all units bound to this texture object)
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->textures.defaultTexture;
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (c->textures.tmu[i].texture == tex.get())
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                invalidate_texture(c, i);
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // get a new texture object for that name
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->surfaceManager->replaceTexture(name);
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // bind this texture to the current active texture unit
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // and add a reference to this texture object
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture = tex.get();
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture->incStrong(c);
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.name = name;
331076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    invalidate_texture(c, active);
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return tex;
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid bindTextureTmu(
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex)
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (tex.get() == c->textures.tmu[tmu].texture)
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
340076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // free the reference to the previously bound object
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texture_unit_t& u(c->textures.tmu[tmu]);
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (u.texture)
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.texture->decStrong(c);
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // bind this texture to the current active texture unit
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // and add a reference to this texture object
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture = tex.get();
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture->incStrong(c);
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.name = texture;
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    invalidate_texture(c, tmu);
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint createTextureSurface(ogles_context_t* c,
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface** outSurface, int32_t* outSize, GLint level,
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum format, GLenum type, GLsizei width, GLsizei height,
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum compressedFormat = 0)
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // find out which texture is bound to the current unit
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int active = c->textures.active;
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GLuint name = c->textures.tmu[active].name;
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // convert the pixelformat to one we can handle
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t formatIdx = convertGLPixelFormat(format, type);
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (formatIdx == 0) { // we don't know what to do with this
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return GL_INVALID_OPERATION;
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
368076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // figure out the size we need as well as the stride
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t align = c->textures.unpackAlignment-1;
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t size = bpr * height;
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t stride = bpr / pixelFormat.size;
375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (level > 0) {
377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int active = c->textures.active;
378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        EGLTextureObject* tex = c->textures.tmu[active].texture;
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        status_t err = tex->reallocate(level,
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                width, height, stride, formatIdx, compressedFormat, bpr);
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (err != NO_ERROR)
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return GL_OUT_OF_MEMORY;
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface& surface = tex->editMip(level);
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *outSurface = &surface;
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *outSize = size;
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = tex->reallocate(level,
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            width, height, stride, formatIdx, compressedFormat, bpr);
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err != NO_ERROR)
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return GL_OUT_OF_MEMORY;
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    tex->internalformat = format;
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *outSurface = &tex->surface;
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *outSize = size;
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
401c044ae5dfc62031924c2f4c0ecc87b0da72a6b3fDan Stozastatic GLsizei dataSizePalette4(int numLevels, int width, int height, int format)
402cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich{
403cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    int indexBits = 8;
404cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    int entrySize = 0;
405cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    switch (format) {
406cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGB8_OES:
407cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        indexBits = 4;
408cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        /* FALLTHROUGH */
409cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGB8_OES:
410cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        entrySize = 3;
411cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        break;
412cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
413cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGBA8_OES:
414cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        indexBits = 4;
415cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        /* FALLTHROUGH */
416cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGBA8_OES:
417cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        entrySize = 4;
418cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        break;
419cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
420cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_R5_G6_B5_OES:
421cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGBA4_OES:
422cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGB5_A1_OES:
423cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        indexBits = 4;
424cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        /* FALLTHROUGH */
425cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_R5_G6_B5_OES:
426cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGBA4_OES:
427cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGB5_A1_OES:
428cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        entrySize = 2;
429cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        break;
430cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    }
431cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
432cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    size_t size = (1 << indexBits) * entrySize; // palette size
433cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
434cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    for (int i=0 ; i< numLevels ; i++) {
435cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        int w = (width  >> i) ? : 1;
436cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        int h = (height >> i) ? : 1;
437cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        int levelSize = h * ((w * indexBits) / 8) ? : 1;
438cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        size += levelSize;
439cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    }
440cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
441cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    return size;
442cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich}
443cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void decodePalette4(const GLvoid *data, int level, int width, int height,
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                           void *surface, int stride, int format)
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int indexBits = 8;
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int entrySize = 0;
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) {
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB8_OES:
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        indexBits = 4;
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        /* FALLTHROUGH */
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB8_OES:
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        entrySize = 3;
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA8_OES:
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        indexBits = 4;
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        /* FALLTHROUGH */
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA8_OES:
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        entrySize = 4;
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_R5_G6_B5_OES:
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA4_OES:
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB5_A1_OES:
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        indexBits = 4;
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        /* FALLTHROUGH */
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_R5_G6_B5_OES:
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA4_OES:
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB5_A1_OES:
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        entrySize = 2;
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int paletteSize = (1 << indexBits) * entrySize;
478cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint8_t const* pixels = (uint8_t *)data + paletteSize;
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<level ; i++) {
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int w = (width  >> i) ? : 1;
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int h = (height >> i) ? : 1;
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        pixels += h * ((w * indexBits) / 8);
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    width  = (width  >> level) ? : 1;
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    height = (height >> level) ? : 1;
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (entrySize == 2) {
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint8_t const* const palette = (uint8_t*)data;
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int y=0 ; y<height ; y++) {
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t* p = (uint8_t*)surface + y*stride*2;
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (indexBits == 8) {
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x++) {
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 2 * (*pixels++);
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x+=2) {
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int v = *pixels++;
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 2 * (v >> 4);
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (x+1 < width) {
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        index = 2 * (v & 0xF);
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 0];
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 1];
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (entrySize == 3) {
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint8_t const* const palette = (uint8_t*)data;
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int y=0 ; y<height ; y++) {
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t* p = (uint8_t*)surface + y*stride*3;
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (indexBits == 8) {
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x++) {
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 3 * (*pixels++);
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x+=2) {
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int v = *pixels++;
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 3 * (v >> 4);
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (x+1 < width) {
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        index = 3 * (v & 0xF);
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 0];
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 1];
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 2];
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (entrySize == 4) {
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint8_t const* const palette = (uint8_t*)data;
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int y=0 ; y<height ; y++) {
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t* p = (uint8_t*)surface + y*stride*4;
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (indexBits == 8) {
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x++) {
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 4 * (*pixels++);
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 3];
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x+=2) {
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int v = *pixels++;
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 4 * (v >> 4);
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 3];
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (x+1 < width) {
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        index = 4 * (v & 0xF);
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 0];
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 1];
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 2];
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 3];
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
57545351bcae55fea67d5560c8a68887394eff9eda8Mathias Agopianvoid set_depth_and_fog(ogles_context_t* c, GGLfixed z)
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we need to compute Zw
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t iterators[3];
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    iterators[1] = iterators[2] = 0;
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLfixed Zw;
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLfixed n = gglFloatToFixed(c->transforms.vpt.zNear);
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLfixed f = gglFloatToFixed(c->transforms.vpt.zFar);
58445351bcae55fea67d5560c8a68887394eff9eda8Mathias Agopian    if (z<=0)               Zw = n;
58545351bcae55fea67d5560c8a68887394eff9eda8Mathias Agopian    else if (z>=0x10000)    Zw = f;
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    else            Zw = gglMulAddx(z, (f-n), n);
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (enables & GGL_ENABLE_FOG) {
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // set up fog if needed...
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        iterators[0] = c->fog.fog(c, Zw);
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.fogGrad3xv(c, iterators);
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (enables & GGL_ENABLE_DEPTH_TEST) {
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // set up z-test if needed...
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t z = (Zw & ~(Zw>>31));
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (z >= 0x10000)
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            z = 0xFFFF;
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        iterators[0] = (z << 16) | z;
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.zGrad3xv(c, iterators);
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Generate mimaps
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectextern status_t buildAPyramid(ogles_context_t* c, EGLTextureObject* tex);
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid generateMipmap(ogles_context_t* c, GLint level)
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (level == 0) {
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int active = c->textures.active;
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        EGLTextureObject* tex = c->textures.tmu[active].texture;
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (tex->generate_mipmap) {
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (buildAPyramid(c, tex) != NO_ERROR) {
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                ogles_error(c, GL_OUT_OF_MEMORY);
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return;
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void texParameterx(
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, GLfixed param, ogles_context_t* c)
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
6283a0cae8e5f3881cb1bcb02ab7fa4cbacf5b55525Mathias Agopian    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
632076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
633076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (pname) {
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_WRAP_S:
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_REPEAT) ||
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_CLAMP_TO_EDGE)) {
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->wraps = param;
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_WRAP_T:
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_REPEAT) ||
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_CLAMP_TO_EDGE)) {
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->wrapt = param;
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_MIN_FILTER:
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_NEAREST) ||
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR) ||
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_NEAREST_MIPMAP_NEAREST) ||
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR_MIPMAP_NEAREST) ||
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_NEAREST_MIPMAP_LINEAR) ||
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR_MIPMAP_LINEAR)) {
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->min_filter = param;
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_MAG_FILTER:
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_NEAREST) ||
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR)) {
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->mag_filter = param;
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_GENERATE_MIPMAP:
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        textureObject->generate_mipmap = param;
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectinvalid_enum:
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    invalidate_texture(c, c->textures.active);
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
683076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
684076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatic void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_context_t* c)
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
6870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    ogles_lock_textures(c);
688cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    y = gglIntToFixed(cbSurface.height) - (y + h);
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    w >>= FIXED_BITS;
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    h >>= FIXED_BITS;
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // set up all texture units
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!c->rasterizer.state.texture[i].enable)
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            continue;
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t texcoords[8];
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texture_unit_t& u(c->textures.tmu[i]);
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // validate this tmu (bind, wrap, filter)
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        validate_tmu(c, i);
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // we CLAMP here, which works with premultiplied (s,t)
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c,
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP);
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c,
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP);
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.dirty = 0xFF; // XXX: should be more subtle
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
711076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        EGLTextureObject* textureObject = u.texture;
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Ucr = textureObject->crop_rect[0] << 16;
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Vcr = textureObject->crop_rect[1] << 16;
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Wcr = textureObject->crop_rect[2] << 16;
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Hcr = textureObject->crop_rect[3] << 16;
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // computes texture coordinates (pre-multiplied)
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t dsdx = Wcr / w;   // dsdx =  ((Wcr/w)/Wt)*Wt
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t dtdy =-Hcr / h;   // dtdy = -((Hcr/h)/Ht)*Ht
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t s0   = Ucr       - gglMulx(dsdx, x); // s0 = Ucr - x * dsdx
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t t0   = (Vcr+Hcr) - gglMulx(dtdy, y); // t0 = (Vcr+Hcr) - y*dtdy
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[0] = s0;
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[1] = dsdx;
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[2] = 0;
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[3] = t0;
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[4] = 0;
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[5] = dtdy;
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[6] = 0;
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[7] = 0;
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texCoordGradScale8xv(c, i, texcoords);
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        set_depth_and_fog(c, z);
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.activeTexture(c, c->textures.active);
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.color4xv(c, c->currentColorClamped.v);
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.disable(c, GGL_W_LERP);
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.disable(c, GGL_AA);
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.shadeModel(c, GL_FLAT);
742076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    c->rasterizer.procs.recti(c,
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(x),
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(y),
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(x)+w,
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(y)+h);
7470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
7480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    ogles_unlock_textures(c);
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
751076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatic void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
752076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_context_t* c)
753076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
754076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // quickly reject empty rects
755076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if ((w|h) <= 0)
756076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return;
757bb0628d9debc5ddd5b1ca3311d6397bbe668c4eeMathias Agopian
758076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    drawTexxOESImp(x, y, z, w, h, c);
759076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
760076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_context_t* c)
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // All coordinates are integer, so if we have only one
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // texture unit active and no scaling is required
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // THEN, we can use our special 1:1 mapping
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // which is a lot faster.
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) {
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int tmu = 0;
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texture_unit_t& u(c->textures.tmu[tmu]);
771076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        EGLTextureObject* textureObject = u.texture;
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Wcr = textureObject->crop_rect[2];
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Hcr = textureObject->crop_rect[3];
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((w == Wcr) && (h == -Hcr)) {
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if ((w|h) <= 0) return; // quickly reject empty rects
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (u.dirty) {
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.activeTexture(c, tmu);
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.texGeni(c, GGL_S,
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.texGeni(c, GGL_T,
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            u.dirty = 0xFF; // XXX: should be more subtle
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.activeTexture(c, c->textures.active);
792076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            y = cbSurface.height - (y + h);
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint Ucr = textureObject->crop_rect[0];
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint Vcr = textureObject->crop_rect[1];
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint s0  = Ucr - x;
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint t0  = (Vcr + Hcr) - y;
799076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLuint tw = textureObject->surface.width;
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLuint th = textureObject->surface.height;
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if ((uint32_t(s0+x+w) > tw) || (uint32_t(t0+y+h) > th)) {
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // The GL spec is unclear about what should happen
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // in this case, so we just use the slow case, which
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // at least won't crash
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                goto slow_case;
807076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8090926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            ogles_lock_textures(c);
8100926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.texCoord2i(c, s0, t0);
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t enables = c->rasterizer.state.enables;
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
81445351bcae55fea67d5560c8a68887394eff9eda8Mathias Agopian                set_depth_and_fog(c, gglIntToFixed(z));
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.color4xv(c, c->currentColorClamped.v);
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.disable(c, GGL_W_LERP);
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.disable(c, GGL_AA);
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.shadeModel(c, GL_FLAT);
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.recti(c, x, y, x+w, y+h);
821cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
8220926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            ogles_unlock_textures(c);
8230926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return;
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectslow_case:
829076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    drawTexxOESImp(
830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglIntToFixed(x), gglIntToFixed(y), gglIntToFixed(z),
831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglIntToFixed(w), gglIntToFixed(h),
832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c);
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace android;
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Texture API
845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glActiveTexture(GLenum texture)
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(texture-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.active = texture - GL_TEXTURE0;
855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.activeTexture(c, c->textures.active);
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glBindTexture(GLenum target, GLuint texture)
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
8613a0cae8e5f3881cb1bcb02ab7fa4cbacf5b55525Mathias Agopian    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Bind or create a texture
867076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<EGLTextureObject> tex;
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (texture == 0) {
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // 0 is our local texture object
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->textures.defaultTexture;
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->surfaceManager->texture(texture);
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (ggl_unlikely(tex == 0)) {
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex = c->surfaceManager->createTexture(texture);
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (tex == 0) {
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                ogles_error(c, GL_OUT_OF_MEMORY);
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return;
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bindTextureTmu(c, c->textures.active, texture, tex);
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glGenTextures(GLsizei n, GLuint *textures)
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (n<0) {
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // generate unique (shared) texture names
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->surfaceManager->getToken(n, textures);
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDeleteTextures(GLsizei n, const GLuint *textures)
896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (n<0) {
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If deleting a bound texture, bind this unit to 0
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int t=0 ; t<GGL_TEXTURE_UNIT_COUNT ; t++) {
905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (c->textures.tmu[t].name == 0)
906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            continue;
907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<n ; i++) {
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (textures[i] && (textures[i] == c->textures.tmu[t].name)) {
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // bind this tmu to texture 0
910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                sp<EGLTextureObject> tex(c->textures.defaultTexture);
911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                bindTextureTmu(c, t, 0, tex);
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->surfaceManager->deleteTextures(n, textures);
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->surfaceManager->recycleTokens(n, textures);
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glMultiTexCoord4f(
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(target-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int tmu = target-GL_TEXTURE0;
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].S = gglFloatToFixed(s);
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].T = gglFloatToFixed(t);
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].R = gglFloatToFixed(r);
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].Q = gglFloatToFixed(q);
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glMultiTexCoord4x(
935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(target-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int tmu = target-GL_TEXTURE0;
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].S = s;
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].T = t;
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].R = r;
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].Q = q;
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glPixelStorei(GLenum pname, GLint param)
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((pname != GL_PACK_ALIGNMENT) && (pname != GL_UNPACK_ALIGNMENT)) {
953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
955076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((param<=0 || param>8) || (param & (param-1))) {
957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_PACK_ALIGNMENT)
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->textures.packAlignment = param;
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_UNPACK_ALIGNMENT)
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->textures.unpackAlignment = param;
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvf(GLenum target, GLenum pname, GLfloat param)
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.texEnvi(c, target, pname, GLint(param));
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvfv(
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, const GLfloat *params)
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_TEXTURE_ENV_MODE) {
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texEnvi(c, target, pname, GLint(*params));
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_TEXTURE_ENV_COLOR) {
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLfixed fixed[4];
982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<4 ; i++)
983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            fixed[i] = gglFloatToFixed(params[i]);
984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texEnvxv(c, target, pname, fixed);
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_error(c, GL_INVALID_ENUM);
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvx(GLenum target, GLenum pname, GLfixed param)
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.texEnvi(c, target, pname, param);
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvxv(
997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, const GLfixed *params)
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.texEnvxv(c, target, pname, params);
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexParameteriv(
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, const GLint* params)
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
10073a0cae8e5f3881cb1bcb02ab7fa4cbacf5b55525Mathias Agopian    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
1008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (pname) {
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_CROP_RECT_OES:
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(textureObject->crop_rect, params, 4*sizeof(GLint));
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1018b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian        texParameterx(target, pname, GLfixed(params[0]), c);
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexParameterf(
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, GLfloat param)
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texParameterx(target, pname, GLfixed(param), c);
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexParameterx(
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, GLfixed param)
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texParameterx(target, pname, param, c);
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1037b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopianvoid glTexParameteri(
1038b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian        GLenum target, GLenum pname, GLint param)
1039b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian{
1040b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian    ogles_context_t* c = ogles_context_t::get();
1041b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian    texParameterx(target, pname, GLfixed(param), c);
1042b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian}
1043b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glCompressedTexImage2D(
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLenum internalformat,
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLsizei width, GLsizei height, GLint border,
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLsizei imageSize, const GLvoid *data)
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (width<0 || height<0 || border!=0) {
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // "uncompress" the texture since pixelflinger doesn't support
1065076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // any compressed texture format natively.
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum format;
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum type;
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (internalformat) {
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB8_OES:
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB8_OES:
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGB;
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_BYTE;
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA8_OES:
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA8_OES:
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGBA;
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_BYTE;
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_R5_G6_B5_OES:
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_R5_G6_B5_OES:
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGB;
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_SHORT_5_6_5;
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA4_OES:
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA4_OES:
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGBA;
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_SHORT_4_4_4_4;
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB5_A1_OES:
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB5_A1_OES:
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGBA;
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_SHORT_5_5_5_1;
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
109418b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian#ifdef GL_OES_compressed_ETC1_RGB8_texture
109518b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian    case GL_ETC1_RGB8_OES:
109618b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        format      = GL_RGB;
109718b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        type        = GL_UNSIGNED_BYTE;
109818b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        break;
109918b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian#endif
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!data || !width || !height) {
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // unclear if this is an error or not...
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t size;
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface* surface;
111218b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian
111318b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian#ifdef GL_OES_compressed_ETC1_RGB8_texture
111418b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian    if (internalformat == GL_ETC1_RGB8_OES) {
111518b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        GLsizei compressedSize = etc1_get_encoded_data_size(width, height);
111618b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        if (compressedSize > imageSize) {
111718b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian            ogles_error(c, GL_INVALID_VALUE);
111818b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian            return;
111918b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        }
112018b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        int error = createTextureSurface(c, &surface, &size,
112118b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian                level, format, type, width, height);
112218b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        if (error) {
112318b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian            ogles_error(c, error);
112418b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian            return;
112518b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        }
112618b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        if (etc1_decode_image(
112718b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian                (const etc1_byte*)data,
112818b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian                (etc1_byte*)surface->data,
112906735863719e08b44edebddcb97861f867bdc01dJack Palevich                width, height, 3, surface->stride*3) != 0) {
113018b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian            ogles_error(c, GL_INVALID_OPERATION);
113118b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        }
113218b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        return;
113318b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian    }
113418b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian#endif
113518b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // all mipmap levels are specified at once.
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int numLevels = level<0 ? -level : 1;
1138cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
1139cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    if (dataSizePalette4(numLevels, width, height, format) > imageSize) {
1140cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        ogles_error(c, GL_INVALID_VALUE);
1141cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        return;
1142cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    }
1143cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<numLevels ; i++) {
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int lod_w = (width  >> i) ? : 1;
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int lod_h = (height >> i) ? : 1;
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int error = createTextureSurface(c, &surface, &size,
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                i, format, type, lod_w, lod_h);
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (error) {
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ogles_error(c, error);
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return;
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        decodePalette4(data, i, width, height,
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                surface->data, surface->stride, internalformat);
1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexImage2D(
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLint internalformat,
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLsizei width, GLsizei height, GLint border,
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum format, GLenum type, const GLvoid *pixels)
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1165076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (target != GL_TEXTURE_2D) {
1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (width<0 || height<0 || border!=0 || level < 0) {
1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1173076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (format != (GLenum)internalformat) {
1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_OPERATION);
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (validFormatType(c, format, type)) {
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t size = 0;
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface* surface = 0;
1183076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    int error = createTextureSurface(c, &surface, &size,
1184076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            level, format, type, width, height);
1185076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (error) {
1186076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_error(c, error);
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pixels) {
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int32_t formatIdx = convertGLPixelFormat(format, type);
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int32_t align = c->textures.unpackAlignment-1;
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t size = bpr * height;
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int32_t stride = bpr / pixelFormat.size;
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface userSurface;
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.version = sizeof(userSurface);
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.width  = width;
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.height = height;
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.stride = stride;
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.format = formatIdx;
1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.compressedFormat = 0;
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.data = (GLubyte*)pixels;
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1207076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        int err = copyPixels(c, *surface, 0, 0, userSurface, 0, 0, width, height);
1208076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (err) {
1209076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            ogles_error(c, err);
1210076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            return;
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1212076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        generateMipmap(c, level);
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glCompressedTexSubImage2D(
121992dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        GLenum /*target*/, GLint /*level*/, GLint /*xoffset*/,
122092dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        GLint /*yoffset*/, GLsizei /*width*/, GLsizei /*height*/,
122192dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        GLenum /*format*/, GLsizei /*imageSize*/,
122292dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        const GLvoid* /*data*/)
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_error(c, GL_INVALID_ENUM);
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexSubImage2D(
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLint xoffset,
1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint yoffset, GLsizei width, GLsizei height,
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum format, GLenum type, const GLvoid *pixels)
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (xoffset<0 || yoffset<0 || width<0 || height<0 || level<0) {
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (validFormatType(c, format, type)) {
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // find out which texture is bound to the current unit
1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int active = c->textures.active;
1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLTextureObject* tex = c->textures.tmu[active].texture;
1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& surface(tex->mip(level));
1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!tex->internalformat || tex->direct) {
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_OPERATION);
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1255d13e46158afd6ff23178f015285535e5bf00dd2cMathias Agopian
1256d13e46158afd6ff23178f015285535e5bf00dd2cMathias Agopian    if (format != tex->internalformat) {
1257d13e46158afd6ff23178f015285535e5bf00dd2cMathias Agopian        ogles_error(c, GL_INVALID_OPERATION);
1258d13e46158afd6ff23178f015285535e5bf00dd2cMathias Agopian        return;
1259d13e46158afd6ff23178f015285535e5bf00dd2cMathias Agopian    }
1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((xoffset + width  > GLsizei(surface.width)) ||
1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (yoffset + height > GLsizei(surface.height))) {
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!width || !height) {
1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return; // okay, but no-op.
1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // figure out the size we need as well as the stride
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t formatIdx = convertGLPixelFormat(format, type);
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (formatIdx == 0) { // we don't know what to do with this
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_OPERATION);
1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t align = c->textures.unpackAlignment-1;
1278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t size = bpr * height;
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t stride = bpr / pixelFormat.size;
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface userSurface;
1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.version = sizeof(userSurface);
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.width  = width;
1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.height = height;
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.stride = stride;
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.format = formatIdx;
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.compressedFormat = 0;
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.data = (GLubyte*)pixels;
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int err = copyPixels(c,
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            surface, xoffset, yoffset,
1292076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            userSurface, 0, 0, width, height);
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) {
1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, err);
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generateMipmap(c, level);
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // since we only changed the content of the texture, we don't need
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // to call bindTexture on the main rasterizer.
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glCopyTexImage2D(
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLenum internalformat,
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint x, GLint y, GLsizei width, GLsizei height,
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint border)
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (internalformat<GL_ALPHA || internalformat>GL_LUMINANCE_ALPHA) {
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (width<0 || height<0 || border!=0 || level<0) {
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum format = 0;
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum type = GL_UNSIGNED_BYTE;
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int cbFormatIdx = cbSurface.format;
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (cbFormatIdx) {
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGB_565:
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type = GL_UNSIGNED_SHORT_5_6_5;
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBA_5551:
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type = GL_UNSIGNED_SHORT_5_5_5_1;
1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBA_4444:
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type = GL_UNSIGNED_SHORT_4_4_4_4;
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (internalformat) {
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_ALPHA:
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_LUMINANCE_ALPHA:
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_LUMINANCE:
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type = GL_UNSIGNED_BYTE;
1345076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        break;
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // figure out the format to use for the new texture
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (cbFormatIdx) {
1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBA_8888:
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_A_8:
1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBA_5551:
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBA_4444:
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = internalformat;
1355076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        break;
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBX_8888:
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGB_888:
1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGB_565:
1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_L_8:
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (internalformat) {
1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case GL_LUMINANCE:
1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case GL_RGB:
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            format = internalformat;
1364076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            break;
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (format == 0) {
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // invalid combination
1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // create the new texture...
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t size;
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface* surface;
1378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int error = createTextureSurface(c, &surface, &size,
1379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            level, format, type, width, height);
1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (error) {
1381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, error);
1382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1384076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // The bottom row is stored first in textures
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface txSurface(*surface);
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    txSurface.stride = -txSurface.stride;
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (x,y) is the lower-left corner of colorBuffer
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    y = cbSurface.height - (y + height);
1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1392fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian    /* The GLES spec says:
1393fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian     * If any of the pixels within the specified rectangle are outside
1394fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian     * the framebuffer associated with the current rendering context,
1395fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian     * then the values obtained for those pixels are undefined.
1396fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian     */
1397fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian    if (x+width > GLint(cbSurface.width))
1398fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian        width = cbSurface.width - x;
1399fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian
1400fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian    if (y+height > GLint(cbSurface.height))
1401fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian        height = cbSurface.height - y;
1402fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int err = copyPixels(c,
1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            txSurface, 0, 0,
1405fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian            cbSurface, x, y, width, height);
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) {
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, err);
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generateMipmap(c, level);
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glCopyTexSubImage2D(
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLint xoffset, GLint yoffset,
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint x, GLint y, GLsizei width, GLsizei height)
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (xoffset<0 || yoffset<0 || width<0 || height<0 || level<0) {
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!width || !height) {
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return; // okay, but no-op.
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // find out which texture is bound to the current unit
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int active = c->textures.active;
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLTextureObject* tex = c->textures.tmu[active].texture;
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& surface(tex->mip(level));
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!tex->internalformat) {
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_OPERATION);
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((xoffset + width  > GLsizei(surface.width)) ||
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (yoffset + height > GLsizei(surface.height))) {
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // The bottom row is stored first in textures
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface txSurface(surface);
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    txSurface.stride = -txSurface.stride;
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (x,y) is the lower-left corner of colorBuffer
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    y = cbSurface.height - (y + height);
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1453fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian    /* The GLES spec says:
1454fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian     * If any of the pixels within the specified rectangle are outside
1455fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian     * the framebuffer associated with the current rendering context,
1456fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian     * then the values obtained for those pixels are undefined.
1457fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian     */
1458fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian    if (x+width > GLint(cbSurface.width))
1459fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian        width = cbSurface.width - x;
1460fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian
1461fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian    if (y+height > GLint(cbSurface.height))
1462fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian        height = cbSurface.height - y;
1463fda42f318a2f6508ed87e51a02bd588db2ddb464Mathias Agopian
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int err = copyPixels(c,
14657c5fe4c4f6ad9f5bad5aa7d7dce6122a3124b87dJack Palevich            txSurface, xoffset, yoffset,
1466076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            cbSurface, x, y, width, height);
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) {
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, err);
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generateMipmap(c, level);
1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glReadPixels(
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint x, GLint y, GLsizei width, GLsizei height,
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum format, GLenum type, GLvoid *pixels)
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((format != GL_RGBA) && (format != GL_RGB)) {
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((type != GL_UNSIGNED_BYTE) && (type != GL_UNSIGNED_SHORT_5_6_5)) {
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (width<0 || height<0) {
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1492a48c654e8207ed820670ea3214a649ff7d92c8a3Mike Playle    if (x<0 || y<0) {
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t formatIdx = GGL_PIXEL_FORMAT_NONE;
1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((format == GL_RGBA) && (type == GL_UNSIGNED_BYTE)) {
1499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        formatIdx = GGL_PIXEL_FORMAT_RGBA_8888;
1500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if ((format == GL_RGB) && (type == GL_UNSIGNED_SHORT_5_6_5)) {
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        formatIdx = GGL_PIXEL_FORMAT_RGB_565;
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_OPERATION);
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& readSurface = c->rasterizer.state.buffers.read.s;
1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((x+width > GLint(readSurface.width)) ||
1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (y+height > GLint(readSurface.height))) {
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t align = c->textures.packAlignment-1;
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t stride = bpr / pixelFormat.size;
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface userSurface;
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.version = sizeof(userSurface);
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.width  = width;
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.height = height;
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.stride = -stride; // bottom row is transfered first
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.format = formatIdx;
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.compressedFormat = 0;
1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.data = (GLubyte*)pixels;
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // use pixel-flinger to handle all the conversions
1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLContext* ggl = getRasterizer(c);
1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!ggl) {
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the only reason this would fail is because we ran out of memory
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_OUT_OF_MEMORY);
1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1536076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    ggl->colorBuffer(ggl, &userSurface);  // destination is user buffer
1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->bindTexture(ggl, &readSurface);  // source is read-buffer
1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->texCoord2i(ggl, x, readSurface.height - (y + height));
1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->recti(ggl, 0, 0, width, height);
1540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark DrawTexture Extension
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexsvOES(const GLshort* coords) {
1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexiOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexivOES(const GLint* coords) {
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexiOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexsOES(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h) {
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexiOES(x, y, z, w, h, c);
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h) {
1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexiOES(x, y, z, w, h, c);
1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexfvOES(const GLfloat* coords) {
1566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexxOES(
1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(coords[0]),
1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(coords[1]),
1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(coords[2]),
1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(coords[3]),
1572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(coords[4]),
1573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c);
1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexxvOES(const GLfixed* coords) {
1576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexxOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
1578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h){
1580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexxOES(
1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(x), gglFloatToFixed(y), gglFloatToFixed(z),
1583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(w), gglFloatToFixed(h),
1584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c);
1585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) {
1587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexxOES(x, y, z, w, h, c);
1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1590076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
1592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#if 0
1593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#pragma mark -
1594076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#pragma mark EGL Image Extension
1595076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#endif
1596076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1597076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
1598076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
1599076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    ogles_context_t* c = ogles_context_t::get();
16003a0cae8e5f3881cb1bcb02ab7fa4cbacf5b55525Mathias Agopian    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
1601076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_error(c, GL_INVALID_ENUM);
1602076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return;
1603076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
16058dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    if (image == EGL_NO_IMAGE_KHR) {
16068dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian        ogles_error(c, GL_INVALID_VALUE);
16078dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian        return;
16088dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    }
16098dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian
1610697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    ANativeWindowBuffer* native_buffer = (ANativeWindowBuffer*)image;
1611076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
1612076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_error(c, GL_INVALID_VALUE);
1613076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return;
1614076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1615697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    if (native_buffer->common.version != sizeof(ANativeWindowBuffer)) {
1616076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_error(c, GL_INVALID_VALUE);
1617076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return;
1618076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1619076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1620076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // bind it to the texture unit
1621076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
16220926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    tex->setImage(native_buffer);
1623076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1624076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1625076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
1626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
16278dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    ogles_context_t* c = ogles_context_t::get();
16288dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    if (target != GL_RENDERBUFFER_OES) {
16298dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian        ogles_error(c, GL_INVALID_ENUM);
16308dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian        return;
16318dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    }
16328dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian
16338dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    if (image == EGL_NO_IMAGE_KHR) {
16348dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian        ogles_error(c, GL_INVALID_VALUE);
16358dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian        return;
16368dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    }
16378dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian
1638697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    ANativeWindowBuffer* native_buffer = (ANativeWindowBuffer*)image;
16398dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
16408dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian        ogles_error(c, GL_INVALID_VALUE);
16418dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian        return;
16428dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    }
1643697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    if (native_buffer->common.version != sizeof(ANativeWindowBuffer)) {
16448dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian        ogles_error(c, GL_INVALID_VALUE);
16458dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian        return;
16468dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    }
16478dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian
16488dccb26901973722164f2a11551fd6d5c52081bfMathias Agopian    // well, we're not supporting this extension anyways
1649076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1650