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
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void bindTextureTmu(
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex);
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid generateMipmap(ogles_context_t* c, GLint level);
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Init
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid ogles_init_texture(ogles_context_t* c)
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.packAlignment   = 4;
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.unpackAlignment = 4;
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // each context has a default named (0) texture (not shared)
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.defaultTexture = new EGLTextureObject();
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.defaultTexture->incStrong(c);
53076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // bind the default texture to each texture unit
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        bindTextureTmu(c, i, 0, c->textures.defaultTexture);
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memset(c->current.texture[i].v, 0, sizeof(vec4_t));
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->current.texture[i].Q = 0x10000;
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid ogles_uninit_texture(ogles_context_t* c)
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (c->textures.ggl)
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        gglUninit(c->textures.ggl);
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.defaultTexture->decStrong(c);
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (c->textures.tmu[i].texture)
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->textures.tmu[i].texture->decStrong(c);
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid validate_tmu(ogles_context_t* c, int i)
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texture_unit_t& u(c->textures.tmu[i]);
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (u.dirty) {
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.dirty = 0;
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.activeTexture(c, i);
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texGeni(c, GGL_S,
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texGeni(c, GGL_T,
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_WRAP_S, u.texture->wraps);
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_WRAP_T, u.texture->wrapt);
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // disable this texture unit if it's not complete
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!u.texture->isComplete()) {
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.disable(c, GGL_TEXTURE_2D);
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1010926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid ogles_validate_texture(ogles_context_t* c)
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (c->rasterizer.state.texture[i].enable)
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            validate_tmu(c, i);
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.activeTexture(c, c->textures.active);
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid invalidate_texture(ogles_context_t* c, int tmu, uint8_t flags = 0xFF) {
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.tmu[tmu].dirty = flags;
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1150926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian/*
1160926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian * If the active textures are EGLImage, they need to be locked before
117cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich * they can be used.
118cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich *
1190926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian * FIXME: code below is far from being optimal
120cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich *
1210926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian */
1220926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1230926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid ogles_lock_textures(ogles_context_t* c)
1240926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{
1250926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
1260926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        if (c->rasterizer.state.texture[i].enable) {
1270926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            texture_unit_t& u(c->textures.tmu[i]);
128697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev            ANativeWindowBuffer* native_buffer = u.texture->buffer;
1290926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (native_buffer) {
1300926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.activeTexture(c, i);
1310926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                hw_module_t const* pModule;
1320926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
1330926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    continue;
1340926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1350926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                gralloc_module_t const* module =
1360926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    reinterpret_cast<gralloc_module_t const*>(pModule);
13721c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian
138e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                void* vaddr;
13921c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian                int err = module->lock(module, native_buffer->handle,
1400926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                        GRALLOC_USAGE_SW_READ_OFTEN,
1410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                        0, 0, native_buffer->width, native_buffer->height,
142e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                        &vaddr);
1430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
144e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                u.texture->setImageBits(vaddr);
1450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
1460926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            }
1470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        }
1480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1490926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian}
1500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid ogles_unlock_textures(ogles_context_t* c)
1520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{
1530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
1540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        if (c->rasterizer.state.texture[i].enable) {
1550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            texture_unit_t& u(c->textures.tmu[i]);
156697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev            ANativeWindowBuffer* native_buffer = u.texture->buffer;
1570926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (native_buffer) {
1580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.activeTexture(c, i);
1590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                hw_module_t const* pModule;
1600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
1610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    continue;
1620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1630926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                gralloc_module_t const* module =
1640926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    reinterpret_cast<gralloc_module_t const*>(pModule);
16521c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian
16621c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian                module->unlock(module, native_buffer->handle);
1670926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                u.texture->setImageBits(NULL);
1680926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
1690926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            }
1700926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        }
1710926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1720926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    c->rasterizer.procs.activeTexture(c, c->textures.active);
1730926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian}
1740926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Format conversion
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic uint32_t gl2format_table[6][4] = {
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // BYTE, 565, 4444, 5551
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_A_8,
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0, 0 },                        // GL_ALPHA
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_RGB_888,
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      GGL_PIXEL_FORMAT_RGB_565,
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0 },                           // GL_RGB
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_RGBA_8888,
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0,
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      GGL_PIXEL_FORMAT_RGBA_4444,
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      GGL_PIXEL_FORMAT_RGBA_5551 },     // GL_RGBA
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_L_8,
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0, 0 },                        // GL_LUMINANCE
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_LA_88,
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0, 0 },                        // GL_LUMINANCE_ALPHA
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project};
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic int32_t convertGLPixelFormat(GLint format, GLenum type)
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t fi = -1;
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t ti = -1;
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) {
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_ALPHA:              fi = 0;     break;
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_RGB:                fi = 1;     break;
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_RGBA:               fi = 2;     break;
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_LUMINANCE:          fi = 3;     break;
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_LUMINANCE_ALPHA:    fi = 4;     break;
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (type) {
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_BYTE:          ti = 0; break;
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_SHORT_5_6_5:   ti = 1; break;
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_SHORT_4_4_4_4: ti = 2; break;
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_SHORT_5_5_5_1: ti = 3; break;
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (fi==-1 || ti==-1)
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return gl2format_table[fi][ti];
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic GLenum validFormatType(ogles_context_t* c, GLenum format, GLenum type)
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum error = 0;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (format<GL_ALPHA || format>GL_LUMINANCE_ALPHA) {
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_ENUM;
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT_4_4_4_4 &&
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type != GL_UNSIGNED_SHORT_5_5_5_1 && type != GL_UNSIGNED_SHORT_5_6_5) {
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_ENUM;
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (type == GL_UNSIGNED_SHORT_5_6_5 && format != GL_RGB) {
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_OPERATION;
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project         type == GL_UNSIGNED_SHORT_5_5_5_1)  && format != GL_RGBA) {
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_OPERATION;
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (error) {
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, error);
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return error;
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGGLContext* getRasterizer(ogles_context_t* c)
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLContext* ggl = c->textures.ggl;
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ggl_unlikely(!ggl)) {
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // this is quite heavy the first time...
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        gglInit(&ggl);
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!ggl) {
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return 0;
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLfixed colors[4] = { 0, 0, 0, 0x10000 };
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->textures.ggl = ggl;
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->activeTexture(ggl, 0);
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->enable(ggl, GGL_TEXTURE_2D);
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->texEnvi(ggl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->disable(ggl, GGL_DITHER);
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->shadeModel(ggl, GGL_FLAT);
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->color4xv(ggl, colors);
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return ggl;
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint copyPixels(
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_context_t* c,
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLSurface& dst,
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint xoffset, GLint yoffset,
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLSurface& src,
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint x, GLint y, GLsizei w, GLsizei h)
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((dst.format == src.format) &&
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.stride == src.stride) &&
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.width == src.width) &&
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.height == src.height) &&
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.stride > 0) &&
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ((x|y) == 0) &&
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ((xoffset|yoffset) == 0))
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // this is a common case...
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLFormat& pixelFormat(c->rasterizer.formats[src.format]);
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t size = src.height * src.stride * pixelFormat.size;
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(dst.data, src.data, size);
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // use pixel-flinger to handle all the conversions
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLContext* ggl = getRasterizer(c);
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!ggl) {
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the only reason this would fail is because we ran out of memory
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return GL_OUT_OF_MEMORY;
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->colorBuffer(ggl, &dst);
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->bindTexture(ggl, &src);
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->texCoord2i(ggl, x-xoffset, y-yoffset);
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->recti(ggl, xoffset, yoffset, xoffset+w, yoffset+h);
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> getAndBindActiveTextureObject(ogles_context_t* c)
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> tex;
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int active = c->textures.active;
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GLuint name = c->textures.tmu[active].name;
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // free the reference to the previously bound object
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texture_unit_t& u(c->textures.tmu[active]);
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (u.texture)
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.texture->decStrong(c);
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (name == 0) {
320076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        // 0 is our local texture object, not shared with anyone.
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // But it affects all bound TMUs immediately.
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // (we need to invalidate all units bound to this texture object)
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->textures.defaultTexture;
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (c->textures.tmu[i].texture == tex.get())
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                invalidate_texture(c, i);
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // get a new texture object for that name
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->surfaceManager->replaceTexture(name);
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // bind this texture to the current active texture unit
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // and add a reference to this texture object
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture = tex.get();
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture->incStrong(c);
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.name = name;
338076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    invalidate_texture(c, active);
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return tex;
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid bindTextureTmu(
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex)
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (tex.get() == c->textures.tmu[tmu].texture)
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
347076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // free the reference to the previously bound object
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texture_unit_t& u(c->textures.tmu[tmu]);
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (u.texture)
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.texture->decStrong(c);
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // bind this texture to the current active texture unit
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // and add a reference to this texture object
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture = tex.get();
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture->incStrong(c);
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.name = texture;
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    invalidate_texture(c, tmu);
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint createTextureSurface(ogles_context_t* c,
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface** outSurface, int32_t* outSize, GLint level,
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum format, GLenum type, GLsizei width, GLsizei height,
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum compressedFormat = 0)
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // find out which texture is bound to the current unit
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int active = c->textures.active;
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GLuint name = c->textures.tmu[active].name;
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // convert the pixelformat to one we can handle
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t formatIdx = convertGLPixelFormat(format, type);
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (formatIdx == 0) { // we don't know what to do with this
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return GL_INVALID_OPERATION;
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
375076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // figure out the size we need as well as the stride
377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t align = c->textures.unpackAlignment-1;
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t size = bpr * height;
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t stride = bpr / pixelFormat.size;
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (level > 0) {
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int active = c->textures.active;
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        EGLTextureObject* tex = c->textures.tmu[active].texture;
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        status_t err = tex->reallocate(level,
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                width, height, stride, formatIdx, compressedFormat, bpr);
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (err != NO_ERROR)
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return GL_OUT_OF_MEMORY;
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface& surface = tex->editMip(level);
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *outSurface = &surface;
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *outSize = size;
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = tex->reallocate(level,
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            width, height, stride, formatIdx, compressedFormat, bpr);
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err != NO_ERROR)
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return GL_OUT_OF_MEMORY;
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    tex->internalformat = format;
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *outSurface = &tex->surface;
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *outSize = size;
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
408cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevichstatic size_t dataSizePalette4(int numLevels, int width, int height, int format)
409cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich{
410cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    int indexBits = 8;
411cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    int entrySize = 0;
412cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    switch (format) {
413cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGB8_OES:
414cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        indexBits = 4;
415cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        /* FALLTHROUGH */
416cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGB8_OES:
417cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        entrySize = 3;
418cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        break;
419cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
420cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGBA8_OES:
421cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        indexBits = 4;
422cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        /* FALLTHROUGH */
423cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGBA8_OES:
424cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        entrySize = 4;
425cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        break;
426cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
427cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_R5_G6_B5_OES:
428cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGBA4_OES:
429cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGB5_A1_OES:
430cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        indexBits = 4;
431cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        /* FALLTHROUGH */
432cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_R5_G6_B5_OES:
433cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGBA4_OES:
434cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGB5_A1_OES:
435cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        entrySize = 2;
436cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        break;
437cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    }
438cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
439cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    size_t size = (1 << indexBits) * entrySize; // palette size
440cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
441cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    for (int i=0 ; i< numLevels ; i++) {
442cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        int w = (width  >> i) ? : 1;
443cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        int h = (height >> i) ? : 1;
444cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        int levelSize = h * ((w * indexBits) / 8) ? : 1;
445cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        size += levelSize;
446cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    }
447cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
448cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    return size;
449cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich}
450cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void decodePalette4(const GLvoid *data, int level, int width, int height,
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                           void *surface, int stride, int format)
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int indexBits = 8;
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int entrySize = 0;
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) {
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB8_OES:
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        indexBits = 4;
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        /* FALLTHROUGH */
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB8_OES:
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        entrySize = 3;
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA8_OES:
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        indexBits = 4;
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        /* FALLTHROUGH */
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA8_OES:
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        entrySize = 4;
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_R5_G6_B5_OES:
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA4_OES:
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB5_A1_OES:
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        indexBits = 4;
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        /* FALLTHROUGH */
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_R5_G6_B5_OES:
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA4_OES:
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB5_A1_OES:
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        entrySize = 2;
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int paletteSize = (1 << indexBits) * entrySize;
485cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint8_t const* pixels = (uint8_t *)data + paletteSize;
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<level ; i++) {
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int w = (width  >> i) ? : 1;
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int h = (height >> i) ? : 1;
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        pixels += h * ((w * indexBits) / 8);
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    width  = (width  >> level) ? : 1;
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    height = (height >> level) ? : 1;
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (entrySize == 2) {
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint8_t const* const palette = (uint8_t*)data;
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int y=0 ; y<height ; y++) {
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t* p = (uint8_t*)surface + y*stride*2;
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (indexBits == 8) {
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x++) {
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 2 * (*pixels++);
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x+=2) {
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int v = *pixels++;
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 2 * (v >> 4);
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (x+1 < width) {
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        index = 2 * (v & 0xF);
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 0];
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 1];
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (entrySize == 3) {
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint8_t const* const palette = (uint8_t*)data;
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int y=0 ; y<height ; y++) {
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t* p = (uint8_t*)surface + y*stride*3;
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (indexBits == 8) {
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x++) {
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 3 * (*pixels++);
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x+=2) {
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int v = *pixels++;
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 3 * (v >> 4);
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (x+1 < width) {
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        index = 3 * (v & 0xF);
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 0];
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 1];
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 2];
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (entrySize == 4) {
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint8_t const* const palette = (uint8_t*)data;
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int y=0 ; y<height ; y++) {
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t* p = (uint8_t*)surface + y*stride*4;
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (indexBits == 8) {
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x++) {
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 4 * (*pixels++);
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 3];
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x+=2) {
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int v = *pixels++;
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 4 * (v >> 4);
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 3];
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (x+1 < width) {
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        index = 4 * (v & 0xF);
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 0];
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 1];
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 2];
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 3];
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
58245351bcae55fea67d5560c8a68887394eff9eda8Mathias Agopianvoid set_depth_and_fog(ogles_context_t* c, GGLfixed z)
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we need to compute Zw
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t iterators[3];
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    iterators[1] = iterators[2] = 0;
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLfixed Zw;
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLfixed n = gglFloatToFixed(c->transforms.vpt.zNear);
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLfixed f = gglFloatToFixed(c->transforms.vpt.zFar);
59145351bcae55fea67d5560c8a68887394eff9eda8Mathias Agopian    if (z<=0)               Zw = n;
59245351bcae55fea67d5560c8a68887394eff9eda8Mathias Agopian    else if (z>=0x10000)    Zw = f;
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    else            Zw = gglMulAddx(z, (f-n), n);
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (enables & GGL_ENABLE_FOG) {
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // set up fog if needed...
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        iterators[0] = c->fog.fog(c, Zw);
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.fogGrad3xv(c, iterators);
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (enables & GGL_ENABLE_DEPTH_TEST) {
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // set up z-test if needed...
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t z = (Zw & ~(Zw>>31));
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (z >= 0x10000)
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            z = 0xFFFF;
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        iterators[0] = (z << 16) | z;
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.zGrad3xv(c, iterators);
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Generate mimaps
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectextern status_t buildAPyramid(ogles_context_t* c, EGLTextureObject* tex);
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid generateMipmap(ogles_context_t* c, GLint level)
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (level == 0) {
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int active = c->textures.active;
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        EGLTextureObject* tex = c->textures.tmu[active].texture;
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (tex->generate_mipmap) {
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (buildAPyramid(c, tex) != NO_ERROR) {
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                ogles_error(c, GL_OUT_OF_MEMORY);
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return;
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void texParameterx(
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, GLfixed param, ogles_context_t* c)
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
6353a0cae8e5f3881cb1bcb02ab7fa4cbacf5b55525Mathias Agopian    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
639076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
640076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (pname) {
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_WRAP_S:
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_REPEAT) ||
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_CLAMP_TO_EDGE)) {
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->wraps = param;
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_WRAP_T:
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_REPEAT) ||
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_CLAMP_TO_EDGE)) {
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->wrapt = param;
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_MIN_FILTER:
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_NEAREST) ||
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR) ||
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_NEAREST_MIPMAP_NEAREST) ||
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR_MIPMAP_NEAREST) ||
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_NEAREST_MIPMAP_LINEAR) ||
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR_MIPMAP_LINEAR)) {
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->min_filter = param;
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_MAG_FILTER:
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_NEAREST) ||
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR)) {
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->mag_filter = param;
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_GENERATE_MIPMAP:
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        textureObject->generate_mipmap = param;
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectinvalid_enum:
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    invalidate_texture(c, c->textures.active);
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
690076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
691076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatic void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_context_t* c)
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
6940926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    ogles_lock_textures(c);
695cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    y = gglIntToFixed(cbSurface.height) - (y + h);
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    w >>= FIXED_BITS;
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    h >>= FIXED_BITS;
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // set up all texture units
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!c->rasterizer.state.texture[i].enable)
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            continue;
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t texcoords[8];
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texture_unit_t& u(c->textures.tmu[i]);
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // validate this tmu (bind, wrap, filter)
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        validate_tmu(c, i);
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // we CLAMP here, which works with premultiplied (s,t)
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c,
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP);
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c,
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP);
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.dirty = 0xFF; // XXX: should be more subtle
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
718076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        EGLTextureObject* textureObject = u.texture;
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Ucr = textureObject->crop_rect[0] << 16;
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Vcr = textureObject->crop_rect[1] << 16;
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Wcr = textureObject->crop_rect[2] << 16;
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Hcr = textureObject->crop_rect[3] << 16;
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // computes texture coordinates (pre-multiplied)
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t dsdx = Wcr / w;   // dsdx =  ((Wcr/w)/Wt)*Wt
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t dtdy =-Hcr / h;   // dtdy = -((Hcr/h)/Ht)*Ht
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t s0   = Ucr       - gglMulx(dsdx, x); // s0 = Ucr - x * dsdx
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t t0   = (Vcr+Hcr) - gglMulx(dtdy, y); // t0 = (Vcr+Hcr) - y*dtdy
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[0] = s0;
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[1] = dsdx;
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[2] = 0;
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[3] = t0;
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[4] = 0;
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[5] = dtdy;
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[6] = 0;
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[7] = 0;
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texCoordGradScale8xv(c, i, texcoords);
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        set_depth_and_fog(c, z);
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.activeTexture(c, c->textures.active);
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.color4xv(c, c->currentColorClamped.v);
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.disable(c, GGL_W_LERP);
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.disable(c, GGL_AA);
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.shadeModel(c, GL_FLAT);
749076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    c->rasterizer.procs.recti(c,
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(x),
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(y),
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(x)+w,
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(y)+h);
7540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
7550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    ogles_unlock_textures(c);
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
758076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatic void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
759076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_context_t* c)
760076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
761076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // quickly reject empty rects
762076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if ((w|h) <= 0)
763076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return;
764bb0628d9debc5ddd5b1ca3311d6397bbe668c4eeMathias Agopian
765076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    drawTexxOESImp(x, y, z, w, h, c);
766076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
767076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_context_t* c)
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // All coordinates are integer, so if we have only one
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // texture unit active and no scaling is required
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // THEN, we can use our special 1:1 mapping
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // which is a lot faster.
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) {
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int tmu = 0;
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texture_unit_t& u(c->textures.tmu[tmu]);
778076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        EGLTextureObject* textureObject = u.texture;
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Wcr = textureObject->crop_rect[2];
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Hcr = textureObject->crop_rect[3];
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((w == Wcr) && (h == -Hcr)) {
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if ((w|h) <= 0) return; // quickly reject empty rects
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (u.dirty) {
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.activeTexture(c, tmu);
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.texGeni(c, GGL_S,
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.texGeni(c, GGL_T,
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            u.dirty = 0xFF; // XXX: should be more subtle
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.activeTexture(c, c->textures.active);
799076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            y = cbSurface.height - (y + h);
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint Ucr = textureObject->crop_rect[0];
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint Vcr = textureObject->crop_rect[1];
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint s0  = Ucr - x;
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint t0  = (Vcr + Hcr) - y;
806076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLuint tw = textureObject->surface.width;
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLuint th = textureObject->surface.height;
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if ((uint32_t(s0+x+w) > tw) || (uint32_t(t0+y+h) > th)) {
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // The GL spec is unclear about what should happen
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // in this case, so we just use the slow case, which
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // at least won't crash
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                goto slow_case;
814076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8160926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            ogles_lock_textures(c);
8170926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.texCoord2i(c, s0, t0);
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t enables = c->rasterizer.state.enables;
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
82145351bcae55fea67d5560c8a68887394eff9eda8Mathias Agopian                set_depth_and_fog(c, gglIntToFixed(z));
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.color4xv(c, c->currentColorClamped.v);
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.disable(c, GGL_W_LERP);
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.disable(c, GGL_AA);
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.shadeModel(c, GL_FLAT);
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.recti(c, x, y, x+w, y+h);
828cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
8290926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            ogles_unlock_textures(c);
8300926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return;
832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectslow_case:
836076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    drawTexxOESImp(
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglIntToFixed(x), gglIntToFixed(y), gglIntToFixed(z),
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglIntToFixed(w), gglIntToFixed(h),
839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c);
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace android;
847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Texture API
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glActiveTexture(GLenum texture)
855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(texture-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.active = texture - GL_TEXTURE0;
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.activeTexture(c, c->textures.active);
863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glBindTexture(GLenum target, GLuint texture)
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
8683a0cae8e5f3881cb1bcb02ab7fa4cbacf5b55525Mathias Agopian    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Bind or create a texture
874076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<EGLTextureObject> tex;
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (texture == 0) {
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // 0 is our local texture object
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->textures.defaultTexture;
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->surfaceManager->texture(texture);
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (ggl_unlikely(tex == 0)) {
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex = c->surfaceManager->createTexture(texture);
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (tex == 0) {
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                ogles_error(c, GL_OUT_OF_MEMORY);
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return;
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bindTextureTmu(c, c->textures.active, texture, tex);
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glGenTextures(GLsizei n, GLuint *textures)
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (n<0) {
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // generate unique (shared) texture names
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->surfaceManager->getToken(n, textures);
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDeleteTextures(GLsizei n, const GLuint *textures)
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (n<0) {
906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If deleting a bound texture, bind this unit to 0
911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int t=0 ; t<GGL_TEXTURE_UNIT_COUNT ; t++) {
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (c->textures.tmu[t].name == 0)
913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            continue;
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<n ; i++) {
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (textures[i] && (textures[i] == c->textures.tmu[t].name)) {
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // bind this tmu to texture 0
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                sp<EGLTextureObject> tex(c->textures.defaultTexture);
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                bindTextureTmu(c, t, 0, tex);
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->surfaceManager->deleteTextures(n, textures);
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->surfaceManager->recycleTokens(n, textures);
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glMultiTexCoord4f(
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(target-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int tmu = target-GL_TEXTURE0;
935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].S = gglFloatToFixed(s);
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].T = gglFloatToFixed(t);
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].R = gglFloatToFixed(r);
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].Q = gglFloatToFixed(q);
939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glMultiTexCoord4x(
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(target-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int tmu = target-GL_TEXTURE0;
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].S = s;
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].T = t;
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].R = r;
953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].Q = q;
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glPixelStorei(GLenum pname, GLint param)
957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((pname != GL_PACK_ALIGNMENT) && (pname != GL_UNPACK_ALIGNMENT)) {
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
962076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((param<=0 || param>8) || (param & (param-1))) {
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_PACK_ALIGNMENT)
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->textures.packAlignment = param;
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_UNPACK_ALIGNMENT)
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->textures.unpackAlignment = param;
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvf(GLenum target, GLenum pname, GLfloat param)
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.texEnvi(c, target, pname, GLint(param));
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvfv(
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, const GLfloat *params)
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_TEXTURE_ENV_MODE) {
984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texEnvi(c, target, pname, GLint(*params));
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_TEXTURE_ENV_COLOR) {
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLfixed fixed[4];
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<4 ; i++)
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            fixed[i] = gglFloatToFixed(params[i]);
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texEnvxv(c, target, pname, fixed);
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_error(c, GL_INVALID_ENUM);
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvx(GLenum target, GLenum pname, GLfixed param)
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.texEnvi(c, target, pname, param);
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvxv(
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, const GLfixed *params)
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1007edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.texEnvxv(c, target, pname, params);
1008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexParameteriv(
1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, const GLint* params)
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
10143a0cae8e5f3881cb1bcb02ab7fa4cbacf5b55525Mathias Agopian    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (pname) {
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_CROP_RECT_OES:
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(textureObject->crop_rect, params, 4*sizeof(GLint));
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1025b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian        texParameterx(target, pname, GLfixed(params[0]), c);
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexParameterf(
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, GLfloat 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, GLfixed(param), c);
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexParameterx(
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, GLfixed param)
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texParameterx(target, pname, param, c);
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1044b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopianvoid glTexParameteri(
1045b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian        GLenum target, GLenum pname, GLint param)
1046b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian{
1047b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian    ogles_context_t* c = ogles_context_t::get();
1048b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian    texParameterx(target, pname, GLfixed(param), c);
1049b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian}
1050b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glCompressedTexImage2D(
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLenum internalformat,
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLsizei width, GLsizei height, GLint border,
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLsizei imageSize, const GLvoid *data)
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (width<0 || height<0 || border!=0) {
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // "uncompress" the texture since pixelflinger doesn't support
1072076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // any compressed texture format natively.
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum format;
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum type;
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (internalformat) {
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB8_OES:
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB8_OES:
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGB;
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_BYTE;
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA8_OES:
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA8_OES:
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGBA;
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_BYTE;
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_R5_G6_B5_OES:
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_R5_G6_B5_OES:
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGB;
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_SHORT_5_6_5;
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA4_OES:
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA4_OES:
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGBA;
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_SHORT_4_4_4_4;
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB5_A1_OES:
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB5_A1_OES:
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGBA;
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_SHORT_5_5_5_1;
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
110118b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian#ifdef GL_OES_compressed_ETC1_RGB8_texture
110218b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian    case GL_ETC1_RGB8_OES:
110318b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        format      = GL_RGB;
110418b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        type        = GL_UNSIGNED_BYTE;
110518b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        break;
110618b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian#endif
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!data || !width || !height) {
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // unclear if this is an error or not...
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t size;
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface* surface;
111918b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian
112018b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian#ifdef GL_OES_compressed_ETC1_RGB8_texture
112118b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian    if (internalformat == GL_ETC1_RGB8_OES) {
112218b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        GLsizei compressedSize = etc1_get_encoded_data_size(width, height);
112318b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        if (compressedSize > imageSize) {
112418b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian            ogles_error(c, GL_INVALID_VALUE);
112518b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian            return;
112618b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        }
112718b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        int error = createTextureSurface(c, &surface, &size,
112818b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian                level, format, type, width, height);
112918b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        if (error) {
113018b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian            ogles_error(c, error);
113118b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian            return;
113218b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        }
113318b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian        if (etc1_decode_image(
113418b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian                (const etc1_byte*)data,
113518b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian                (etc1_byte*)surface->data,
113606735863719e08b44edebddcb97861f867bdc01dJack Palevich                width, height, 3, surface->stride*3) != 0) {
113718b915a1026dfe9d273ee3fd2139b7feed22008cMathias Agopian            ogles_error(c, GL_INVALID_OPERATION);
1138