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