TextureObjectManager.cpp revision 697526bc9e44ce61c88614f98387ae8bbf0a187e
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
2258a79f47457e9cae2f6880653b581fe3170b0b1fMathias Agopian#include <private/ui/android_natives_priv.h>
237189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectEGLTextureObject::EGLTextureObject()
280926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    : mSize(0)
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectEGLTextureObject::~EGLTextureObject()
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!direct) {
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mSize && surface.data)
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            free(surface.data);
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mMipmaps)
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            freeMipmaps();
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid EGLTextureObject::init()
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(&surface, 0, sizeof(surface));
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    surface.version = sizeof(surface);
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mMipmaps = 0;
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mNumExtraLod = 0;
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mIsComplete = false;
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    wraps = GL_REPEAT;
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    wrapt = GL_REPEAT;
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    min_filter = GL_LINEAR;
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mag_filter = GL_LINEAR;
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    internalformat = 0;
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(crop_rect, 0, sizeof(crop_rect));
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generate_mipmap = GL_FALSE;
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    direct = GL_FALSE;
580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    buffer = 0;
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;
1290926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    buffer = 0;
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we should keep the crop_rect, but it's delicate because
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the new size of the surface could make it invalid.
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // so for now, we just loose it.
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(crop_rect, 0, sizeof(crop_rect));
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // it would be nice if we could keep the generate_mipmap flag,
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we would have to generate them right now though.
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    generate_mipmap = GL_FALSE;
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    direct = GL_TRUE;
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSize = 0;  // we don't own this surface
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mMipmaps)
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        freeMipmaps();
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mIsComplete = true;
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
148697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchevstatus_t EGLTextureObject::setImage(ANativeWindowBuffer* native_buffer)
1490926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{
1500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    GGLSurface sur;
1510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.version = sizeof(GGLSurface);
1520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.width = native_buffer->width;
1530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.height= native_buffer->height;
1540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.stride= native_buffer->stride;
1550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.format= native_buffer->format;
1560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sur.data  = 0;
1570926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    setSurface(&sur);
1580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    buffer = native_buffer;
1590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    return NO_ERROR;
1600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian}
1610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t EGLTextureObject::reallocate(
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLint level, int w, int h, int s,
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int format, int compressedFormat, int bpr)
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t size = h * bpr;
167076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (level == 0)
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (size!=mSize || !surface.data) {
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (mSize && surface.data) {
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                free(surface.data);
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            surface.data = (GGLubyte*)malloc(size);
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!surface.data) {
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mSize = 0;
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mIsComplete = false;
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_MEMORY;
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mSize = size;
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.version = sizeof(GGLSurface);
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.width  = w;
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.height = h;
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.stride = s;
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.format = format;
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surface.compressedFormat = compressedFormat;
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mMipmaps)
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            freeMipmaps();
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mIsComplete = true;
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    else
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!mMipmaps) {
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (allocateMipmaps() != NO_ERROR)
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_MEMORY;
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
198076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGW_IF(level-1 >= mNumExtraLod,
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "specifying mipmap level %d, but # of level is %d",
200076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                level, mNumExtraLod+1);
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface& mipmap = editMip(level);
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mipmap.data)
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            free(mipmap.data);
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.data = (GGLubyte*)malloc(size);
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!mipmap.data) {
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            memset(&mipmap, 0, sizeof(GGLSurface));
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mIsComplete = false;
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_MEMORY;
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.version = sizeof(GGLSurface);
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.width  = w;
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.height = h;
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.stride = s;
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.format = format;
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mipmap.compressedFormat = compressedFormat;
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // check if the texture is complete
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mIsComplete = true;
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GGLSurface* prev = &surface;
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i=0 ; i<mNumExtraLod ; i++) {
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GGLSurface* curr = mMipmaps + i;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (curr->format != surface.format) {
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mIsComplete = false;
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                break;
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t w = (prev->width  >> 1) ? : 1;
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t h = (prev->height >> 1) ? : 1;
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (w != curr->width || h != curr->height) {
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mIsComplete = false;
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                break;
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            prev = curr;
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectEGLSurfaceManager::EGLSurfaceManager()
2450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    : TokenManager()
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectEGLSurfaceManager::~EGLSurfaceManager()
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // everything gets freed automatically here...
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::createTexture(GLuint name)
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> result;
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mTextures.indexOfKey(name) >= 0)
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return result; // already exists!
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    result = new EGLTextureObject();
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = mTextures.add(name, result);
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err < 0)
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.clear();
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return result;
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::removeTexture(GLuint name)
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t index = mTextures.indexOfKey(name);
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        sp<EGLTextureObject> result(mTextures.valueAt(index));
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTextures.removeItemsAt(index);
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return result;
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::replaceTexture(GLuint name)
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<EGLTextureObject> tex;
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t index = mTextures.indexOfKey(name);
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<EGLTextureObject>& old = mTextures.valueAt(index);
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t refs = old->getStrongCount();
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (ggl_likely(refs == 1)) {
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we're the only owner
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex = old;
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // keep the texture's parameters
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex = new EGLTextureObject();
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            tex->copyParameters(old);
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTextures.removeItemsAt(index);
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTextures.add(name, tex);
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return tex;
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid EGLSurfaceManager::deleteTextures(GLsizei n, const GLuint *tokens)
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // free all textures
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (GLsizei i=0 ; i<n ; i++) {
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLuint t(*tokens++);
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (t) {
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTextures.removeItem(t);
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<EGLTextureObject> EGLSurfaceManager::texture(GLuint name)
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t index = mTextures.indexOfKey(name);
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0)
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return mTextures.valueAt(index);
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
328