TextureObjectManager.cpp revision 076b1cc3a9b90aa5b381a1ed268ca0b548444c9b
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()
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mCount(0), 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;
56076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#ifdef LIBAGL_USE_GRALLOC_COPYBITS
57076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    copybits_fd = -1;
58076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#endif // LIBAGL_USE_GRALLOC_COPYBITS
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid EGLTextureObject::copyParameters(const sp<EGLTextureObject>& old)
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    wraps = old->wraps;
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    wrapt = old->wrapt;
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    min_filter = old->min_filter;
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mag_filter = old->mag_filter;
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memcpy(crop_rect, old->crop_rect, sizeof(crop_rect));
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generate_mipmap = old->generate_mipmap;
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    direct = old->direct;
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t EGLTextureObject::allocateMipmaps()
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // here, by construction, mMipmaps=0 && mNumExtraLod=0
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!surface.data)
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_INIT;
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int w = surface.width;
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int h = surface.height;
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int numLods = 31 - gglClz(max(w,h));
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (numLods <= 0)
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mMipmaps = (GGLSurface*)malloc(numLods * sizeof(GGLSurface));
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mMipmaps)
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_MEMORY;
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(mMipmaps, 0, numLods * sizeof(GGLSurface));
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mNumExtraLod = numLods;
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid EGLTextureObject::freeMipmaps()
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mMipmaps) {
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<mNumExtraLod ; i++) {
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (mMipmaps[i].data) {
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                free(mMipmaps[i].data);
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        free(mMipmaps);
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mMipmaps = 0;
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mNumExtraLod = 0;
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GGLSurface& EGLTextureObject::mip(int lod) const
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (lod<=0 || !mMipmaps)
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return surface;
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    lod = min(lod-1, mNumExtraLod-1);
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mMipmaps[lod];
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGGLSurface& EGLTextureObject::editMip(int lod)
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GGLSurface&>(mip(lod));
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t EGLTextureObject::setSurface(GGLSurface const* s)
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: glFlush() on 's'
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mSize && surface.data) {
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        free(surface.data);
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    surface = *s;
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    internalformat = 0;
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we should keep the crop_rect, but it's delicate because
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the new size of the surface could make it invalid.
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // so for now, we just loose it.
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(crop_rect, 0, sizeof(crop_rect));
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // it would be nice if we could keep the generate_mipmap flag,
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we would have to generate them right now though.
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generate_mipmap = GL_FALSE;
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    direct = GL_TRUE;
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSize = 0;  // we don't own this surface
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mMipmaps)
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        freeMipmaps();
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mIsComplete = true;
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t EGLTextureObject::reallocate(
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint level, int w, int h, int s,
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int format, int compressedFormat, int bpr)
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t size = h * bpr;
152076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (level == 0)
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (size!=mSize || !surface.data) {
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (mSize && surface.data) {
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                free(surface.data);
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            surface.data = (GGLubyte*)malloc(size);
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!surface.data) {
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mSize = 0;
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mIsComplete = false;
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_MEMORY;
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mSize = size;
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.version = sizeof(GGLSurface);
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.width  = w;
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.height = h;
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.stride = s;
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.format = format;
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.compressedFormat = compressedFormat;
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mMipmaps)
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            freeMipmaps();
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mIsComplete = true;
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    else
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!mMipmaps) {
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (allocateMipmaps() != NO_ERROR)
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_MEMORY;
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
183076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGW_IF(level-1 >= mNumExtraLod,
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "specifying mipmap level %d, but # of level is %d",
185076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                level, mNumExtraLod+1);
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface& mipmap = editMip(level);
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mipmap.data)
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            free(mipmap.data);
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.data = (GGLubyte*)malloc(size);
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!mipmap.data) {
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            memset(&mipmap, 0, sizeof(GGLSurface));
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mIsComplete = false;
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_MEMORY;
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.version = sizeof(GGLSurface);
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.width  = w;
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.height = h;
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.stride = s;
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.format = format;
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.compressedFormat = compressedFormat;
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // check if the texture is complete
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mIsComplete = true;
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLSurface* prev = &surface;
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<mNumExtraLod ; i++) {
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GGLSurface* curr = mMipmaps + i;
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (curr->format != surface.format) {
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mIsComplete = false;
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                break;
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t w = (prev->width  >> 1) ? : 1;
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t h = (prev->height >> 1) ? : 1;
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (w != curr->width || h != curr->height) {
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mIsComplete = false;
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                break;
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            prev = curr;
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectEGLSurfaceManager::EGLSurfaceManager()
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : TokenManager(), mCount(0)
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectEGLSurfaceManager::~EGLSurfaceManager()
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // everything gets freed automatically here...
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::createTexture(GLuint name)
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> result;
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mTextures.indexOfKey(name) >= 0)
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return result; // already exists!
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    result = new EGLTextureObject();
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = mTextures.add(name, result);
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err < 0)
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.clear();
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return result;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::removeTexture(GLuint name)
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t index = mTextures.indexOfKey(name);
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        sp<EGLTextureObject> result(mTextures.valueAt(index));
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTextures.removeItemsAt(index);
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return result;
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::replaceTexture(GLuint name)
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> tex;
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        const sp<EGLTextureObject>& old = mTextures.valueAt(index);
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t refs = old->getStrongCount();
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (ggl_likely(refs == 1)) {
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we're the only owner
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex = old;
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // keep the texture's parameters
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex = new EGLTextureObject();
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex->copyParameters(old);
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTextures.removeItemsAt(index);
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTextures.add(name, tex);
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return tex;
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid EGLSurfaceManager::deleteTextures(GLsizei n, const GLuint *tokens)
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // free all textures
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (GLsizei i=0 ; i<n ; i++) {
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLuint t(*tokens++);
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (t) {
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTextures.removeItem(t);
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::texture(GLuint name)
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t index = mTextures.indexOfKey(name);
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0)
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return mTextures.valueAt(index);
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
313