1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ** Copyright 2006, The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project **
4076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian ** Licensed under the Apache License, Version 2.0 (the "License");
5076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian ** you may not use this file except in compliance with the License.
6076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian ** You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project **
8076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian **     http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project **
10076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian ** Unless required by applicable law or agreed to in writing, software
11076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian ** distributed under the License is distributed on an "AS IS" BASIS,
12076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian ** See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ** limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "context.h"
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "TextureObjectManager.h"
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectEGLTextureObject::EGLTextureObject()
260926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    : mSize(0)
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectEGLTextureObject::~EGLTextureObject()
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!direct) {
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mSize && surface.data)
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            free(surface.data);
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mMipmaps)
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            freeMipmaps();
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid EGLTextureObject::init()
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(&surface, 0, sizeof(surface));
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    surface.version = sizeof(surface);
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mMipmaps = 0;
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mNumExtraLod = 0;
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mIsComplete = false;
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    wraps = GL_REPEAT;
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    wrapt = GL_REPEAT;
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    min_filter = GL_LINEAR;
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mag_filter = GL_LINEAR;
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    internalformat = 0;
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(crop_rect, 0, sizeof(crop_rect));
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generate_mipmap = GL_FALSE;
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    direct = GL_FALSE;
560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    buffer = 0;
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid EGLTextureObject::copyParameters(const sp<EGLTextureObject>& old)
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    wraps = old->wraps;
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    wrapt = old->wrapt;
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    min_filter = old->min_filter;
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mag_filter = old->mag_filter;
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memcpy(crop_rect, old->crop_rect, sizeof(crop_rect));
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generate_mipmap = old->generate_mipmap;
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    direct = old->direct;
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t EGLTextureObject::allocateMipmaps()
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // here, by construction, mMipmaps=0 && mNumExtraLod=0
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!surface.data)
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_INIT;
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int w = surface.width;
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int h = surface.height;
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int numLods = 31 - gglClz(max(w,h));
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (numLods <= 0)
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mMipmaps = (GGLSurface*)malloc(numLods * sizeof(GGLSurface));
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mMipmaps)
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_MEMORY;
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(mMipmaps, 0, numLods * sizeof(GGLSurface));
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mNumExtraLod = numLods;
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid EGLTextureObject::freeMipmaps()
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mMipmaps) {
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<mNumExtraLod ; i++) {
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (mMipmaps[i].data) {
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                free(mMipmaps[i].data);
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        free(mMipmaps);
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mMipmaps = 0;
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mNumExtraLod = 0;
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GGLSurface& EGLTextureObject::mip(int lod) const
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (lod<=0 || !mMipmaps)
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return surface;
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    lod = min(lod-1, mNumExtraLod-1);
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mMipmaps[lod];
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGGLSurface& EGLTextureObject::editMip(int lod)
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GGLSurface&>(mip(lod));
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t EGLTextureObject::setSurface(GGLSurface const* s)
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: glFlush() on 's'
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mSize && surface.data) {
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        free(surface.data);
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    surface = *s;
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    internalformat = 0;
1270926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    buffer = 0;
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we should keep the crop_rect, but it's delicate because
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the new size of the surface could make it invalid.
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // so for now, we just loose it.
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(crop_rect, 0, sizeof(crop_rect));
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // it would be nice if we could keep the generate_mipmap flag,
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we would have to generate them right now though.
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generate_mipmap = GL_FALSE;
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    direct = GL_TRUE;
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSize = 0;  // we don't own this surface
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mMipmaps)
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        freeMipmaps();
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mIsComplete = true;
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
146697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchevstatus_t EGLTextureObject::setImage(ANativeWindowBuffer* native_buffer)
1470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{
1480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    GGLSurface sur;
1490926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.version = sizeof(GGLSurface);
1500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.width = native_buffer->width;
1510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.height= native_buffer->height;
1520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.stride= native_buffer->stride;
1530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.format= native_buffer->format;
1540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.data  = 0;
1550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    setSurface(&sur);
1560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    buffer = native_buffer;
1570926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    return NO_ERROR;
1580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian}
1590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t EGLTextureObject::reallocate(
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint level, int w, int h, int s,
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int format, int compressedFormat, int bpr)
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t size = h * bpr;
165076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (level == 0)
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (size!=mSize || !surface.data) {
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (mSize && surface.data) {
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                free(surface.data);
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            surface.data = (GGLubyte*)malloc(size);
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!surface.data) {
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mSize = 0;
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mIsComplete = false;
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_MEMORY;
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mSize = size;
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.version = sizeof(GGLSurface);
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.width  = w;
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.height = h;
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.stride = s;
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.format = format;
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.compressedFormat = compressedFormat;
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mMipmaps)
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            freeMipmaps();
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mIsComplete = true;
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    else
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!mMipmaps) {
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (allocateMipmaps() != NO_ERROR)
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_MEMORY;
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19632397c1cd3327905173b36baa6fd1c579bc328ffSteve Block        ALOGW_IF(level-1 >= mNumExtraLod,
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "specifying mipmap level %d, but # of level is %d",
198076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                level, mNumExtraLod+1);
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface& mipmap = editMip(level);
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mipmap.data)
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            free(mipmap.data);
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.data = (GGLubyte*)malloc(size);
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!mipmap.data) {
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            memset(&mipmap, 0, sizeof(GGLSurface));
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mIsComplete = false;
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_MEMORY;
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.version = sizeof(GGLSurface);
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.width  = w;
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.height = h;
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.stride = s;
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.format = format;
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.compressedFormat = compressedFormat;
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // check if the texture is complete
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mIsComplete = true;
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLSurface* prev = &surface;
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<mNumExtraLod ; i++) {
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GGLSurface* curr = mMipmaps + i;
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (curr->format != surface.format) {
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mIsComplete = false;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                break;
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t w = (prev->width  >> 1) ? : 1;
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t h = (prev->height >> 1) ? : 1;
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (w != curr->width || h != curr->height) {
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mIsComplete = false;
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                break;
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            prev = curr;
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectEGLSurfaceManager::EGLSurfaceManager()
2430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    : TokenManager()
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectEGLSurfaceManager::~EGLSurfaceManager()
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // everything gets freed automatically here...
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::createTexture(GLuint name)
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> result;
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mTextures.indexOfKey(name) >= 0)
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return result; // already exists!
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    result = new EGLTextureObject();
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = mTextures.add(name, result);
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err < 0)
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.clear();
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return result;
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::removeTexture(GLuint name)
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t index = mTextures.indexOfKey(name);
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        sp<EGLTextureObject> result(mTextures.valueAt(index));
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTextures.removeItemsAt(index);
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return result;
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::replaceTexture(GLuint name)
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> tex;
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t index = mTextures.indexOfKey(name);
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<EGLTextureObject>& old = mTextures.valueAt(index);
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t refs = old->getStrongCount();
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (ggl_likely(refs == 1)) {
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we're the only owner
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex = old;
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // keep the texture's parameters
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex = new EGLTextureObject();
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex->copyParameters(old);
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTextures.removeItemsAt(index);
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTextures.add(name, tex);
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return tex;
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid EGLSurfaceManager::deleteTextures(GLsizei n, const GLuint *tokens)
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // free all textures
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (GLsizei i=0 ; i<n ; i++) {
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLuint t(*tokens++);
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (t) {
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTextures.removeItem(t);
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::texture(GLuint name)
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t index = mTextures.indexOfKey(name);
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0)
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return mTextures.valueAt(index);
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
326