Build the Vulkan server

Bug: 171711491

TODO: Flesh out Framebuffer, ColorBuffer, RenderControl
TODO: Make sure feature control flags are set properly on init.
TODO: Implement various System related things like program and launcher
directory, env variable setting.

Change-Id: I126b9a7c3dcad6318e20e82eed1b6c774827804d
diff --git a/base/EntityManager.h b/base/EntityManager.h
new file mode 100644
index 0000000..d176114
--- /dev/null
+++ b/base/EntityManager.h
@@ -0,0 +1,568 @@
+// Copyright (C) 2019 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.
+#pragma once
+
+#include "base/Lookup.h"
+#include "base/Optional.h"
+
+#include <functional>
+#include <unordered_map>
+#include <vector>
+
+#include <inttypes.h>
+#include <stdio.h>
+
+#define ENTITY_MANAGER_DEBUG 0
+
+#if ENTITY_MANAGER_DEBUG
+
+#define EM_DBG(fmt,...) fprintf(stderr, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);
+
+#else
+#define EM_DBG(...)
+#endif
+
+#define INVALID_ENTITY_HANDLE 0
+#define INVALID_COMPONENT_HANDLE 0
+
+namespace android {
+namespace base {
+
+// EntityManager: A way to represent an abstrat space of objects with handles.
+// Each handle is associated with data of type Item for quick access from handles to data.
+// Otherwise, entity data is spread through ComponentManagers.
+template<size_t indexBits,
+         size_t generationBits,
+         size_t typeBits,
+         class Item>
+class EntityManager {
+public:
+
+    static_assert(64 == (indexBits + generationBits + typeBits),
+                  "bits of index, generation, and type must add to 64");
+
+    using EntityHandle = uint64_t;
+    using IteratorFunc = std::function<void(bool live, EntityHandle h, Item& item)>;
+    using ConstIteratorFunc = std::function<void(bool live, EntityHandle h, const Item& item)>;
+
+    static size_t getHandleIndex(EntityHandle h) {
+        return static_cast<size_t>(h & ((1ULL << indexBits) - 1ULL));
+    }
+
+    static size_t getHandleGeneration(EntityHandle h) {
+        return static_cast<size_t>(
+            (h >> indexBits) &
+            ((1ULL << generationBits) - 1ULL));
+    }
+
+    static size_t getHandleType(EntityHandle h) {
+        return static_cast<size_t>(
+            (h >> (indexBits + generationBits)) &
+            ((1ULL << typeBits) - 1ULL));
+        return h & ((1ULL << indexBits) - 1ULL);
+    }
+
+    static EntityHandle makeHandle(
+        size_t index,
+        size_t generation,
+        size_t type) {
+        EntityHandle res = index;
+        res |= generation << indexBits;
+        res |= type << (indexBits + generationBits);
+        return res;
+    }
+
+    static EntityHandle withIndex(EntityHandle h, size_t i) {
+        return makeHandle(i, getHandleGeneration(h), getHandleType(h));
+    }
+
+    static EntityHandle withGeneration(EntityHandle h, size_t nextGen) {
+        return makeHandle(getHandleIndex(h), nextGen, getHandleType(h));
+    }
+
+    static EntityHandle withType(EntityHandle h, size_t newType) {
+        return makeHandle(getHandleIndex(h), getHandleGeneration(h), newType);
+    }
+
+    EntityManager() : EntityManager(0) { }
+
+    ~EntityManager() { clear(); }
+
+    struct EntityEntry {
+        EntityHandle handle = 0;
+        size_t nextFreeIndex = 0;
+        // 0 is a special generation for brand new entries
+        // that are not used yet
+        size_t liveGeneration = 1;
+        Item item;
+    };
+
+    void clear() {
+        mEntries.clear();
+        mFirstFreeIndex = 0;
+        mLiveEntries = 0;
+    }
+
+    EntityHandle add(const Item& item, size_t type) {
+
+        if (!type) return INVALID_ENTITY_HANDLE;
+
+        size_t maxElements = (1ULL << indexBits);
+        if (mLiveEntries == maxElements) return INVALID_ENTITY_HANDLE;
+
+        size_t newIndex = mFirstFreeIndex;
+
+        EM_DBG("newIndex/firstFree: %zu type: %zu", newIndex, type);
+
+        size_t neededCapacity = newIndex + 1;
+        if (maxElements < neededCapacity) return INVALID_ENTITY_HANDLE;
+
+        size_t currentCapacity = mEntries.size();
+        size_t nextCapacity = neededCapacity << 1;
+        if (nextCapacity > maxElements) nextCapacity = maxElements;
+
+        EM_DBG("needed/current/next capacity: %zu %zu %zu",
+               neededCapacity,
+               currentCapacity,
+               nextCapacity);
+
+        if (neededCapacity > mEntries.size()) {
+            mEntries.resize(nextCapacity);
+            for (size_t i = currentCapacity; i < nextCapacity; ++i) {
+                mEntries[i].handle = makeHandle(i, 0, type);
+                mEntries[i].nextFreeIndex = i + 1;
+                EM_DBG("new un-init entry: index %zu nextFree %zu",
+                       i, i + 1);
+            }
+        }
+
+        mEntries[newIndex].handle =
+            makeHandle(newIndex, mEntries[newIndex].liveGeneration, type);
+        mEntries[newIndex].item = item;
+
+        mFirstFreeIndex = mEntries[newIndex].nextFreeIndex;
+        EM_DBG("created. new first free: %zu", mFirstFreeIndex);
+
+        ++mLiveEntries;
+
+        EM_DBG("result handle: 0x%llx", (unsigned long long)mEntries[newIndex].handle);
+
+        return mEntries[newIndex].handle;
+    }
+
+    EntityHandle addFixed(EntityHandle fixedHandle, const Item& item, size_t type) {
+        // 3 cases:
+        // 1. handle is not allocated and doesn't correspond to mFirstFreeIndex
+        bool isFreeListNonHead = false;
+        // 2. handle already exists (replace)
+        bool isAlloced = false;
+        // 3. index(handle) == mFirstFreeIndex
+        bool isFreeListHead = false;
+
+        if (!type) return INVALID_ENTITY_HANDLE;
+
+        size_t maxElements = (1ULL << indexBits);
+        if (mLiveEntries == maxElements) return INVALID_ENTITY_HANDLE;
+
+        size_t newIndex = getHandleIndex(fixedHandle);
+
+        EM_DBG("newIndex/firstFree: %zu type: %zu", newIndex, type);
+
+        size_t neededCapacity = newIndex + 1;
+
+        if (maxElements < neededCapacity) return INVALID_ENTITY_HANDLE;
+
+        size_t currentCapacity = mEntries.size();
+        size_t nextCapacity = neededCapacity << 1;
+        if (nextCapacity > maxElements) nextCapacity = maxElements;
+
+        EM_DBG("needed/current/next capacity: %zu %zu %zu",
+               neededCapacity,
+               currentCapacity,
+               nextCapacity);
+
+        if (neededCapacity > mEntries.size()) {
+            mEntries.resize(nextCapacity);
+            for (size_t i = currentCapacity; i < nextCapacity; ++i) {
+                mEntries[i].handle = makeHandle(i, 0, type);
+                mEntries[i].nextFreeIndex = i + 1;
+                EM_DBG("new un-init entry: index %zu nextFree %zu",
+                       i, i + 1);
+            }
+        }
+
+        // Now we ensured that there is enough space to talk about the entry of
+        // this |fixedHandle|.
+        if (mFirstFreeIndex == newIndex) {
+            isFreeListHead = true;
+        } else {
+            auto& entry = mEntries[newIndex];
+            if (entry.liveGeneration == getHandleGeneration(entry.handle)) {
+                isAlloced = true;
+            } else {
+                isFreeListNonHead = true;
+            }
+        }
+
+        mEntries[newIndex].handle = fixedHandle;
+        mEntries[newIndex].liveGeneration = getHandleGeneration(fixedHandle);
+        mEntries[newIndex].item = item;
+
+        EM_DBG("new index: %zu", newIndex);
+
+        if (isFreeListHead) {
+
+            EM_DBG("first free index reset from %zu to %zu",
+                    mFirstFreeIndex, mEntries[newIndex].nextFreeIndex);
+
+            mFirstFreeIndex = mEntries[newIndex].nextFreeIndex;
+
+            ++mLiveEntries;
+
+        } else if (isAlloced) {
+            // Already replaced whatever is there, and since it's already allocated,
+            // no need to update freelist.
+            EM_DBG("entry at %zu already alloced. replacing.", newIndex);
+        } else if (isFreeListNonHead) {
+            // Go through the freelist and skip over the entry we just added.
+            size_t prevEntryIndex = mFirstFreeIndex;
+
+            EM_DBG("in free list but not head. reorganizing freelist. "
+                   "start at %zu -> %zu",
+                   mFirstFreeIndex, mEntries[prevEntryIndex].nextFreeIndex);
+
+            while (mEntries[prevEntryIndex].nextFreeIndex != newIndex) {
+                EM_DBG("next: %zu -> %zu",
+                       prevEntryIndex,
+                       mEntries[prevEntryIndex].nextFreeIndex);
+                prevEntryIndex =
+                    mEntries[prevEntryIndex].nextFreeIndex;
+            }
+
+            EM_DBG("finished. set prev entry %zu to new entry's next, %zu",
+                    prevEntryIndex, mEntries[newIndex].nextFreeIndex);
+
+            mEntries[prevEntryIndex].nextFreeIndex =
+                mEntries[newIndex].nextFreeIndex;
+
+            ++mLiveEntries;
+        }
+
+        return fixedHandle;
+    }
+    void remove(EntityHandle h) {
+
+        if (get(h) == nullptr) return;
+
+        size_t index = getHandleIndex(h);
+
+        EM_DBG("remove handle: 0x%llx -> index %zu", (unsigned long long)h, index);
+
+        auto& entry = mEntries[index];
+
+        EM_DBG("handle gen: %zu entry gen: %zu", getHandleGeneration(h), entry.liveGeneration);
+
+        ++entry.liveGeneration;
+        if ((entry.liveGeneration == 0) ||
+            (entry.liveGeneration == (1ULL << generationBits))) {
+            entry.liveGeneration = 1;
+        }
+
+        entry.nextFreeIndex = mFirstFreeIndex;
+
+        mFirstFreeIndex = index;
+
+        EM_DBG("new first free: %zu next free: %zu", mFirstFreeIndex, entry.nextFreeIndex);
+
+        --mLiveEntries;
+    }
+
+    Item* get(EntityHandle h) {
+        size_t index = getHandleIndex(h);
+        if (index >= mEntries.size()) return nullptr;
+
+        auto& entry = mEntries[index];
+        if (entry.liveGeneration != getHandleGeneration(h)) return nullptr;
+
+        return &entry.item;
+    }
+
+    bool isLive(EntityHandle h) const {
+        size_t index = getHandleIndex(h);
+        if (index >= mEntries.size()) return false;
+
+        const auto& entry = mEntries[index];
+
+        return (entry.liveGeneration == getHandleGeneration(h));
+    }
+
+    void forEachEntry(IteratorFunc func) {
+        for (auto& entry: mEntries) {
+            auto handle = entry.handle;
+            bool live = isLive(handle);
+            auto& item = entry.item;
+            func(live, handle, item);
+        }
+    }
+
+    void forEachLiveEntry(IteratorFunc func) {
+        for (auto& entry: mEntries) {
+            auto handle = entry.handle;
+            bool live = isLive(handle);
+
+            if (!live) continue;
+
+            auto& item = entry.item;
+            func(live, handle, item);
+        }
+    }
+
+    void forEachLiveEntry_const(ConstIteratorFunc func) const {
+        for (auto& entry: mEntries) {
+            auto handle = entry.handle;
+            bool live = isLive(handle);
+
+            if (!live) continue;
+
+            const auto& item = entry.item;
+            func(live, handle, item);
+        }
+    }
+
+private:
+    EntityManager(size_t initialItems) :
+        mEntries(initialItems),
+        mFirstFreeIndex(0),
+        mLiveEntries(0) { }
+
+    std::vector<EntityEntry> mEntries;
+    size_t mFirstFreeIndex;
+    size_t mLiveEntries;
+};
+
+// Tracks components over a given space of entities.
+// Looking up by entity index is slower, but takes less space overall versus
+// a flat array that parallels the entities.
+template<size_t indexBits,
+         size_t generationBits,
+         size_t typeBits,
+         class Data>
+class ComponentManager {
+public:
+
+    static_assert(64 == (indexBits + generationBits + typeBits),
+                  "bits of index, generation, and type must add to 64");
+
+    using ComponentHandle = uint64_t;
+    using EntityHandle = uint64_t;
+    using ComponentIteratorFunc = std::function<void(bool, ComponentHandle componentHandle, EntityHandle entityHandle, Data& data)>;
+    using ConstComponentIteratorFunc = std::function<void(bool, ComponentHandle componentHandle, EntityHandle entityHandle, const Data& data)>;
+
+    // Adds the given |data| and associates it with EntityHandle.
+    // We can also opt-in to immediately tracking the handle in the reverse mapping,
+    // which has an upfront cost in runtime.
+    // Many uses of ComponentManager don't really need to track the associated entity handle,
+    // so it is opt-in.
+
+    ComponentHandle add(
+        EntityHandle h,
+        const Data& data,
+        size_t type,
+        bool tracked = false) {
+
+        InternalItem item = { h, data, tracked };
+        auto res = static_cast<ComponentHandle>(mData.add(item, type));
+
+        if (tracked) {
+            mEntityToComponentMap[h] = res;
+        }
+
+        return res;
+    }
+
+    void clear() {
+        mData.clear();
+        mEntityToComponentMap.clear();
+    }
+
+    // If we didn't explicitly track, just fail.
+    ComponentHandle getComponentHandle(EntityHandle h) const {
+        auto componentHandlePtr = android::base::find(mEntityToComponentMap, h);
+        if (!componentHandlePtr) return INVALID_COMPONENT_HANDLE;
+        return *componentHandlePtr;
+    }
+
+    EntityHandle getEntityHandle(ComponentHandle h) const {
+        return mData.get(h)->entityHandle;
+    }
+
+    void removeByEntity(EntityHandle h) {
+        auto componentHandle = getComponentHandle(h);
+        removeByComponent(componentHandle);
+    }
+
+    void removeByComponent(ComponentHandle h) {
+        auto item = mData.get(h);
+
+        if (!item) return;
+        if (item->tracked) {
+            mEntityToComponentMap.erase(item->entityHandle);
+        }
+
+        mData.remove(h);
+    }
+
+    Data* getByEntity(EntityHandle h) {
+        return getByComponent(getComponentHandle(h));
+    }
+
+    Data* getByComponent(ComponentHandle h) {
+        auto item = mData.get(h);
+        if (!item) return nullptr;
+        return &(item->data);
+    }
+
+    void forEachComponent(ComponentIteratorFunc func) {
+        mData.forEachEntry(
+            [func](bool live, typename InternalEntityManager::EntityHandle componentHandle, InternalItem& item) {
+                func(live, componentHandle, item.entityHandle, item.data);
+        });
+    }
+
+    void forEachLiveComponent(ComponentIteratorFunc func) {
+        mData.forEachLiveEntry(
+            [func](bool live, typename InternalEntityManager::EntityHandle componentHandle, InternalItem& item) {
+                func(live, componentHandle, item.entityHandle, item.data);
+        });
+    }
+
+    void forEachLiveComponent_const(ConstComponentIteratorFunc func) const {
+        mData.forEachLiveEntry_const(
+            [func](bool live, typename InternalEntityManager::EntityHandle componentHandle, const InternalItem& item) {
+                func(live, componentHandle, item.entityHandle, item.data);
+        });
+    }
+
+private:
+    struct InternalItem {
+        EntityHandle entityHandle;
+        Data data;
+        bool tracked;
+    };
+
+    using InternalEntityManager = EntityManager<indexBits, generationBits, typeBits, InternalItem>;
+    using EntityToComponentMap = std::unordered_map<EntityHandle, ComponentHandle>;
+
+    mutable InternalEntityManager mData;
+    EntityToComponentMap mEntityToComponentMap;
+};
+
+// ComponentManager, but unpacked; uses the same index space as the associated
+// entities. Takes more space by default, but not more if all entities have this component.
+template<size_t indexBits,
+         size_t generationBits,
+         size_t typeBits,
+         class Data>
+class UnpackedComponentManager {
+public:
+    using ComponentHandle = uint64_t;
+    using EntityHandle = uint64_t;
+    using ComponentIteratorFunc =
+        std::function<void(bool, ComponentHandle componentHandle, EntityHandle entityHandle, Data& data)>;
+    using ConstComponentIteratorFunc =
+        std::function<void(bool, ComponentHandle componentHandle, EntityHandle entityHandle, const Data& data)>;
+
+    EntityHandle add(EntityHandle h, const Data& data) {
+
+        size_t index = indexOfEntity(h);
+
+        if (index + 1 > mItems.size()) {
+            mItems.resize((index + 1) * 2);
+        }
+
+        mItems[index].live = true;
+        mItems[index].handle = h;
+        mItems[index].data = data;
+
+        return h;
+    }
+
+    void clear() {
+        mItems.clear();
+    }
+
+    void remove(EntityHandle h) {
+        size_t index = indexOfEntity(h);
+        if (index >= mItems.size()) return;
+        mItems[index].live = false;
+    }
+
+    Data* get(EntityHandle h) {
+        size_t index = indexOfEntity(h);
+
+        if (index + 1 > mItems.size()) {
+            mItems.resize((index + 1) * 2);
+        }
+
+        auto item = mItems.data() + index;
+        if (!item->live) return nullptr;
+        return &item->data;
+    }
+
+    const Data* get_const(EntityHandle h) const {
+        size_t index = indexOfEntity(h);
+
+        if (index + 1 > mItems.size()) {
+            return nullptr;
+        }
+
+        auto item = mItems.data() + index;
+        if (!item->live) return nullptr;
+        return &item->data;
+    }
+
+    void forEachComponent(ComponentIteratorFunc func) {
+        for (auto& item : mItems) {
+            func(item.live, item.handle, item.handle, item.data);
+        }
+    }
+
+    void forEachLiveComponent(ComponentIteratorFunc func) {
+        for (auto& item : mItems) {
+            if (item.live) func(item.live, item.handle, item.handle, item.data);
+        }
+    }
+
+    void forEachLiveComponent_const(ConstComponentIteratorFunc func) const {
+        for (auto& item : mItems) {
+            if (item.live) func(item.live, item.handle, item.handle, item.data);
+        }
+    }
+
+private:
+    static size_t indexOfEntity(EntityHandle h) {
+        return EntityManager<indexBits, generationBits, typeBits, int>::getHandleIndex(h);
+    }
+
+    struct InternalItem {
+        bool live = false;
+        EntityHandle handle = 0;
+        Data data;
+    };
+
+    std::vector<InternalItem> mItems;
+};
+
+} // namespace android
+} // namespace base