Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b6168ab authored by Chris Forbes's avatar Chris Forbes Committed by Android (Google) Code Review
Browse files

Merge changes from topic "libagl"

* changes:
  Remove mention of legacy software renderer
  Nuke libagl and setEmulatorGlesValue
parents 194e1069 b856aff7
Loading
Loading
Loading
Loading

opengl/libagl/Android.bp

deleted100644 → 0
+0 −99
Original line number Diff line number Diff line
//
// Build the software OpenGL ES library
//

cc_defaults {
    name: "libGLES_android_defaults",

    cflags: [
        "-DLOG_TAG=\"libagl\"",
        "-DGL_GLEXT_PROTOTYPES",
        "-DEGL_EGLEXT_PROTOTYPES",
        "-fvisibility=hidden",
        "-Wall",
        "-Werror",
    ],

    shared_libs: [
        "libcutils",
        "libhardware",
        "libutils",
        "liblog",
        "libpixelflinger",
        "libETC1",
        "libui",
        "libnativewindow",
    ],

    // we need to access the private Bionic header <bionic_tls.h>
    include_dirs: ["bionic/libc/private"],

    arch: {
        arm: {
            cflags: ["-fstrict-aliasing"],
        },

        mips: {
            cflags: [
                "-fstrict-aliasing",
                // The graphics code can generate division by zero
                "-mno-check-zero-division",
            ],
        },
    },
}

cc_library_shared {
    name: "libGLES_android",
    defaults: ["libGLES_android_defaults"],

    whole_static_libs: ["libGLES_android_arm"],

    srcs: [
        "egl.cpp",
        "state.cpp",
        "texture.cpp",
        "Tokenizer.cpp",
        "TokenManager.cpp",
        "TextureObjectManager.cpp",
        "BufferObjectManager.cpp",
    ],

    arch: {
        arm: {
            srcs: [
                "fixed_asm.S",
                "iterators.S",
            ],
        },

        mips: {
            rev6: {
                srcs: ["arch-mips/fixed_asm.S"],
            },
        },
    },

    relative_install_path: "egl",
}

cc_library_static {
    name: "libGLES_android_arm",
    defaults: ["libGLES_android_defaults"],

    srcs: [
        "array.cpp",
        "fp.cpp",
        "light.cpp",
        "matrix.cpp",
        "mipmap.cpp",
        "primitives.cpp",
        "vertex.cpp",
    ],

    arch: {
        arm: {
            instruction_set: "arm",
        },
    },
}
+0 −103
Original line number Diff line number Diff line
/*
 ** Copyright 2008, 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 <stdint.h>
#include <stddef.h>
#include <sys/types.h>

#include <cutils/atomic.h>
#include <utils/RefBase.h>
#include <utils/KeyedVector.h>
#include <utils/Errors.h>

#include <GLES/gl.h>

#include "BufferObjectManager.h"


namespace android {

using namespace gl;

// ----------------------------------------------------------------------------

EGLBufferObjectManager::EGLBufferObjectManager() 
: TokenManager(), mCount(0)
{
}

EGLBufferObjectManager::~EGLBufferObjectManager()
{
    // destroy all the buffer objects and their storage
    GLsizei n = mBuffers.size();
    for (GLsizei i=0 ; i<n ; i++) {
        buffer_t* bo = mBuffers.valueAt(i);
        free(bo->data);
        delete bo;
    }
}

buffer_t const* EGLBufferObjectManager::bind(GLuint buffer)
{
    Mutex::Autolock _l(mLock);
    int32_t i = mBuffers.indexOfKey(buffer);
    if (i >= 0) {
        return mBuffers.valueAt(i);
    }
    buffer_t* bo = new buffer_t;
    bo->data = 0;
    bo->usage = GL_STATIC_DRAW;
    bo->size = 0;
    bo->name = buffer;
    mBuffers.add(buffer, bo);
    return bo;
}

int EGLBufferObjectManager::allocateStore(buffer_t* bo,
        GLsizeiptr size, GLenum usage)
{
    Mutex::Autolock _l(mLock);
    if (size != bo->size) {
       uint8_t* data = (uint8_t*)malloc(size);
        if (data == 0)
            return -1;
        free(bo->data);
        bo->data = data;
        bo->size = size;
    }
    bo->usage = usage;
    return 0;
}

void EGLBufferObjectManager::deleteBuffers(GLsizei n, const GLuint* buffers)
{
    Mutex::Autolock _l(mLock);
    while (n--) {
        const GLuint t = *buffers++;
        if (t) {
            int32_t index = mBuffers.indexOfKey(t);
            if (index >= 0) {
                buffer_t* bo = mBuffers.valueAt(index);
                free(bo->data);
                mBuffers.removeItemsAt(index);
                delete bo;
            }
        }
    }
}

// ----------------------------------------------------------------------------
}; // namespace android
+0 −86
Original line number Diff line number Diff line
/*
 **
 ** 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.
 */

#ifndef ANDROID_OPENGLES_BUFFER_OBJECT_MANAGER_H
#define ANDROID_OPENGLES_BUFFER_OBJECT_MANAGER_H

#include <atomic>
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>

#include <utils/RefBase.h>
#include <utils/KeyedVector.h>
#include <utils/Errors.h>

#include <GLES/gl.h>

#include "Tokenizer.h"
#include "TokenManager.h"


namespace android {

// ----------------------------------------------------------------------------

namespace gl {

struct buffer_t {
    GLsizeiptr      size;
    GLenum          usage;
    uint8_t*        data;
    uint32_t        name;
};

};

class EGLBufferObjectManager : public TokenManager
{
public:
    EGLBufferObjectManager();
    ~EGLBufferObjectManager();

    // protocol for sp<>
    inline  void    incStrong(const void* id) const;
    inline  void    decStrong(const void* id) const;
    typedef void    weakref_type;

    gl::buffer_t const* bind(GLuint buffer);
    int                 allocateStore(gl::buffer_t* bo, GLsizeiptr size, GLenum usage);
    void                deleteBuffers(GLsizei n, const GLuint* buffers);

private:
    mutable std::atomic_size_t          mCount;
    mutable Mutex                       mLock;
    KeyedVector<GLuint, gl::buffer_t*>  mBuffers;
};

void EGLBufferObjectManager::incStrong(const void* /*id*/) const {
    mCount.fetch_add(1, std::memory_order_relaxed);
}
void EGLBufferObjectManager::decStrong(const void* /*id*/) const {
    if (mCount.fetch_sub(1, std::memory_order_release) == 0) {
        std::atomic_thread_fence(std::memory_order_acquire);
        delete this;
    }
}

// ----------------------------------------------------------------------------
}; // namespace android

#endif // ANDROID_OPENGLES_BUFFER_OBJECT_MANAGER_H
+0 −325
Original line number Diff line number Diff line
/*
 ** 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()
    : 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;
    buffer = 0;
}

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;
    buffer = 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::setImage(ANativeWindowBuffer* native_buffer)
{
    GGLSurface sur;
    sur.version = sizeof(GGLSurface);
    sur.width = native_buffer->width;
    sur.height= native_buffer->height;
    sur.stride= native_buffer->stride;
    sur.format= native_buffer->format;
    sur.data  = 0;
    setSurface(&sur);
    buffer = native_buffer;
    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;
        }

        ALOGW_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()
{
}

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
+0 −111
Original line number Diff line number Diff line
/*
** 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.
*/

#ifndef ANDROID_OPENGLES_SURFACE_H
#define ANDROID_OPENGLES_SURFACE_H

#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>

#include <cutils/atomic.h>
#include <utils/threads.h>
#include <utils/RefBase.h>
#include <utils/KeyedVector.h>
#include <utils/Errors.h>

#include <private/pixelflinger/ggl_context.h>

#include <GLES/gl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>

#include "Tokenizer.h"
#include "TokenManager.h"


namespace android {

// ----------------------------------------------------------------------------

class EGLTextureObject : public LightRefBase<EGLTextureObject>
{
public:
                    EGLTextureObject();
                   ~EGLTextureObject();

    status_t    setSurface(GGLSurface const* s);
    status_t    setImage(ANativeWindowBuffer* buffer);
    void        setImageBits(void* vaddr) { surface.data = (GGLubyte*)vaddr; }

    status_t            reallocate(GLint level,
                            int w, int h, int s,
                            int format, int compressedFormat, int bpr);
    inline  size_t      size() const { return mSize; }
    const GGLSurface&   mip(int lod) const;
    GGLSurface&         editMip(int lod);
    bool                hasMipmaps() const { return mMipmaps!=0; }
    bool                isComplete() const { return mIsComplete; }
    void                copyParameters(const sp<EGLTextureObject>& old);

private:
        status_t        allocateMipmaps();
            void        freeMipmaps();
            void        init();
    size_t              mSize;
    GGLSurface          *mMipmaps;
    int                 mNumExtraLod;
    bool                mIsComplete;

public:
    GGLSurface          surface;
    GLenum              wraps;
    GLenum              wrapt;
    GLenum              min_filter;
    GLenum              mag_filter;
    GLenum              internalformat;
    GLint               crop_rect[4];
    GLint               generate_mipmap;
    GLint               direct;
    ANativeWindowBuffer* buffer;
};

// ----------------------------------------------------------------------------

class EGLSurfaceManager :
    public LightRefBase<EGLSurfaceManager>,
    public TokenManager
{
public:
                EGLSurfaceManager();
                ~EGLSurfaceManager();

    sp<EGLTextureObject>    createTexture(GLuint name);
    sp<EGLTextureObject>    removeTexture(GLuint name);
    sp<EGLTextureObject>    replaceTexture(GLuint name);
    void                    deleteTextures(GLsizei n, const GLuint *tokens);
    sp<EGLTextureObject>    texture(GLuint name);

private:
    mutable Mutex                               mLock;
    KeyedVector< GLuint, sp<EGLTextureObject> > mTextures;
};

// ----------------------------------------------------------------------------
}; // namespace android

#endif // ANDROID_OPENGLES_SURFACE_H
Loading