auto import from //depot/cupcake/@135843
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
new file mode 100644
index 0000000..ce31854
--- /dev/null
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -0,0 +1,309 @@
+/*
+ ** Copyright 2006, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License"); 
+ ** you may not use this file except in compliance with the License. 
+ ** You may obtain a copy of the License at 
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0 
+ **
+ ** Unless required by applicable law or agreed to in writing, software 
+ ** distributed under the License is distributed on an "AS IS" BASIS, 
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ ** See the License for the specific language governing permissions and 
+ ** limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "context.h"
+#include "TextureObjectManager.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+EGLTextureObject::EGLTextureObject()
+    : mCount(0), mSize(0)
+{
+    init();
+}
+
+EGLTextureObject::~EGLTextureObject()
+{
+    if (!direct) {
+        if (mSize && surface.data)
+            free(surface.data);
+        if (mMipmaps)
+            freeMipmaps();
+    }
+}
+
+void EGLTextureObject::init()
+{
+    memset(&surface, 0, sizeof(surface));
+    surface.version = sizeof(surface);
+    mMipmaps = 0;
+    mNumExtraLod = 0;
+    mIsComplete = false;
+    wraps = GL_REPEAT;
+    wrapt = GL_REPEAT;
+    min_filter = GL_LINEAR;
+    mag_filter = GL_LINEAR;
+    internalformat = 0;
+    memset(crop_rect, 0, sizeof(crop_rect));
+    generate_mipmap = GL_FALSE;
+    direct = GL_FALSE;
+}
+
+void EGLTextureObject::copyParameters(const sp<EGLTextureObject>& old)
+{
+    wraps = old->wraps;
+    wrapt = old->wrapt;
+    min_filter = old->min_filter;
+    mag_filter = old->mag_filter;
+    memcpy(crop_rect, old->crop_rect, sizeof(crop_rect));
+    generate_mipmap = old->generate_mipmap;
+    direct = old->direct;
+}
+
+status_t EGLTextureObject::allocateMipmaps()
+{
+    // here, by construction, mMipmaps=0 && mNumExtraLod=0
+
+    if (!surface.data)
+        return NO_INIT;
+
+    int w = surface.width;
+    int h = surface.height;
+    const int numLods = 31 - gglClz(max(w,h));
+    if (numLods <= 0)
+        return NO_ERROR;
+
+    mMipmaps = (GGLSurface*)malloc(numLods * sizeof(GGLSurface));
+    if (!mMipmaps)
+        return NO_MEMORY;
+
+    memset(mMipmaps, 0, numLods * sizeof(GGLSurface));
+    mNumExtraLod = numLods;
+    return NO_ERROR;
+}
+
+void EGLTextureObject::freeMipmaps()
+{
+    if (mMipmaps) {
+        for (int i=0 ; i<mNumExtraLod ; i++) {
+            if (mMipmaps[i].data) {
+                free(mMipmaps[i].data);
+            }
+        }
+        free(mMipmaps);
+        mMipmaps = 0;
+        mNumExtraLod = 0;
+    }
+}
+
+const GGLSurface& EGLTextureObject::mip(int lod) const
+{
+    if (lod<=0 || !mMipmaps)
+        return surface;
+    lod = min(lod-1, mNumExtraLod-1);
+    return mMipmaps[lod];
+}
+
+GGLSurface& EGLTextureObject::editMip(int lod)
+{
+    return const_cast<GGLSurface&>(mip(lod));
+}
+
+status_t EGLTextureObject::setSurface(GGLSurface const* s)
+{
+    // XXX: glFlush() on 's'
+    if (mSize && surface.data) {
+        free(surface.data);
+    }
+    surface = *s;
+    internalformat = 0;
+
+    // we should keep the crop_rect, but it's delicate because
+    // the new size of the surface could make it invalid.
+    // so for now, we just loose it.
+    memset(crop_rect, 0, sizeof(crop_rect));
+
+    // it would be nice if we could keep the generate_mipmap flag,
+    // we would have to generate them right now though.
+    generate_mipmap = GL_FALSE;
+
+    direct = GL_TRUE;
+    mSize = 0;  // we don't own this surface
+    if (mMipmaps)
+        freeMipmaps();
+    mIsComplete = true;
+    return NO_ERROR;
+}
+
+status_t EGLTextureObject::reallocate(
+        GLint level, int w, int h, int s,
+        int format, int compressedFormat, int bpr)
+{
+    const size_t size = h * bpr;
+    if (level == 0) 
+    {
+        if (size!=mSize || !surface.data) {
+            if (mSize && surface.data) {
+                free(surface.data);
+            }
+            surface.data = (GGLubyte*)malloc(size);
+            if (!surface.data) {
+                mSize = 0;
+                mIsComplete = false;
+                return NO_MEMORY;
+            }
+            mSize = size;
+        }
+        surface.version = sizeof(GGLSurface);
+        surface.width  = w;
+        surface.height = h;
+        surface.stride = s;
+        surface.format = format;
+        surface.compressedFormat = compressedFormat;
+        if (mMipmaps)
+            freeMipmaps();
+        mIsComplete = true;
+    }
+    else
+    {
+        if (!mMipmaps) {
+            if (allocateMipmaps() != NO_ERROR)
+                return NO_MEMORY;
+        }
+
+        LOGW_IF(level-1 >= mNumExtraLod, 
+                "specifying mipmap level %d, but # of level is %d",
+                level, mNumExtraLod+1);        
+
+        GGLSurface& mipmap = editMip(level);
+        if (mipmap.data)
+            free(mipmap.data);
+
+        mipmap.data = (GGLubyte*)malloc(size);
+        if (!mipmap.data) {
+            memset(&mipmap, 0, sizeof(GGLSurface));
+            mIsComplete = false;
+            return NO_MEMORY;
+        }
+
+        mipmap.version = sizeof(GGLSurface);
+        mipmap.width  = w;
+        mipmap.height = h;
+        mipmap.stride = s;
+        mipmap.format = format;
+        mipmap.compressedFormat = compressedFormat;
+
+        // check if the texture is complete
+        mIsComplete = true;
+        const GGLSurface* prev = &surface;
+        for (int i=0 ; i<mNumExtraLod ; i++) {
+            const GGLSurface* curr = mMipmaps + i;
+            if (curr->format != surface.format) {
+                mIsComplete = false;
+                break;
+            }
+
+            uint32_t w = (prev->width  >> 1) ? : 1;
+            uint32_t h = (prev->height >> 1) ? : 1;
+            if (w != curr->width || h != curr->height) {
+                mIsComplete = false;
+                break;
+            }
+            prev = curr;
+        }
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+EGLSurfaceManager::EGLSurfaceManager()
+    : TokenManager(), mCount(0)
+{
+}
+
+EGLSurfaceManager::~EGLSurfaceManager()
+{
+    // everything gets freed automatically here...
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::createTexture(GLuint name)
+{
+    sp<EGLTextureObject> result;
+
+    Mutex::Autolock _l(mLock);
+    if (mTextures.indexOfKey(name) >= 0)
+        return result; // already exists!
+
+    result = new EGLTextureObject();
+
+    status_t err = mTextures.add(name, result);
+    if (err < 0)
+        result.clear();
+
+    return result;
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::removeTexture(GLuint name)
+{
+    Mutex::Autolock _l(mLock);
+    const ssize_t index = mTextures.indexOfKey(name);
+    if (index >= 0) {
+        sp<EGLTextureObject> result(mTextures.valueAt(index));
+        mTextures.removeItemsAt(index);
+        return result;
+    }
+    return 0;
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::replaceTexture(GLuint name)
+{
+    sp<EGLTextureObject> tex;
+    Mutex::Autolock _l(mLock);
+    const ssize_t index = mTextures.indexOfKey(name);
+    if (index >= 0) {
+        const sp<EGLTextureObject>& old = mTextures.valueAt(index);
+        const uint32_t refs = old->getStrongCount();
+        if (ggl_likely(refs == 1)) {
+            // we're the only owner
+            tex = old;
+        } else {
+            // keep the texture's parameters
+            tex = new EGLTextureObject();
+            tex->copyParameters(old);
+            mTextures.removeItemsAt(index);
+            mTextures.add(name, tex);
+        }
+    }
+    return tex;
+}
+
+void EGLSurfaceManager::deleteTextures(GLsizei n, const GLuint *tokens)
+{
+    // free all textures
+    Mutex::Autolock _l(mLock);
+    for (GLsizei i=0 ; i<n ; i++) {
+        const GLuint t(*tokens++);
+        if (t) {
+            mTextures.removeItem(t);
+        }
+    }
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::texture(GLuint name)
+{
+    Mutex::Autolock _l(mLock);
+    const ssize_t index = mTextures.indexOfKey(name);
+    if (index >= 0)
+        return mTextures.valueAt(index);
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android