/*
 * Copyright (C) 2015 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 "rs.h"
#include "rsDevice.h"
#include "rsContext.h"
#include "rsThreadIO.h"

#include "rsgApiStructs.h"

#ifndef RS_COMPATIBILITY_LIB
#include "rsMesh.h"
#include <gui/DisplayEventReceiver.h>
#endif

#include <sys/types.h>
#include <sys/resource.h>
#include <sched.h>

#include <sys/syscall.h>
#include <string.h>
#include <dlfcn.h>
#include <inttypes.h>
#include <unistd.h>

#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) && \
        defined(HAVE_ANDROID_OS)
#include <cutils/properties.h>
#endif

#ifdef RS_COMPATIBILITY_LIB
#include "rsCompatibilityLib.h"
#endif

using namespace android;
using namespace android::renderscript;



typedef bool (*HalQueryVersion)(uint32_t *version_major, uint32_t *version_minor);
typedef bool (*HalQueryHal)(android::renderscript::RsHalInitEnums entry, void **fnPtr);
typedef bool (*HalInit)(RsContext, uint32_t version_major, uint32_t version_minor);
typedef void (*HalAbort)(RsContext);


static bool LoadHalTable(Context *rsc, HalQueryHal fn, bool loadGraphics) {
    bool ret = true;

    ret &= fn(RS_HAL_CORE_SHUTDOWN, (void **)&rsc->mHal.funcs.shutdownDriver);
    ret &= fn(RS_HAL_CORE_SET_PRIORITY, (void **)&rsc->mHal.funcs.setPriority);
    ret &= fn(RS_HAL_CORE_ALLOC_RUNTIME_MEM, (void **)&rsc->mHal.funcs.allocRuntimeMem);
    ret &= fn(RS_HAL_CORE_FREE_RUNTIME_MEM, (void **)&rsc->mHal.funcs.freeRuntimeMem);
    ret &= fn(RS_HAL_CORE_FINISH, (void **)&rsc->mHal.funcs.finish);

    ret &= fn(RS_HAL_SCRIPT_INIT, (void **)&rsc->mHal.funcs.script.init);
    ret &= fn(RS_HAL_SCRIPT_INIT_INTRINSIC, (void **)&rsc->mHal.funcs.script.initIntrinsic);
    ret &= fn(RS_HAL_SCRIPT_INVOKE_FUNCTION, (void **)&rsc->mHal.funcs.script.invokeFunction);
    ret &= fn(RS_HAL_SCRIPT_INVOKE_ROOT, (void **)&rsc->mHal.funcs.script.invokeRoot);
    ret &= fn(RS_HAL_SCRIPT_INVOKE_FOR_EACH, (void **)&rsc->mHal.funcs.script.invokeForEach);
    ret &= fn(RS_HAL_SCRIPT_INVOKE_INIT, (void **)&rsc->mHal.funcs.script.invokeInit);
    ret &= fn(RS_HAL_SCRIPT_INVOKE_FREE_CHILDREN, (void **)&rsc->mHal.funcs.script.invokeFreeChildren);
    ret &= fn(RS_HAL_SCRIPT_SET_GLOBAL_VAR, (void **)&rsc->mHal.funcs.script.setGlobalVar);
    ret &= fn(RS_HAL_SCRIPT_GET_GLOBAL_VAR, (void **)&rsc->mHal.funcs.script.getGlobalVar);
    ret &= fn(RS_HAL_SCRIPT_SET_GLOBAL_VAR_WITH_ELEMENT_DIM, (void **)&rsc->mHal.funcs.script.setGlobalVarWithElemDims);
    ret &= fn(RS_HAL_SCRIPT_SET_GLOBAL_BIND, (void **)&rsc->mHal.funcs.script.setGlobalBind);
    ret &= fn(RS_HAL_SCRIPT_SET_GLOBAL_OBJECT, (void **)&rsc->mHal.funcs.script.setGlobalObj);
    ret &= fn(RS_HAL_SCRIPT_DESTROY, (void **)&rsc->mHal.funcs.script.destroy);
    ret &= fn(RS_HAL_SCRIPT_INVOKE_FOR_EACH_MULTI, (void **)&rsc->mHal.funcs.script.invokeForEachMulti);
    ret &= fn(RS_HAL_SCRIPT_UPDATE_CACHED_OBJECT, (void **)&rsc->mHal.funcs.script.updateCachedObject);

    ret &= fn(RS_HAL_ALLOCATION_INIT, (void **)&rsc->mHal.funcs.allocation.init);
    ret &= fn(RS_HAL_ALLOCATION_INIT_OEM, (void **)&rsc->mHal.funcs.allocation.initOem);
    ret &= fn(RS_HAL_ALLOCATION_INIT_ADAPTER, (void **)&rsc->mHal.funcs.allocation.initAdapter);
    ret &= fn(RS_HAL_ALLOCATION_DESTROY, (void **)&rsc->mHal.funcs.allocation.destroy);
    ret &= fn(RS_HAL_ALLOCATION_GET_GRALLOC_BITS, (void **)&rsc->mHal.funcs.allocation.grallocBits);
    ret &= fn(RS_HAL_ALLOCATION_RESIZE, (void **)&rsc->mHal.funcs.allocation.resize);
    ret &= fn(RS_HAL_ALLOCATION_SYNC_ALL, (void **)&rsc->mHal.funcs.allocation.syncAll);
    ret &= fn(RS_HAL_ALLOCATION_MARK_DIRTY, (void **)&rsc->mHal.funcs.allocation.markDirty);
    ret &= fn(RS_HAL_ALLOCATION_SET_SURFACE, (void **)&rsc->mHal.funcs.allocation.setSurface);
    ret &= fn(RS_HAL_ALLOCATION_IO_SEND, (void **)&rsc->mHal.funcs.allocation.ioSend);
    ret &= fn(RS_HAL_ALLOCATION_IO_RECEIVE, (void **)&rsc->mHal.funcs.allocation.ioReceive);
    ret &= fn(RS_HAL_ALLOCATION_DATA_1D, (void **)&rsc->mHal.funcs.allocation.data1D);
    ret &= fn(RS_HAL_ALLOCATION_DATA_2D, (void **)&rsc->mHal.funcs.allocation.data2D);
    ret &= fn(RS_HAL_ALLOCATION_DATA_3D, (void **)&rsc->mHal.funcs.allocation.data3D);
    ret &= fn(RS_HAL_ALLOCATION_READ_1D, (void **)&rsc->mHal.funcs.allocation.read1D);
    ret &= fn(RS_HAL_ALLOCATION_READ_2D, (void **)&rsc->mHal.funcs.allocation.read2D);
    ret &= fn(RS_HAL_ALLOCATION_READ_3D, (void **)&rsc->mHal.funcs.allocation.read3D);
    ret &= fn(RS_HAL_ALLOCATION_LOCK_1D, (void **)&rsc->mHal.funcs.allocation.lock1D);
    ret &= fn(RS_HAL_ALLOCATION_UNLOCK_1D, (void **)&rsc->mHal.funcs.allocation.unlock1D);
    ret &= fn(RS_HAL_ALLOCATION_COPY_1D, (void **)&rsc->mHal.funcs.allocation.allocData1D);
    ret &= fn(RS_HAL_ALLOCATION_COPY_2D, (void **)&rsc->mHal.funcs.allocation.allocData2D);
    ret &= fn(RS_HAL_ALLOCATION_COPY_3D, (void **)&rsc->mHal.funcs.allocation.allocData3D);
    ret &= fn(RS_HAL_ALLOCATION_ELEMENT_DATA, (void **)&rsc->mHal.funcs.allocation.elementData);
    ret &= fn(RS_HAL_ALLOCATION_ELEMENT_READ, (void **)&rsc->mHal.funcs.allocation.elementRead);
    ret &= fn(RS_HAL_ALLOCATION_GENERATE_MIPMAPS, (void **)&rsc->mHal.funcs.allocation.generateMipmaps);
    ret &= fn(RS_HAL_ALLOCATION_UPDATE_CACHED_OBJECT, (void **)&rsc->mHal.funcs.allocation.updateCachedObject);
    ret &= fn(RS_HAL_ALLOCATION_ADAPTER_OFFSET, (void **)&rsc->mHal.funcs.allocation.adapterOffset);
    ret &= fn(RS_HAL_ALLOCATION_GET_POINTER, (void **)&rsc->mHal.funcs.allocation.getPointer);

    ret &= fn(RS_HAL_SAMPLER_INIT, (void **)&rsc->mHal.funcs.sampler.init);
    ret &= fn(RS_HAL_SAMPLER_DESTROY, (void **)&rsc->mHal.funcs.sampler.destroy);
    ret &= fn(RS_HAL_SAMPLER_UPDATE_CACHED_OBJECT, (void **)&rsc->mHal.funcs.sampler.updateCachedObject);

    ret &= fn(RS_HAL_TYPE_INIT, (void **)&rsc->mHal.funcs.type.init);
    ret &= fn(RS_HAL_TYPE_DESTROY, (void **)&rsc->mHal.funcs.type.destroy);
    ret &= fn(RS_HAL_TYPE_UPDATE_CACHED_OBJECT, (void **)&rsc->mHal.funcs.type.updateCachedObject);

    ret &= fn(RS_HAL_ELEMENT_INIT, (void **)&rsc->mHal.funcs.element.init);
    ret &= fn(RS_HAL_ELEMENT_DESTROY, (void **)&rsc->mHal.funcs.element.destroy);
    ret &= fn(RS_HAL_ELEMENT_UPDATE_CACHED_OBJECT, (void **)&rsc->mHal.funcs.element.updateCachedObject);

    ret &= fn(RS_HAL_SCRIPT_GROUP_INIT, (void **)&rsc->mHal.funcs.scriptgroup.init);
    ret &= fn(RS_HAL_SCRIPT_GROUP_DESTROY, (void **)&rsc->mHal.funcs.scriptgroup.destroy);
    ret &= fn(RS_HAL_SCRIPT_GROUP_UPDATE_CACHED_OBJECT, (void **)&rsc->mHal.funcs.scriptgroup.updateCachedObject);
    ret &= fn(RS_HAL_SCRIPT_GROUP_SET_INPUT, (void **)&rsc->mHal.funcs.scriptgroup.setInput);
    ret &= fn(RS_HAL_SCRIPT_GROUP_SET_OUTPUT, (void **)&rsc->mHal.funcs.scriptgroup.setOutput);
    ret &= fn(RS_HAL_SCRIPT_GROUP_EXECUTE, (void **)&rsc->mHal.funcs.scriptgroup.execute);


    if (loadGraphics) {
        ret &= fn(RS_HAL_GRAPHICS_INIT, (void **)&rsc->mHal.funcs.initGraphics);
        ret &= fn(RS_HAL_GRAPHICS_SHUTDOWN, (void **)&rsc->mHal.funcs.shutdownGraphics);
        ret &= fn(RS_HAL_GRAPHICS_SWAP, (void **)&rsc->mHal.funcs.swap);
        ret &= fn(RS_HAL_GRAPHICS_SET_SURFACE, (void **)&rsc->mHal.funcs.setSurface);
        ret &= fn(RS_HAL_GRAPHICS_RASTER_INIT, (void **)&rsc->mHal.funcs.raster.init);
        ret &= fn(RS_HAL_GRAPHICS_RASTER_SET_ACTIVE, (void **)&rsc->mHal.funcs.raster.setActive);
        ret &= fn(RS_HAL_GRAPHICS_RASTER_DESTROY, (void **)&rsc->mHal.funcs.raster.destroy);
        ret &= fn(RS_HAL_GRAPHICS_VERTEX_INIT, (void **)&rsc->mHal.funcs.vertex.init);
        ret &= fn(RS_HAL_GRAPHICS_VERTEX_SET_ACTIVE, (void **)&rsc->mHal.funcs.vertex.setActive);
        ret &= fn(RS_HAL_GRAPHICS_VERTEX_DESTROY, (void **)&rsc->mHal.funcs.vertex.destroy);
        ret &= fn(RS_HAL_GRAPHICS_FRAGMENT_INIT, (void **)&rsc->mHal.funcs.fragment.init);
        ret &= fn(RS_HAL_GRAPHICS_FRAGMENT_SET_ACTIVE, (void **)&rsc->mHal.funcs.fragment.setActive);
        ret &= fn(RS_HAL_GRAPHICS_FRAGMENT_DESTROY, (void **)&rsc->mHal.funcs.fragment.destroy);
        ret &= fn(RS_HAL_GRAPHICS_MESH_INIT, (void **)&rsc->mHal.funcs.mesh.init);
        ret &= fn(RS_HAL_GRAPHICS_MESH_DRAW, (void **)&rsc->mHal.funcs.mesh.draw);
        ret &= fn(RS_HAL_GRAPHICS_MESH_DESTROY, (void **)&rsc->mHal.funcs.mesh.destroy);
        ret &= fn(RS_HAL_GRAPHICS_FB_INIT, (void **)&rsc->mHal.funcs.framebuffer.init);
        ret &= fn(RS_HAL_GRAPHICS_FB_SET_ACTIVE, (void **)&rsc->mHal.funcs.framebuffer.setActive);
        ret &= fn(RS_HAL_GRAPHICS_FB_DESTROY, (void **)&rsc->mHal.funcs.framebuffer.destroy);
        ret &= fn(RS_HAL_GRAPHICS_STORE_INIT, (void **)&rsc->mHal.funcs.store.init);
        ret &= fn(RS_HAL_GRAPHICS_STORE_SET_ACTIVE, (void **)&rsc->mHal.funcs.store.setActive);
        ret &= fn(RS_HAL_GRAPHICS_STORE_DESTROY, (void **)&rsc->mHal.funcs.store.destroy);
    }

    return ret;
}

bool Context::loadRuntime(const char* filename) {
    HalQueryVersion fnQueryVersion = nullptr;
    HalQueryHal fnQueryHal = nullptr;
    HalInit fnInit = nullptr;
    HalAbort fnAbort = nullptr;


    // TODO: store the driverSO somewhere so we can dlclose later
    void *driverSO = nullptr;

    driverSO = dlopen(filename, RTLD_LAZY);
    if (driverSO == nullptr) {
        ALOGE("Failed loading RS driver: %s", dlerror());
        return false;
    }

    // Need to call dlerror() to clear buffer before using it for dlsym().
    (void) dlerror();

    fnQueryVersion = (HalQueryVersion) dlsym(driverSO, "rsdHalQueryVersion");
    fnQueryHal = (HalQueryHal) dlsym(driverSO, "rsdHalQueryHal");
    fnInit = (HalInit) dlsym(driverSO, "rsdHalInit");
    fnAbort = (HalAbort) dlsym(driverSO, "rsdHalAbort");
    uint32_t version_major = 0;
    uint32_t version_minor = 0;

    if ((fnQueryVersion == nullptr) || (fnQueryHal == nullptr) ||
        (fnInit == nullptr) || (fnAbort == nullptr)) {

        ALOGE("Failed to find hal setup entry points: %s", dlerror());
        goto error;
    }

    if (!fnQueryVersion(&version_major, &version_minor)) {
        ALOGE("Error checking RS driver version, %s", filename);
        goto error;
    }

    if (!LoadHalTable(this, fnQueryHal, mIsGraphicsContext)) {
        ALOGE("Error loading RS HAL table, %s", filename);
        goto error;
    }

    if (!(*fnInit)(this, 0, 0)) {
        ALOGE("Hal init failed,  %s", filename);
        goto error;
    }

    // Only map in the actual driver name if we successfully load the runtime.
    setDriverName(filename);

    return true;


error:
    if (fnAbort != nullptr) {
        fnAbort(this);
    }
    dlclose(driverSO);
    return false;
}



bool Context::loadDriver(bool forceDefault) {
    bool loadDefault = true;

    // Provide a mechanism for dropping in a different RS driver.
#ifndef RS_COMPATIBILITY_LIB
#ifdef OVERRIDE_RS_DRIVER
#define XSTR(S) #S
#define STR(S) XSTR(S)
#define OVERRIDE_RS_DRIVER_STRING STR(OVERRIDE_RS_DRIVER)

    if (!forceDefault) {
        if (loadRuntime(OVERRIDE_RS_DRIVER_STRING)) {
            ALOGV("Successfully loaded runtime: %s", OVERRIDE_RS_DRIVER_STRING);
            loadDefault = false;
        } else {
            ALOGE("Failed to load runtime %s, loading default", OVERRIDE_RS_DRIVER_STRING);
        }
    }
#undef XSTR
#undef STR
#endif  // OVERRIDE_RS_DRIVER

    if (loadDefault) {
        if (!loadRuntime("libRSDriver.so")) {
            ALOGE("Failed to load default runtime!");
            return false;
        }
    }
#else // RS_COMPATIBILITY_LIB
    if (!LoadHalTable(this, rsdHalQueryHal, false)) {
        ALOGE("Error loading RS HAL table");
        return false;
    }
    if (rsdHalInit(this, 0, 0) != true) {
        return false;
    }
#endif

    return true;
}



