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