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

Commit 27d40795 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic 'drvup-master'

* changes:
  EGL: Load updated EGL/GLES drivers
  Load updated drivers using derived loader namespace
parents cd89857b 7a8d83ef
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@

#include <string>

struct android_namespace_t;

namespace android {

class GraphicsEnv {
@@ -31,12 +33,27 @@ public:
    // in the search path must have a '!' after the zip filename, e.g.
    //     /data/app/com.example.driver/base.apk!/lib/arm64-v8a
    void setDriverPath(const std::string path);
    android_namespace_t* getDriverNamespace();

private:
    GraphicsEnv() = default;
    std::string mDriverPath;
    android_namespace_t* mDriverNamespace = nullptr;
};

} // namespace android

/* FIXME
 * Export an un-mangled function that just does
 *     return android::GraphicsEnv::getInstance().getDriverNamespace();
 * This allows libEGL to get the function pointer via dlsym, since it can't
 * directly link against libgui. In a future release, we'll fix this so that
 * libgui does not depend on graphics API libraries, and libEGL can link
 * against it. The current dependencies from libgui -> libEGL are:
 *  - the GLConsumer class, which should be moved to its own library
 *  - the EGLsyncKHR synchronization in BufferQueue, which is deprecated and
 *    will be removed soon.
 */
extern "C" android_namespace_t* android_getDriverNamespace();

#endif // ANDROID_GUI_GRAPHICS_ENV_H
+1 −0
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ cc_library_shared {
    ],

    shared_libs: [
        "libnativeloader",
        "libsync",
        "libbinder",
        "libcutils",
+41 −0
Original line number Diff line number Diff line
@@ -18,7 +18,10 @@
#define LOG_TAG "GraphicsEnv"
#include <gui/GraphicsEnv.h>

#include <mutex>

#include <log/log.h>
#include <nativeloader/dlext_namespaces.h>

namespace android {

@@ -37,4 +40,42 @@ void GraphicsEnv::setDriverPath(const std::string path) {
    mDriverPath = path;
}

android_namespace_t* GraphicsEnv::getDriverNamespace() {
    static std::once_flag once;
    std::call_once(once, [this]() {
        // TODO; In the next version of Android, all graphics drivers will be
        // loaded into a custom namespace. To minimize risk for this release,
        // only updated drivers use a custom namespace.
        //
        // Additionally, the custom namespace will be
        // ANDROID_NAMESPACE_TYPE_ISOLATED, and will only have access to a
        // subset of the system.
        if (mDriverPath.empty())
            return;

        char defaultPath[PATH_MAX];
        android_get_LD_LIBRARY_PATH(defaultPath, sizeof(defaultPath));
        size_t defaultPathLen = strlen(defaultPath);

        std::string path;
        path.reserve(mDriverPath.size() + 1 + defaultPathLen);
        path.append(mDriverPath);
        path.push_back(':');
        path.append(defaultPath, defaultPathLen);

        mDriverNamespace = android_create_namespace(
                "gfx driver",
                nullptr,                    // ld_library_path
                path.c_str(),               // default_library_path
                ANDROID_NAMESPACE_TYPE_SHARED,
                nullptr,                    // permitted_when_isolated_path
                nullptr);                   // parent
    });
    return mDriverNamespace;
}

} // namespace android

extern "C" android_namespace_t* android_getDriverNamespace() {
    return android::GraphicsEnv::getInstance().getDriverNamespace();
}
+67 −5
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@
 ** limitations under the License.
 */

//#define LOG_NDEBUG 0

#include <array>
#include <ctype.h>
#include <dirent.h>
#include <dlfcn.h>
@@ -23,6 +26,7 @@
#include <stdlib.h>
#include <string.h>

#include <android/dlext.h>
#include <cutils/properties.h>
#include <log/log.h>

@@ -136,10 +140,26 @@ status_t Loader::driver_t::set(void* hnd, int32_t api)
// ----------------------------------------------------------------------------

Loader::Loader()
    : getProcAddress(NULL) {
    : getProcAddress(NULL),
      mLibGui(nullptr),
      mGetDriverNamespace(nullptr)
{
    // FIXME: See note in GraphicsEnv.h about android_getDriverNamespace().
    // libgui should already be loaded in any process that uses libEGL, but
    // if for some reason it isn't, then we're not going to get a driver
    // namespace anyway, so don't force it to be loaded.
    mLibGui = dlopen("libgui.so", RTLD_NOLOAD | RTLD_LOCAL | RTLD_LAZY);
    if (!mLibGui) {
        ALOGD("failed to load libgui: %s", dlerror());
        return;
    }
    mGetDriverNamespace = reinterpret_cast<decltype(mGetDriverNamespace)>(
            dlsym(mLibGui, "android_getDriverNamespace"));
}

Loader::~Loader() {
    if (mLibGui)
        dlclose(mLibGui);
}

static void* load_wrapper(const char* path) {
@@ -286,9 +306,7 @@ void Loader::init_api(void* dso,
    }
}

void *Loader::load_driver(const char* kind,
        egl_connection_t* cnx, uint32_t mask)
{
static void* load_system_driver(const char* kind) {
    class MatchFile {
    public:
        static String8 find(const char* kind) {
@@ -413,11 +431,55 @@ void *Loader::load_driver(const char* kind,

    ALOGD("loaded %s", driver_absolute_path);

    return dso;
}

static const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
    "ro.hardware.egl",
    "ro.board.platform",
}};

static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
    const android_dlextinfo dlextinfo = {
        .flags = ANDROID_DLEXT_USE_NAMESPACE,
        .library_namespace = ns,
    };
    void* so = nullptr;
    char prop[PROPERTY_VALUE_MAX + 1];
    for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
        if (property_get(key, prop, nullptr) > 0) {
            String8 name;
            name.appendFormat("lib%s_%s.so", kind, prop);
            so = android_dlopen_ext(name.string(), RTLD_LOCAL | RTLD_NOW,
                    &dlextinfo);
            if (so)
                return so;
        }
    }
    return nullptr;
}

void *Loader::load_driver(const char* kind,
        egl_connection_t* cnx, uint32_t mask)
{
    void* dso = nullptr;
    if (mGetDriverNamespace) {
        android_namespace_t* ns = mGetDriverNamespace();
        if (ns) {
            dso = load_updated_driver(kind, ns);
        }
    }
    if (!dso) {
        dso = load_system_driver(kind);
        if (!dso)
            return NULL;
    }

    if (mask & EGL) {
        getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");

        ALOGE_IF(!getProcAddress,
                "can't find eglGetProcAddress() in %s", driver_absolute_path);
                "can't find eglGetProcAddress() in EGL driver library");

        egl_t* egl = &cnx->egl;
        __eglMustCastToProperFunctionPointerType* curr =
+6 −1
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@
#include <utils/Singleton.h>
#include <utils/String8.h>

#include <gui/GraphicsEnv.h>

#include <EGL/egl.h>

// ----------------------------------------------------------------------------
@@ -54,6 +56,9 @@ class Loader : public Singleton<Loader>
    
    getProcAddressType getProcAddress;

    void* mLibGui;
    decltype(android_getDriverNamespace)* mGetDriverNamespace;

public:
    ~Loader();
    
Loading