texture.cpp revision cfa316b9e759ca0e9ee80fd275f441666532f9b1
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
2658a79f47457e9cae2f6880653b581fe3170b0b1fMathias Agopian#include <private/ui/android_natives_priv.h>
27076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
28076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#ifdef LIBAGL_USE_GRALLOC_COPYBITS
29076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include "copybit.h"
30076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#endif // LIBAGL_USE_GRALLOC_COPYBITS
31076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void bindTextureTmu(
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex);
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid generateMipmap(ogles_context_t* c, GLint level);
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Init
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid ogles_init_texture(ogles_context_t* c)
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.packAlignment   = 4;
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.unpackAlignment = 4;
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // each context has a default named (0) texture (not shared)
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.defaultTexture = new EGLTextureObject();
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.defaultTexture->incStrong(c);
57076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // bind the default texture to each texture unit
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        bindTextureTmu(c, i, 0, c->textures.defaultTexture);
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memset(c->current.texture[i].v, 0, sizeof(vec4_t));
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->current.texture[i].Q = 0x10000;
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid ogles_uninit_texture(ogles_context_t* c)
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (c->textures.ggl)
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        gglUninit(c->textures.ggl);
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.defaultTexture->decStrong(c);
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (c->textures.tmu[i].texture)
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->textures.tmu[i].texture->decStrong(c);
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid validate_tmu(ogles_context_t* c, int i)
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texture_unit_t& u(c->textures.tmu[i]);
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (u.dirty) {
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.dirty = 0;
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.activeTexture(c, i);
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texGeni(c, GGL_S,
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texGeni(c, GGL_T,
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_WRAP_S, u.texture->wraps);
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_WRAP_T, u.texture->wrapt);
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // disable this texture unit if it's not complete
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!u.texture->isComplete()) {
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.disable(c, GGL_TEXTURE_2D);
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1050926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid ogles_validate_texture(ogles_context_t* c)
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (c->rasterizer.state.texture[i].enable)
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            validate_tmu(c, i);
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.activeTexture(c, c->textures.active);
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid invalidate_texture(ogles_context_t* c, int tmu, uint8_t flags = 0xFF) {
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.tmu[tmu].dirty = flags;
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1190926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian/*
1200926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian * If the active textures are EGLImage, they need to be locked before
121cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich * they can be used.
122cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich *
1230926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian * FIXME: code below is far from being optimal
124cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich *
1250926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian */
1260926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1270926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid ogles_lock_textures(ogles_context_t* c)
1280926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{
1290926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
1300926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        if (c->rasterizer.state.texture[i].enable) {
1310926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            texture_unit_t& u(c->textures.tmu[i]);
1320926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            android_native_buffer_t* native_buffer = u.texture->buffer;
1330926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (native_buffer) {
1340926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.activeTexture(c, i);
1350926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                hw_module_t const* pModule;
1360926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
1370926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    continue;
1380926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1390926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                gralloc_module_t const* module =
1400926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    reinterpret_cast<gralloc_module_t const*>(pModule);
14121c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian
142e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                void* vaddr;
14321c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian                int err = module->lock(module, native_buffer->handle,
1440926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                        GRALLOC_USAGE_SW_READ_OFTEN,
1450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                        0, 0, native_buffer->width, native_buffer->height,
146e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                        &vaddr);
1470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
148e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                u.texture->setImageBits(vaddr);
1490926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
1500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            }
1510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        }
1520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian}
1540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid ogles_unlock_textures(ogles_context_t* c)
1560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{
1570926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
1580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        if (c->rasterizer.state.texture[i].enable) {
1590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            texture_unit_t& u(c->textures.tmu[i]);
1600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            android_native_buffer_t* native_buffer = u.texture->buffer;
1610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (native_buffer) {
1620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.activeTexture(c, i);
1630926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                hw_module_t const* pModule;
1640926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
1650926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    continue;
1660926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1670926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                gralloc_module_t const* module =
1680926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    reinterpret_cast<gralloc_module_t const*>(pModule);
16921c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian
17021c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian                module->unlock(module, native_buffer->handle);
1710926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                u.texture->setImageBits(NULL);
1720926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
1730926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            }
1740926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        }
1750926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1760926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    c->rasterizer.procs.activeTexture(c, c->textures.active);
1770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian}
1780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Format conversion
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic uint32_t gl2format_table[6][4] = {
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // BYTE, 565, 4444, 5551
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_A_8,
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0, 0 },                        // GL_ALPHA
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_RGB_888,
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      GGL_PIXEL_FORMAT_RGB_565,
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0 },                           // GL_RGB
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_RGBA_8888,
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0,
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      GGL_PIXEL_FORMAT_RGBA_4444,
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      GGL_PIXEL_FORMAT_RGBA_5551 },     // GL_RGBA
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_L_8,
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0, 0 },                        // GL_LUMINANCE
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { GGL_PIXEL_FORMAT_LA_88,
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      0, 0, 0 },                        // GL_LUMINANCE_ALPHA
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project};
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic int32_t convertGLPixelFormat(GLint format, GLenum type)
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t fi = -1;
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t ti = -1;
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) {
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_ALPHA:              fi = 0;     break;
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_RGB:                fi = 1;     break;
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_RGBA:               fi = 2;     break;
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_LUMINANCE:          fi = 3;     break;
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_LUMINANCE_ALPHA:    fi = 4;     break;
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (type) {
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_BYTE:          ti = 0; break;
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_SHORT_5_6_5:   ti = 1; break;
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_SHORT_4_4_4_4: ti = 2; break;
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_UNSIGNED_SHORT_5_5_5_1: ti = 3; break;
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (fi==-1 || ti==-1)
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return gl2format_table[fi][ti];
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic GLenum validFormatType(ogles_context_t* c, GLenum format, GLenum type)
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum error = 0;
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (format<GL_ALPHA || format>GL_LUMINANCE_ALPHA) {
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_ENUM;
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT_4_4_4_4 &&
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type != GL_UNSIGNED_SHORT_5_5_5_1 && type != GL_UNSIGNED_SHORT_5_6_5) {
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_ENUM;
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (type == GL_UNSIGNED_SHORT_5_6_5 && format != GL_RGB) {
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_OPERATION;
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project         type == GL_UNSIGNED_SHORT_5_5_5_1)  && format != GL_RGBA) {
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        error = GL_INVALID_OPERATION;
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (error) {
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, error);
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return error;
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGGLContext* getRasterizer(ogles_context_t* c)
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLContext* ggl = c->textures.ggl;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ggl_unlikely(!ggl)) {
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // this is quite heavy the first time...
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        gglInit(&ggl);
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!ggl) {
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return 0;
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLfixed colors[4] = { 0, 0, 0, 0x10000 };
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->textures.ggl = ggl;
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->activeTexture(ggl, 0);
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->enable(ggl, GGL_TEXTURE_2D);
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->texEnvi(ggl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->disable(ggl, GGL_DITHER);
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->shadeModel(ggl, GGL_FLAT);
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ggl->color4xv(ggl, colors);
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return ggl;
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint copyPixels(
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_context_t* c,
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLSurface& dst,
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint xoffset, GLint yoffset,
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLSurface& src,
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint x, GLint y, GLsizei w, GLsizei h)
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((dst.format == src.format) &&
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.stride == src.stride) &&
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.width == src.width) &&
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.height == src.height) &&
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (dst.stride > 0) &&
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ((x|y) == 0) &&
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ((xoffset|yoffset) == 0))
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // this is a common case...
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLFormat& pixelFormat(c->rasterizer.formats[src.format]);
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t size = src.height * src.stride * pixelFormat.size;
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(dst.data, src.data, size);
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // use pixel-flinger to handle all the conversions
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLContext* ggl = getRasterizer(c);
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!ggl) {
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the only reason this would fail is because we ran out of memory
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return GL_OUT_OF_MEMORY;
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->colorBuffer(ggl, &dst);
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->bindTexture(ggl, &src);
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->texCoord2i(ggl, x-xoffset, y-yoffset);
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->recti(ggl, xoffset, yoffset, xoffset+w, yoffset+h);
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> getAndBindActiveTextureObject(ogles_context_t* c)
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> tex;
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int active = c->textures.active;
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GLuint name = c->textures.tmu[active].name;
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // free the reference to the previously bound object
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texture_unit_t& u(c->textures.tmu[active]);
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (u.texture)
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.texture->decStrong(c);
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (name == 0) {
324076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        // 0 is our local texture object, not shared with anyone.
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // But it affects all bound TMUs immediately.
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // (we need to invalidate all units bound to this texture object)
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->textures.defaultTexture;
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (c->textures.tmu[i].texture == tex.get())
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                invalidate_texture(c, i);
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // get a new texture object for that name
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->surfaceManager->replaceTexture(name);
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // bind this texture to the current active texture unit
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // and add a reference to this texture object
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture = tex.get();
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture->incStrong(c);
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.name = name;
342076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    invalidate_texture(c, active);
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return tex;
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid bindTextureTmu(
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex)
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (tex.get() == c->textures.tmu[tmu].texture)
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
351076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // free the reference to the previously bound object
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texture_unit_t& u(c->textures.tmu[tmu]);
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (u.texture)
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.texture->decStrong(c);
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // bind this texture to the current active texture unit
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // and add a reference to this texture object
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture = tex.get();
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.texture->incStrong(c);
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    u.name = texture;
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    invalidate_texture(c, tmu);
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint createTextureSurface(ogles_context_t* c,
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface** outSurface, int32_t* outSize, GLint level,
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum format, GLenum type, GLsizei width, GLsizei height,
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum compressedFormat = 0)
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // find out which texture is bound to the current unit
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int active = c->textures.active;
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GLuint name = c->textures.tmu[active].name;
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // convert the pixelformat to one we can handle
375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t formatIdx = convertGLPixelFormat(format, type);
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (formatIdx == 0) { // we don't know what to do with this
377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return GL_INVALID_OPERATION;
378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
379076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // figure out the size we need as well as the stride
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t align = c->textures.unpackAlignment-1;
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t size = bpr * height;
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t stride = bpr / pixelFormat.size;
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (level > 0) {
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int active = c->textures.active;
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        EGLTextureObject* tex = c->textures.tmu[active].texture;
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        status_t err = tex->reallocate(level,
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                width, height, stride, formatIdx, compressedFormat, bpr);
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (err != NO_ERROR)
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return GL_OUT_OF_MEMORY;
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface& surface = tex->editMip(level);
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *outSurface = &surface;
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *outSize = size;
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = tex->reallocate(level,
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            width, height, stride, formatIdx, compressedFormat, bpr);
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err != NO_ERROR)
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return GL_OUT_OF_MEMORY;
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    tex->internalformat = format;
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *outSurface = &tex->surface;
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *outSize = size;
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
412cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevichstatic size_t dataSizePalette4(int numLevels, int width, int height, int format)
413cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich{
414cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    int indexBits = 8;
415cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    int entrySize = 0;
416cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    switch (format) {
417cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGB8_OES:
418cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        indexBits = 4;
419cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        /* FALLTHROUGH */
420cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGB8_OES:
421cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        entrySize = 3;
422cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        break;
423cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
424cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGBA8_OES:
425cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        indexBits = 4;
426cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        /* FALLTHROUGH */
427cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGBA8_OES:
428cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        entrySize = 4;
429cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        break;
430cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
431cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_R5_G6_B5_OES:
432cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGBA4_OES:
433cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE4_RGB5_A1_OES:
434cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        indexBits = 4;
435cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        /* FALLTHROUGH */
436cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_R5_G6_B5_OES:
437cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGBA4_OES:
438cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    case GL_PALETTE8_RGB5_A1_OES:
439cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        entrySize = 2;
440cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        break;
441cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    }
442cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
443cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    size_t size = (1 << indexBits) * entrySize; // palette size
444cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
445cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    for (int i=0 ; i< numLevels ; i++) {
446cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        int w = (width  >> i) ? : 1;
447cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        int h = (height >> i) ? : 1;
448cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        int levelSize = h * ((w * indexBits) / 8) ? : 1;
449cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        size += levelSize;
450cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    }
451cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
452cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    return size;
453cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich}
454cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void decodePalette4(const GLvoid *data, int level, int width, int height,
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                           void *surface, int stride, int format)
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int indexBits = 8;
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int entrySize = 0;
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) {
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB8_OES:
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        indexBits = 4;
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        /* FALLTHROUGH */
465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB8_OES:
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        entrySize = 3;
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA8_OES:
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        indexBits = 4;
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        /* FALLTHROUGH */
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA8_OES:
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        entrySize = 4;
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_R5_G6_B5_OES:
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA4_OES:
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB5_A1_OES:
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        indexBits = 4;
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        /* FALLTHROUGH */
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_R5_G6_B5_OES:
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA4_OES:
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB5_A1_OES:
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        entrySize = 2;
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int paletteSize = (1 << indexBits) * entrySize;
489cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint8_t const* pixels = (uint8_t *)data + paletteSize;
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<level ; i++) {
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int w = (width  >> i) ? : 1;
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int h = (height >> i) ? : 1;
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        pixels += h * ((w * indexBits) / 8);
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    width  = (width  >> level) ? : 1;
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    height = (height >> level) ? : 1;
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (entrySize == 2) {
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint8_t const* const palette = (uint8_t*)data;
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int y=0 ; y<height ; y++) {
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t* p = (uint8_t*)surface + y*stride*2;
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (indexBits == 8) {
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x++) {
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 2 * (*pixels++);
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x+=2) {
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int v = *pixels++;
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 2 * (v >> 4);
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (x+1 < width) {
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        index = 2 * (v & 0xF);
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 0];
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 1];
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (entrySize == 3) {
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint8_t const* const palette = (uint8_t*)data;
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int y=0 ; y<height ; y++) {
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t* p = (uint8_t*)surface + y*stride*3;
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (indexBits == 8) {
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x++) {
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 3 * (*pixels++);
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x+=2) {
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int v = *pixels++;
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 3 * (v >> 4);
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (x+1 < width) {
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        index = 3 * (v & 0xF);
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 0];
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 1];
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 2];
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (entrySize == 4) {
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint8_t const* const palette = (uint8_t*)data;
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int y=0 ; y<height ; y++) {
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t* p = (uint8_t*)surface + y*stride*4;
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (indexBits == 8) {
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x++) {
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 4 * (*pixels++);
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 3];
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<width ; x+=2) {
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int v = *pixels++;
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int index = 4 * (v >> 4);
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 0];
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 1];
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 2];
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *p++ = palette[index + 3];
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (x+1 < width) {
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        index = 4 * (v & 0xF);
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 0];
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 1];
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 2];
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *p++ = palette[index + 3];
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 Project}
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid set_depth_and_fog(ogles_context_t* c, GLint z)
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we need to compute Zw
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t iterators[3];
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    iterators[1] = iterators[2] = 0;
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLfixed Zw;
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLfixed n = gglFloatToFixed(c->transforms.vpt.zNear);
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLfixed f = gglFloatToFixed(c->transforms.vpt.zFar);
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (z<=0)       Zw = n;
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    else if (z>=1)  Zw = f;
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    else            Zw = gglMulAddx(z, (f-n), n);
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (enables & GGL_ENABLE_FOG) {
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // set up fog if needed...
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        iterators[0] = c->fog.fog(c, Zw);
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.fogGrad3xv(c, iterators);
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (enables & GGL_ENABLE_DEPTH_TEST) {
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // set up z-test if needed...
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t z = (Zw & ~(Zw>>31));
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (z >= 0x10000)
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            z = 0xFFFF;
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        iterators[0] = (z << 16) | z;
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.zGrad3xv(c, iterators);
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Generate mimaps
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectextern status_t buildAPyramid(ogles_context_t* c, EGLTextureObject* tex);
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid generateMipmap(ogles_context_t* c, GLint level)
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (level == 0) {
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int active = c->textures.active;
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        EGLTextureObject* tex = c->textures.tmu[active].texture;
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (tex->generate_mipmap) {
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (buildAPyramid(c, tex) != NO_ERROR) {
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                ogles_error(c, GL_OUT_OF_MEMORY);
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return;
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void texParameterx(
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, GLfixed param, ogles_context_t* c)
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
643076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
644076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (pname) {
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_WRAP_S:
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_REPEAT) ||
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_CLAMP_TO_EDGE)) {
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->wraps = param;
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_WRAP_T:
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_REPEAT) ||
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_CLAMP_TO_EDGE)) {
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->wrapt = param;
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_MIN_FILTER:
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_NEAREST) ||
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR) ||
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_NEAREST_MIPMAP_NEAREST) ||
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR_MIPMAP_NEAREST) ||
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_NEAREST_MIPMAP_LINEAR) ||
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR_MIPMAP_LINEAR)) {
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->min_filter = param;
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_MAG_FILTER:
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((param == GL_NEAREST) ||
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (param == GL_LINEAR)) {
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            textureObject->mag_filter = param;
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto invalid_enum;
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_GENERATE_MIPMAP:
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        textureObject->generate_mipmap = param;
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectinvalid_enum:
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    invalidate_texture(c, c->textures.active);
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
694076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
695076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatic void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_context_t* c)
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
6980926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    ogles_lock_textures(c);
699cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    y = gglIntToFixed(cbSurface.height) - (y + h);
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    w >>= FIXED_BITS;
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    h >>= FIXED_BITS;
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // set up all texture units
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!c->rasterizer.state.texture[i].enable)
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            continue;
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t texcoords[8];
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texture_unit_t& u(c->textures.tmu[i]);
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // validate this tmu (bind, wrap, filter)
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        validate_tmu(c, i);
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // we CLAMP here, which works with premultiplied (s,t)
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c,
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP);
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texParameteri(c,
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP);
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        u.dirty = 0xFF; // XXX: should be more subtle
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
722076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        EGLTextureObject* textureObject = u.texture;
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Ucr = textureObject->crop_rect[0] << 16;
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Vcr = textureObject->crop_rect[1] << 16;
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Wcr = textureObject->crop_rect[2] << 16;
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Hcr = textureObject->crop_rect[3] << 16;
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // computes texture coordinates (pre-multiplied)
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t dsdx = Wcr / w;   // dsdx =  ((Wcr/w)/Wt)*Wt
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t dtdy =-Hcr / h;   // dtdy = -((Hcr/h)/Ht)*Ht
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t s0   = Ucr       - gglMulx(dsdx, x); // s0 = Ucr - x * dsdx
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t t0   = (Vcr+Hcr) - gglMulx(dtdy, y); // t0 = (Vcr+Hcr) - y*dtdy
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[0] = s0;
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[1] = dsdx;
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[2] = 0;
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[3] = t0;
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[4] = 0;
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[5] = dtdy;
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[6] = 0;
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texcoords[7] = 0;
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texCoordGradScale8xv(c, i, texcoords);
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        set_depth_and_fog(c, z);
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.activeTexture(c, c->textures.active);
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.color4xv(c, c->currentColorClamped.v);
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.disable(c, GGL_W_LERP);
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.disable(c, GGL_AA);
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.shadeModel(c, GL_FLAT);
753076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    c->rasterizer.procs.recti(c,
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(x),
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(y),
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(x)+w,
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFixedToIntRound(y)+h);
7580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
7590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    ogles_unlock_textures(c);
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
762076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatic void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
763076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_context_t* c)
764076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
765076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#ifdef LIBAGL_USE_GRALLOC_COPYBITS
766076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (drawTexiOESWithCopybit(gglFixedToIntRound(x),
767076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            gglFixedToIntRound(y), gglFixedToIntRound(z),
768076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            gglFixedToIntRound(w), gglFixedToIntRound(h), c)) {
769076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return;
770076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
771076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#else
772076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // quickly reject empty rects
773076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if ((w|h) <= 0)
774076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return;
775076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#endif
776076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    drawTexxOESImp(x, y, z, w, h, c);
777076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
778076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_context_t* c)
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // All coordinates are integer, so if we have only one
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // texture unit active and no scaling is required
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // THEN, we can use our special 1:1 mapping
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // which is a lot faster.
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) {
787076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#ifdef LIBAGL_USE_GRALLOC_COPYBITS
788076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (drawTexiOESWithCopybit(x, y, z, w, h, c)) {
789076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            return;
790076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
791076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#endif
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int tmu = 0;
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        texture_unit_t& u(c->textures.tmu[tmu]);
794076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        EGLTextureObject* textureObject = u.texture;
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Wcr = textureObject->crop_rect[2];
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLint Hcr = textureObject->crop_rect[3];
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((w == Wcr) && (h == -Hcr)) {
799076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#ifndef LIBAGL_USE_GRALLOC_COPYBITS
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if ((w|h) <= 0) return; // quickly reject empty rects
801076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#endif
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (u.dirty) {
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.activeTexture(c, tmu);
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.texGeni(c, GGL_S,
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.texGeni(c, GGL_T,
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            u.dirty = 0xFF; // XXX: should be more subtle
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.activeTexture(c, c->textures.active);
817076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            y = cbSurface.height - (y + h);
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint Ucr = textureObject->crop_rect[0];
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint Vcr = textureObject->crop_rect[1];
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint s0  = Ucr - x;
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint t0  = (Vcr + Hcr) - y;
824076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLuint tw = textureObject->surface.width;
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLuint th = textureObject->surface.height;
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if ((uint32_t(s0+x+w) > tw) || (uint32_t(t0+y+h) > th)) {
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // The GL spec is unclear about what should happen
829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // in this case, so we just use the slow case, which
830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // at least won't crash
831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                goto slow_case;
832076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8340926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            ogles_lock_textures(c);
8350926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.texCoord2i(c, s0, t0);
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t enables = c->rasterizer.state.enables;
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                set_depth_and_fog(c, z);
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.color4xv(c, c->currentColorClamped.v);
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.disable(c, GGL_W_LERP);
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.disable(c, GGL_AA);
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.shadeModel(c, GL_FLAT);
845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c->rasterizer.procs.recti(c, x, y, x+w, y+h);
846cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
8470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            ogles_unlock_textures(c);
8480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return;
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectslow_case:
854076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    drawTexxOESImp(
855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglIntToFixed(x), gglIntToFixed(y), gglIntToFixed(z),
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglIntToFixed(w), gglIntToFixed(h),
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c);
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace android;
865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Texture API
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glActiveTexture(GLenum texture)
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(texture-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->textures.active = texture - GL_TEXTURE0;
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.activeTexture(c, c->textures.active);
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glBindTexture(GLenum target, GLuint texture)
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Bind or create a texture
892076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<EGLTextureObject> tex;
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (texture == 0) {
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // 0 is our local texture object
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->textures.defaultTexture;
896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tex = c->surfaceManager->texture(texture);
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (ggl_unlikely(tex == 0)) {
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex = c->surfaceManager->createTexture(texture);
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (tex == 0) {
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                ogles_error(c, GL_OUT_OF_MEMORY);
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return;
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bindTextureTmu(c, c->textures.active, texture, tex);
907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glGenTextures(GLsizei n, GLuint *textures)
910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (n<0) {
913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // generate unique (shared) texture names
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->surfaceManager->getToken(n, textures);
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDeleteTextures(GLsizei n, const GLuint *textures)
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (n<0) {
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If deleting a bound texture, bind this unit to 0
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int t=0 ; t<GGL_TEXTURE_UNIT_COUNT ; t++) {
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (c->textures.tmu[t].name == 0)
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            continue;
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<n ; i++) {
933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (textures[i] && (textures[i] == c->textures.tmu[t].name)) {
934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // bind this tmu to texture 0
935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                sp<EGLTextureObject> tex(c->textures.defaultTexture);
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                bindTextureTmu(c, t, 0, tex);
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->surfaceManager->deleteTextures(n, textures);
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->surfaceManager->recycleTokens(n, textures);
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glMultiTexCoord4f(
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(target-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int tmu = target-GL_TEXTURE0;
953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].S = gglFloatToFixed(s);
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].T = gglFloatToFixed(t);
955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].R = gglFloatToFixed(r);
956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].Q = gglFloatToFixed(q);
957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glMultiTexCoord4x(
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(target-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int tmu = target-GL_TEXTURE0;
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].S = s;
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].T = t;
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].R = r;
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->current.texture[tmu].Q = q;
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glPixelStorei(GLenum pname, GLint param)
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((pname != GL_PACK_ALIGNMENT) && (pname != GL_UNPACK_ALIGNMENT)) {
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
980076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((param<=0 || param>8) || (param & (param-1))) {
982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_PACK_ALIGNMENT)
986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->textures.packAlignment = param;
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_UNPACK_ALIGNMENT)
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->textures.unpackAlignment = param;
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvf(GLenum target, GLenum pname, GLfloat param)
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.texEnvi(c, target, pname, GLint(param));
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvfv(
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, const GLfloat *params)
999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_TEXTURE_ENV_MODE) {
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texEnvi(c, target, pname, GLint(*params));
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pname == GL_TEXTURE_ENV_COLOR) {
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLfixed fixed[4];
1007edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<4 ; i++)
1008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            fixed[i] = gglFloatToFixed(params[i]);
1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        c->rasterizer.procs.texEnvxv(c, target, pname, fixed);
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_error(c, GL_INVALID_ENUM);
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvx(GLenum target, GLenum pname, GLfixed param)
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.texEnvi(c, target, pname, param);
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexEnvxv(
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, const GLfixed *params)
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c->rasterizer.procs.texEnvxv(c, target, pname, params);
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexParameteriv(
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, const GLint* params)
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GGL_TEXTURE_2D) {
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (pname) {
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_TEXTURE_CROP_RECT_OES:
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(textureObject->crop_rect, params, 4*sizeof(GLint));
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1043b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian        texParameterx(target, pname, GLfixed(params[0]), c);
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexParameterf(
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, GLfloat param)
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texParameterx(target, pname, GLfixed(param), c);
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexParameterx(
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLenum pname, GLfixed param)
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    texParameterx(target, pname, param, c);
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1062b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopianvoid glTexParameteri(
1063b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian        GLenum target, GLenum pname, GLint param)
1064b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian{
1065b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian    ogles_context_t* c = ogles_context_t::get();
1066b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian    texParameterx(target, pname, GLfixed(param), c);
1067b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian}
1068b12f99b31528a9ab9aa8f5c9fcfb57ad4c8b0517Mathias Agopian
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glCompressedTexImage2D(
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLenum internalformat,
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLsizei width, GLsizei height, GLint border,
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLsizei imageSize, const GLvoid *data)
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((internalformat < GL_PALETTE4_RGB8_OES ||
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project         internalformat > GL_PALETTE8_RGB5_A1_OES)) {
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (width<0 || height<0 || border!=0) {
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // "uncompress" the texture since pixelflinger doesn't support
1095076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // any compressed texture format natively.
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum format;
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum type;
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (internalformat) {
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB8_OES:
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB8_OES:
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGB;
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_BYTE;
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA8_OES:
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA8_OES:
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGBA;
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_BYTE;
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_R5_G6_B5_OES:
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_R5_G6_B5_OES:
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGB;
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_SHORT_5_6_5;
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGBA4_OES:
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGBA4_OES:
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGBA;
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_SHORT_4_4_4_4;
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE8_RGB5_A1_OES:
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_PALETTE4_RGB5_A1_OES:
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format      = GL_RGBA;
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type        = GL_UNSIGNED_SHORT_5_5_5_1;
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!data || !width || !height) {
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // unclear if this is an error or not...
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t size;
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface* surface;
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // all mipmap levels are specified at once.
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int numLevels = level<0 ? -level : 1;
1138cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
1139cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    if (dataSizePalette4(numLevels, width, height, format) > imageSize) {
1140cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        ogles_error(c, GL_INVALID_VALUE);
1141cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich        return;
1142cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich    }
1143cfa316b9e759ca0e9ee80fd275f441666532f9b1Jack Palevich
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<numLevels ; i++) {
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int lod_w = (width  >> i) ? : 1;
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int lod_h = (height >> i) ? : 1;
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int error = createTextureSurface(c, &surface, &size,
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                i, format, type, lod_w, lod_h);
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (error) {
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ogles_error(c, error);
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return;
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        decodePalette4(data, i, width, height,
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                surface->data, surface->stride, internalformat);
1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexImage2D(
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLint internalformat,
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLsizei width, GLsizei height, GLint border,
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum format, GLenum type, const GLvoid *pixels)
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1165076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (target != GL_TEXTURE_2D) {
1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (width<0 || height<0 || border!=0 || level < 0) {
1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1173076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (format != (GLenum)internalformat) {
1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_OPERATION);
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (validFormatType(c, format, type)) {
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t size = 0;
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface* surface = 0;
1183076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    int error = createTextureSurface(c, &surface, &size,
1184076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            level, format, type, width, height);
1185076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (error) {
1186076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_error(c, error);
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pixels) {
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int32_t formatIdx = convertGLPixelFormat(format, type);
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int32_t align = c->textures.unpackAlignment-1;
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t size = bpr * height;
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int32_t stride = bpr / pixelFormat.size;
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface userSurface;
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.version = sizeof(userSurface);
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.width  = width;
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.height = height;
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.stride = stride;
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.format = formatIdx;
1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.compressedFormat = 0;
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        userSurface.data = (GLubyte*)pixels;
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1207076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        int err = copyPixels(c, *surface, 0, 0, userSurface, 0, 0, width, height);
1208076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (err) {
1209076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            ogles_error(c, err);
1210076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            return;
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1212076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        generateMipmap(c, level);
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glCompressedTexSubImage2D(
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLint xoffset,
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint yoffset, GLsizei width, GLsizei height,
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum format, GLsizei imageSize,
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLvoid *data)
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_error(c, GL_INVALID_ENUM);
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glTexSubImage2D(
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLint xoffset,
1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint yoffset, GLsizei width, GLsizei height,
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum format, GLenum type, const GLvoid *pixels)
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (xoffset<0 || yoffset<0 || width<0 || height<0 || level<0) {
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (validFormatType(c, format, type)) {
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // find out which texture is bound to the current unit
1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int active = c->textures.active;
1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLTextureObject* tex = c->textures.tmu[active].texture;
1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& surface(tex->mip(level));
1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!tex->internalformat || tex->direct) {
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_OPERATION);
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((xoffset + width  > GLsizei(surface.width)) ||
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (yoffset + height > GLsizei(surface.height))) {
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!width || !height) {
1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return; // okay, but no-op.
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // figure out the size we need as well as the stride
1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t formatIdx = convertGLPixelFormat(format, type);
1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (formatIdx == 0) { // we don't know what to do with this
1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_OPERATION);
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t align = c->textures.unpackAlignment-1;
1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
1274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t size = bpr * height;
1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t stride = bpr / pixelFormat.size;
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface userSurface;
1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.version = sizeof(userSurface);
1278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.width  = width;
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.height = height;
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.stride = stride;
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.format = formatIdx;
1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.compressedFormat = 0;
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.data = (GLubyte*)pixels;
1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int err = copyPixels(c,
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            surface, xoffset, yoffset,
1287076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            userSurface, 0, 0, width, height);
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) {
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, err);
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generateMipmap(c, level);
1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // since we only changed the content of the texture, we don't need
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // to call bindTexture on the main rasterizer.
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glCopyTexImage2D(
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLenum internalformat,
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint x, GLint y, GLsizei width, GLsizei height,
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint border)
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (internalformat<GL_ALPHA || internalformat>GL_LUMINANCE_ALPHA) {
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (width<0 || height<0 || border!=0 || level<0) {
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum format = 0;
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GLenum type = GL_UNSIGNED_BYTE;
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int cbFormatIdx = cbSurface.format;
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (cbFormatIdx) {
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGB_565:
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type = GL_UNSIGNED_SHORT_5_6_5;
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBA_5551:
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type = GL_UNSIGNED_SHORT_5_5_5_1;
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBA_4444:
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type = GL_UNSIGNED_SHORT_4_4_4_4;
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (internalformat) {
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_ALPHA:
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_LUMINANCE_ALPHA:
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_LUMINANCE:
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        type = GL_UNSIGNED_BYTE;
1340076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        break;
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // figure out the format to use for the new texture
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (cbFormatIdx) {
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBA_8888:
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_A_8:
1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBA_5551:
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBA_4444:
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = internalformat;
1350076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        break;
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGBX_8888:
1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGB_888:
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_RGB_565:
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GGL_PIXEL_FORMAT_L_8:
1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (internalformat) {
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case GL_LUMINANCE:
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case GL_RGB:
1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            format = internalformat;
1359076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            break;
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (format == 0) {
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // invalid combination
1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // create the new texture...
1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t size;
1372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface* surface;
1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int error = createTextureSurface(c, &surface, &size,
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            level, format, type, width, height);
1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (error) {
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, error);
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1379076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // The bottom row is stored first in textures
1381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface txSurface(*surface);
1382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    txSurface.stride = -txSurface.stride;
1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (x,y) is the lower-left corner of colorBuffer
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    y = cbSurface.height - (y + height);
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int err = copyPixels(c,
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            txSurface, 0, 0,
1389076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            cbSurface, x, y, cbSurface.width, cbSurface.height);
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) {
1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, err);
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generateMipmap(c, level);
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glCopyTexSubImage2D(
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum target, GLint level, GLint xoffset, GLint yoffset,
1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint x, GLint y, GLsizei width, GLsizei height)
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (target != GL_TEXTURE_2D) {
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (xoffset<0 || yoffset<0 || width<0 || height<0 || level<0) {
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!width || !height) {
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return; // okay, but no-op.
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // find out which texture is bound to the current unit
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int active = c->textures.active;
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLTextureObject* tex = c->textures.tmu[active].texture;
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& surface(tex->mip(level));
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!tex->internalformat) {
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_OPERATION);
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((xoffset + width  > GLsizei(surface.width)) ||
1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (yoffset + height > GLsizei(surface.height))) {
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // The bottom row is stored first in textures
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface txSurface(surface);
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    txSurface.stride = -txSurface.stride;
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (x,y) is the lower-left corner of colorBuffer
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    y = cbSurface.height - (y + height);
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int err = copyPixels(c,
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            surface, xoffset, yoffset,
1439076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            cbSurface, x, y, width, height);
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err) {
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, err);
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generateMipmap(c, level);
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glReadPixels(
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint x, GLint y, GLsizei width, GLsizei height,
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLenum format, GLenum type, GLvoid *pixels)
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((format != GL_RGBA) && (format != GL_RGB)) {
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((type != GL_UNSIGNED_BYTE) && (type != GL_UNSIGNED_SHORT_5_6_5)) {
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_ENUM);
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (width<0 || height<0) {
1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (x<0 || x<0) {
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t formatIdx = GGL_PIXEL_FORMAT_NONE;
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((format == GL_RGBA) && (type == GL_UNSIGNED_BYTE)) {
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        formatIdx = GGL_PIXEL_FORMAT_RGBA_8888;
1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if ((format == GL_RGB) && (type == GL_UNSIGNED_SHORT_5_6_5)) {
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        formatIdx = GGL_PIXEL_FORMAT_RGB_565;
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_OPERATION);
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface& readSurface = c->rasterizer.state.buffers.read.s;
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((x+width > GLint(readSurface.width)) ||
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (y+height > GLint(readSurface.height))) {
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_INVALID_VALUE);
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t align = c->textures.packAlignment-1;
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t stride = bpr / pixelFormat.size;
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLSurface userSurface;
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.version = sizeof(userSurface);
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.width  = width;
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.height = height;
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.stride = -stride; // bottom row is transfered first
1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.format = formatIdx;
1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.compressedFormat = 0;
1499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    userSurface.data = (GLubyte*)pixels;
1500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // use pixel-flinger to handle all the conversions
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    GGLContext* ggl = getRasterizer(c);
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!ggl) {
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the only reason this would fail is because we ran out of memory
1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ogles_error(c, GL_OUT_OF_MEMORY);
1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1509076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    ggl->colorBuffer(ggl, &userSurface);  // destination is user buffer
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->bindTexture(ggl, &readSurface);  // source is read-buffer
1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->texCoord2i(ggl, x, readSurface.height - (y + height));
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ggl->recti(ggl, 0, 0, width, height);
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark DrawTexture Extension
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexsvOES(const GLshort* coords) {
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexiOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexivOES(const GLint* coords) {
1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexiOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexsOES(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h) {
1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexiOES(x, y, z, w, h, c);
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h) {
1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexiOES(x, y, z, w, h, c);
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexfvOES(const GLfloat* coords) {
1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexxOES(
1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(coords[0]),
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(coords[1]),
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(coords[2]),
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(coords[3]),
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(coords[4]),
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c);
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexxvOES(const GLfixed* coords) {
1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexxOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h){
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexxOES(
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(x), gglFloatToFixed(y), gglFloatToFixed(z),
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gglFloatToFixed(w), gglFloatToFixed(h),
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c);
1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) {
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ogles_context_t* c = ogles_context_t::get();
1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    drawTexxOES(x, y, z, w, h, c);
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1563076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1564076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
1565076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#if 0
1566076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#pragma mark -
1567076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#pragma mark EGL Image Extension
1568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#endif
1569076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1570076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
1571076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
1572076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    ogles_context_t* c = ogles_context_t::get();
1573076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (target != GL_TEXTURE_2D) {
1574076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_error(c, GL_INVALID_ENUM);
1575076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return;
1576076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1577076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1578076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
1579076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
1580076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_error(c, GL_INVALID_VALUE);
1581076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return;
1582076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1583076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
1584076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        ogles_error(c, GL_INVALID_VALUE);
1585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return;
1586076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1588076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // bind it to the texture unit
1589076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
15900926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    tex->setImage(native_buffer);
1591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#ifdef LIBAGL_USE_GRALLOC_COPYBITS
15930a3139a21e628093893bba8ca0bb0b4742e0522cMathias Agopian    tex->try_copybit = false;
1594f13901eaa98241b52062a3ae3b016badce3dee0cMathias Agopian    if (c->copybits.blitEngine != NULL) {
15950a3139a21e628093893bba8ca0bb0b4742e0522cMathias Agopian        tex->try_copybit = true;
1596076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1597076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#endif // LIBAGL_USE_GRALLOC_COPYBITS
1598076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1599076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1600076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
1601076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
1602076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1603