Merge pull request !13 from zleoyu/master_1009
This commit is contained in:
openharmony_ci 2023-03-29 02:29:09 +00:00 committed by Gitee
commit fc4325e87a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
11 changed files with 8544 additions and 8317 deletions

129
include/ohos_log.h Normal file
View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* 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 DISP_COMMON_H
#define DISP_COMMON_H
#include <string.h>
#include <stdint.h>
#include "hilog/log.h"
#ifdef HDF_LOG_TAG
#undef HDF_LOG_TAG
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#define FENCE_TIMEOUT 3000
#undef LOG_TAG
#undef LOG_DOMAIN
#define LOG_TAG "DISP"
#define LOG_DOMAIN 0xD001400
#ifndef DISPLAY_UNUSED
#define DISPLAY_UNUSED(x) ((void)(x))
#endif
#define DISP_FILENAME (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1) : __FILE__)
#ifndef DISPLAY_DEBUG_ENABLE
#define DISPLAY_DEBUG_ENABLE 1
#endif
#ifndef DISPLAY_LOGD
#define DISPLAY_LOGD(format, ...) \
do { \
if (DISPLAY_DEBUG_ENABLE) { \
HILOG_DEBUG(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", \
__FUNCTION__, DISP_FILENAME, __LINE__, \
##__VA_ARGS__); \
} \
} while (0)
#endif
#ifndef DISPLAY_LOGI
#define DISPLAY_LOGI(format, ...) \
do { \
HILOG_INFO(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, DISP_FILENAME, __LINE__, \
##__VA_ARGS__); \
} while (0)
#endif
#ifndef DISPLAY_LOGW
#define DISPLAY_LOGW(format, ...) \
do { \
HILOG_WARN(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, DISP_FILENAME, __LINE__, \
##__VA_ARGS__); \
} while (0)
#endif
#ifndef DISPLAY_LOGE
#define DISPLAY_LOGE(format, ...) \
do { \
HILOG_ERROR(LOG_CORE, \
"\033[0;32;31m" \
"[%{public}s@%{public}s:%{public}d] " format "\033[m" \
"\n", \
__FUNCTION__, DISP_FILENAME, __LINE__, ##__VA_ARGS__); \
} while (0)
#endif
#ifndef CHECK_NULLPOINTER_RETURN_VALUE
#define CHECK_NULLPOINTER_RETURN_VALUE(pointer, ret) \
do { \
if ((pointer) == NULL) { \
DISPLAY_LOGE("pointer is null and return ret\n"); \
return (ret); \
} \
} while (0)
#endif
#ifndef CHECK_NULLPOINTER_RETURN
#define CHECK_NULLPOINTER_RETURN(pointer) \
do { \
if ((pointer) == NULL) { \
DISPLAY_LOGE("pointer is null and return\n"); \
return; \
} \
} while (0)
#endif
#ifndef DISPLAY_CHK_RETURN
#define DISPLAY_CHK_RETURN(val, ret, ...) \
do { \
if (val) { \
__VA_ARGS__; \
return (ret); \
} \
} while (0)extern "C" {
#endif
#ifndef DISPLAY_CHK_RETURN_NOT_VALUE
#define DISPLAY_CHK_RETURN_NOT_VALUE(val, ...) \
do { \
if (val) { \
__VA_ARGS__; \
return; \
} \
} while (0)
#endif
#ifdef __cplusplus
}
#endif
#endif /* DISP_COMMON_H */

View File

@ -964,6 +964,7 @@ if with_platform_ohos
pre_args += '-DHAVE_OHOS_PLATFORM'
dep_ohos = [
dependency('libsurface'),
dependency('libhilog'),
]
c_args += '-I../ohos'
endif
@ -1607,6 +1608,10 @@ foreach d : _libdrm_checks
endif
endforeach
dep_hilog = dependency(
'libhilog'
)
with_gallium_drisw_kms = false
dep_libdrm = dependency(
'libdrm', version : '>=' + _drm_ver,

View File

@ -10,6 +10,8 @@
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
import("//build/config/clang/clang.gni")
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -18,52 +20,89 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import("//build/ohos.gni")
import("//build/config/clang/clang.gni")
import("dependency_inputs.gni")
mesa3d_libs_dir = "$root_build_dir/packages/phone/mesa3d"
mesa3d_gallium_symlinks = ["panfrost_dri.so"]
mesa3d_gallium_symlinks = [ "panfrost_dri.so" ]
mesa3d_all_lib_items = [
["libEGL.so.1.0.0", ["libEGL.so", "libEGL.so.1"]],
["libgbm.so.1.0.0", ["libgbm.so", "libgbm.so.1"]],
["libglapi.so.0.0.0", ["libglapi.so", "libglapi.so.0"]],
["libGLESv1_CM.so.1.1.0", ["libGLESv1_CM.so", "libGLESv1_CM.so.1"]],
["libGLESv2.so.2.0.0", ["libGLESv2.so", "libGLESv2.so.2", "libGLESv3.so"]],
["libgallium_dri.so", mesa3d_gallium_symlinks]
[
"libEGL.so.1.0.0",
[
"libEGL.so",
"libEGL.so.1",
"libEGL_impl.so",
],
],
[
"libgbm.so.1.0.0",
[
"libgbm.so",
"libgbm.so.1",
],
],
[
"libglapi.so.0.0.0",
[
"libglapi.so",
"libglapi.so.0",
],
],
[
"libGLESv1_CM.so.1.1.0",
[
"libGLESv1_CM.so",
"libGLESv1_CM.so.1",
"libGLESv1_impl.so",
],
],
[
"libGLESv2.so.2.0.0",
[
"libGLESv2.so",
"libGLESv2.so.2",
"libGLESv3.so",
"libGLESv2_impl.so",
"libGLESv3_impl.so",
],
],
[
"libgallium_dri.so",
mesa3d_gallium_symlinks,
],
]
action("mesa3d_build") {
inputs = deps_inputs
script = "build_mesa3d.py"
deps = [
"//foundation/graphic/graphic_2d:libsurface",
"//third_party/expat:expat",
]
outputs = []
foreach(item, mesa3d_all_lib_items) {
name = item[0]
outputs += [ "$mesa3d_libs_dir/$name" ]
}
args = [ rebase_path(root_build_dir) ]
inputs = deps_inputs
script = "build_mesa3d.py"
deps = [
"//foundation/graphic/graphic_2d:libsurface",
"//third_party/expat:expat",
]
outputs = []
foreach(item, mesa3d_all_lib_items) {
name = item[0]
outputs += [ "$mesa3d_libs_dir/$name" ]
}
args = [ rebase_path(root_build_dir) ]
}
mesa3d_all_lib_deps = []
foreach(item, mesa3d_all_lib_items) {
name = item[0]
ohos_prebuilt_shared_library(name) {
source = "$mesa3d_libs_dir/$name"
deps = [ ":mesa3d_build" ]
symlink_target_name = item[1]
install_enable = true
install_images = [ system_base_dir ]
subsystem_name = "rockchip_products"
part_name = "rockchip_products"
}
mesa3d_all_lib_deps += [ ":$name" ]
name = item[0]
ohos_prebuilt_shared_library(name) {
source = "$mesa3d_libs_dir/$name"
deps = [ ":mesa3d_build" ]
symlink_target_name = item[1]
install_enable = true
install_images = [ system_base_dir ]
subsystem_name = "rockchip_products"
part_name = "rockchip_products"
}
mesa3d_all_lib_deps += [ ":$name" ]
}
group("mesa3d_all_libs"){
deps = mesa3d_all_lib_deps
group("mesa3d_all_libs") {
deps = mesa3d_all_lib_deps
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
ohos_project_dir=ohos_project_directory_stub
libdir=${ohos_project_dir}/out/ohos-arm-release/graphic/graphic_standard/
libdir=${ohos_project_dir}/out/ohos-arm-release/thirdparty/libdrm/
includedir=${ohos_project_dir}/third_party/libdrm
Name: libdrm

View File

@ -1,8 +1,9 @@
ohos_project_dir=ohos_project_directory_stub
libdir=${ohos_project_dir}/out/ohos-arm-release/hiviewdfx/hilog_native
includedir=${ohos_project_dir}/foundation/graphic/standard/rosen/include/backstore/nativewindow
includedir=${ohos_project_dir}/base/hiviewdfx/hilog/interfaces/native/innerkits/include
Name: libhilog
Version: 2.4.1
Description: libhilog
Libs: -L${libdir} -lhilog
Cflags: -I${includedir}

File diff suppressed because it is too large Load Diff

View File

@ -27,14 +27,12 @@
*
**************************************************************************/
/**
* Logging facility for debug/info messages.
* _EGL_FATAL messages are printed to stderr
* The EGL_LOG_LEVEL var controls the output of other warning/info/debug msgs.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@ -55,29 +53,32 @@
#endif /* HAVE_ANDROID_PLATFORM */
#ifdef HAVE_OHOS_PLATFORM
#include "hilog/log.h"
#include "ohos_log.h"
#endif
#define MAXSTRING 1000
#define FALLBACK_LOG_LEVEL _EGL_WARNING
static struct {
mtx_t mutex;
mtx_t mutex;
EGLBoolean initialized;
EGLint level;
EGLBoolean initialized;
EGLint level;
} logging = {
.mutex = _MTX_INITIALIZER_NP,
.initialized = EGL_FALSE,
.level = FALLBACK_LOG_LEVEL,
.mutex = _MTX_INITIALIZER_NP,
.initialized = EGL_FALSE,
.level = FALLBACK_LOG_LEVEL,
};
static const char *level_strings[] = {
[_EGL_FATAL] = "fatal",
[_EGL_WARNING] = "warning",
[_EGL_INFO] = "info",
[_EGL_DEBUG] = "debug",
[_EGL_FATAL] = "fatal",
[_EGL_WARNING] = "warning",
[_EGL_INFO] = "info",
[_EGL_DEBUG] = "debug",
};
/**
* The default logger. It prints the message to stderr.
*/
@ -85,85 +86,83 @@ static void
_eglDefaultLogger(EGLint level, const char *msg)
{
#ifdef HAVE_ANDROID_PLATFORM
static const int egl2alog[] = {
[_EGL_FATAL] = ANDROID_LOG_ERROR,
[_EGL_WARNING] = ANDROID_LOG_WARN,
[_EGL_INFO] = ANDROID_LOG_INFO,
[_EGL_DEBUG] = ANDROID_LOG_DEBUG,
};
LOG_PRI(egl2alog[level], LOG_TAG, "%s", msg);
static const int egl2alog[] = {
[_EGL_FATAL] = ANDROID_LOG_ERROR,
[_EGL_WARNING] = ANDROID_LOG_WARN,
[_EGL_INFO] = ANDROID_LOG_INFO,
[_EGL_DEBUG] = ANDROID_LOG_DEBUG,
};
LOG_PRI(egl2alog[level], LOG_TAG, "%s", msg);
#else
fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg);
fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg);
DISPLAY_LOGE("libEGL %{public}s: %{public}s\n", level_strings[level], msg);
#endif /* HAVE_ANDROID_PLATFORM */
}
/**
* Initialize the logging facility.
*/
static void
_eglInitLogger(void)
{
const char *log_env;
EGLint i, level = -1;
const char *log_env;
EGLint i, level = -1;
if (logging.initialized)
return;
if (logging.initialized)
return;
log_env = getenv("EGL_LOG_LEVEL");
if (log_env) {
for (i = 0; i < ARRAY_SIZE(level_strings); i++) {
if (strcasecmp(log_env, level_strings[i]) == 0) {
level = i;
break;
}
}
}
log_env = getenv("EGL_LOG_LEVEL");
if (log_env) {
for (i = 0; i < ARRAY_SIZE(level_strings); i++) {
if (strcasecmp(log_env, level_strings[i]) == 0) {
level = i;
break;
}
}
}
logging.level = (level >= 0) ? level : FALLBACK_LOG_LEVEL;
logging.initialized = EGL_TRUE;
logging.level = (level >= 0) ? level : FALLBACK_LOG_LEVEL;
logging.initialized = EGL_TRUE;
/* it is fine to call _eglLog now */
if (log_env && level < 0) {
_eglLog(_EGL_WARNING,
"Unrecognized EGL_LOG_LEVEL environment variable value. "
"Expected one of \"fatal\", \"warning\", \"info\", \"debug\". "
"Got \"%s\". Falling back to \"%s\".",
log_env, level_strings[FALLBACK_LOG_LEVEL]);
}
/* it is fine to call _eglLog now */
if (log_env && level < 0) {
_eglLog(_EGL_WARNING,
"Unrecognized EGL_LOG_LEVEL environment variable value. "
"Expected one of \"fatal\", \"warning\", \"info\", \"debug\". "
"Got \"%s\". Falling back to \"%s\".",
log_env, level_strings[FALLBACK_LOG_LEVEL]);
}
}
/**
* Log a message with message logger.
* \param level one of _EGL_FATAL, _EGL_WARNING, _EGL_INFO, _EGL_DEBUG.
*/
void
_eglLog(EGLint level, const char *fmtStr, ...)
void _eglLog(EGLint level, const char *fmtStr, ...)
{
va_list args;
char msg[MAXSTRING];
int ret;
va_list args;
char msg[MAXSTRING];
int ret;
DISPLAY_LOGD();
/* one-time initialization; a little race here is fine */
/*
if (!logging.initialized)
_eglInitLogger();
if (level > logging.level || level < 0)
return;
*/
mtx_lock(&logging.mutex);
/* one-time initialization; a little race here is fine */
/*
if (!logging.initialized)
_eglInitLogger();
if (level > logging.level || level < 0)
return;
*/
mtx_lock(&logging.mutex);
va_start(args, fmtStr);
ret = vsnprintf(msg, MAXSTRING, fmtStr, args);
if (ret < 0 || ret >= MAXSTRING)
strcpy(msg, "<message truncated>");
va_end(args);
va_start(args, fmtStr);
ret = vsnprintf(msg, MAXSTRING, fmtStr, args);
if (ret < 0 || ret >= MAXSTRING)
strcpy(msg, "<message truncated>");
va_end(args);
_eglDefaultLogger(level, msg);
_eglDefaultLogger(level, msg);
mtx_unlock(&logging.mutex);
mtx_unlock(&logging.mutex);
if (level == _EGL_FATAL)
exit(1); /* or abort()? */
if (level == _EGL_FATAL)
exit(1); /* or abort()? */
}

View File

@ -67,318 +67,372 @@
#define PATH_MAX 4096
#endif
#include "ohos_log.h"
static void default_logger(int level, const char *fmt, ...)
{
if (level <= _LOADER_WARNING) {
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
const int MAX_BUFFER_LEN = 1024;
char log_string[MAX_BUFFER_LEN];
if (level <= _LOADER_WARNING) {
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
sprintf_s(log_string, MAX_BUFFER_LEN, fmt, args);
va_end(args);
}
DISPLAY_LOGI();
}
static loader_logger *log_ = default_logger;
int
loader_open_device(const char *device_name)
static void ohos_logger(int level, const char *fmt, ...)
{
int fd;
const int MAX_BUFFER_LEN = 1024;
char log_string[MAX_BUFFER_LEN];
va_list args;
va_start(args, fmt);
(void)sprintf_s(log_string, MAX_BUFFER_LEN, fmt, args);
va_end(args);
switch (level) {
case _LOADER_WARNING:
DISPLAY_LOGW("%{public}s", log_string);
break;
case _LOADER_DEBUG:
DISPLAY_LOGD("%{public}s", log_string);
break;
case _LOADER_FATAL:
DISPLAY_LOGE("%{public}s", log_string);
break;
case _LOADER_INFO:
DISPLAY_LOGI("%{public}s", log_string);
break;
default:
break;
}
DISPLAY_LOGI();
}
static loader_logger *log_ = ohos_logger;
int loader_open_device(const char *device_name)
{
log_(_LOADER_WARNING, "loader_open_device %s", device_name);
int fd;
#ifdef O_CLOEXEC
fd = open(device_name, O_RDWR | O_CLOEXEC);
if (fd == -1 && errno == EINVAL)
fd = open(device_name, O_RDWR | O_CLOEXEC);
#endif
{
fd = open(device_name, O_RDWR);
if (fd != -1)
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
}
if (fd == -1 && errno == EACCES) {
log_(_LOADER_WARNING, "failed to open %s: %s\n",
device_name, strerror(errno));
}
return fd;
if (fd == -1 && errno == EINVAL) {
fd = open(device_name, O_RDWR);
if (fd != -1) {
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
}
}
if (fd == -1 && errno == EACCES) {
log_(_LOADER_WARNING, "failed to open %s: %s\n",
device_name, strerror(errno));
}
return fd;
}
static char *loader_get_kernel_driver_name(int fd)
{
#if HAVE_LIBDRM
char *driver;
drmVersionPtr version = drmGetVersion(fd);
char *driver;
drmVersionPtr version = drmGetVersion(fd);
if (!version) {
log_(_LOADER_WARNING, "failed to get driver name for fd %d\n", fd);
return NULL;
}
if (!version) {
log_(_LOADER_WARNING, "failed to get driver name for fd %d\n", fd);
return NULL;
}
driver = strndup(version->name, version->name_len);
log_(driver ? _LOADER_DEBUG : _LOADER_WARNING, "using driver %s for %d\n",
driver, fd);
driver = strndup(version->name, version->name_len);
log_(driver ? _LOADER_DEBUG : _LOADER_WARNING, "using driver %s for %d\n",
driver, fd);
drmFreeVersion(version);
return driver;
drmFreeVersion(version);
return driver;
#else
return NULL;
return NULL;
#endif
}
bool
is_kernel_i915(int fd)
bool is_kernel_i915(int fd)
{
char *kernel_driver = loader_get_kernel_driver_name(fd);
bool is_i915 = kernel_driver && strcmp(kernel_driver, "i915") == 0;
char *kernel_driver = loader_get_kernel_driver_name(fd);
bool is_i915 = kernel_driver && strcmp(kernel_driver, "i915") == 0;
free(kernel_driver);
return is_i915;
free(kernel_driver);
return is_i915;
}
#if defined(HAVE_LIBDRM)
int
loader_open_render_node(const char *name)
int loader_open_render_node(const char *name)
{
drmDevicePtr devices[MAX_DRM_DEVICES], device;
int i, num_devices, fd = -1;
drmDevicePtr devices[MAX_DRM_DEVICES], device;
int i, num_devices, fd = -1;
num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
if (num_devices <= 0)
return -ENOENT;
num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
if (num_devices <= 0) {
return -ENOENT;
}
for (i = 0; i < num_devices; i++) {
device = devices[i];
for (i = 0; i < num_devices; i++) {
device = devices[i];
if ((device->available_nodes & (1 << DRM_NODE_RENDER)) &&
(device->bustype == DRM_BUS_PLATFORM)) {
drmVersionPtr version;
if ((device->available_nodes & (1 << DRM_NODE_RENDER)) &&
(device->bustype == DRM_BUS_PLATFORM)) {
drmVersionPtr version;
fd = loader_open_device(device->nodes[DRM_NODE_RENDER]);
if (fd < 0)
continue;
fd = loader_open_device(device->nodes[DRM_NODE_RENDER]);
if (fd < 0) {
continue;
}
version = drmGetVersion(fd);
if (!version) {
close(fd);
continue;
}
version = drmGetVersion(fd);
if (!version) {
close(fd);
continue;
}
if (strcmp(version->name, name) != 0) {
drmFreeVersion(version);
close(fd);
continue;
}
if (strcmp(version->name, name) != 0) {
drmFreeVersion(version);
close(fd);
continue;
}
break;
}
}
drmFreeDevices(devices, num_devices);
drmFreeVersion(version);
break;
}
}
drmFreeDevices(devices, num_devices);
if (i == num_devices) {
return -ENOENT;
}
if (i == num_devices)
return -ENOENT;
return fd;
return fd;
}
#ifdef USE_DRICONF
static const driOptionDescription __driConfigOptionsLoader[] = {
DRI_CONF_SECTION_INITIALIZATION
DRI_CONF_DEVICE_ID_PATH_TAG()
DRI_CONF_DRI_DRIVER()
DRI_CONF_SECTION_END
};
DRI_CONF_DRI_DRIVER()
DRI_CONF_SECTION_END};
static char *loader_get_dri_config_driver(int fd)
{
driOptionCache defaultInitOptions;
driOptionCache userInitOptions;
char *dri_driver = NULL;
char *kernel_driver = loader_get_kernel_driver_name(fd);
driOptionCache defaultInitOptions;
driOptionCache userInitOptions;
char *dri_driver = NULL;
char *kernel_driver = loader_get_kernel_driver_name(fd);
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader,
ARRAY_SIZE(__driConfigOptionsLoader));
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
"loader", kernel_driver, NULL, NULL, 0, NULL, 0);
if (driCheckOption(&userInitOptions, "dri_driver", DRI_STRING)) {
char *opt = driQueryOptionstr(&userInitOptions, "dri_driver");
/* not an empty string */
if (*opt)
dri_driver = strdup(opt);
}
driDestroyOptionCache(&userInitOptions);
driDestroyOptionInfo(&defaultInitOptions);
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader,
ARRAY_SIZE(__driConfigOptionsLoader));
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
"loader", kernel_driver, NULL, NULL, 0, NULL, 0);
if (driCheckOption(&userInitOptions, "dri_driver", DRI_STRING)) {
char *opt = driQueryOptionstr(&userInitOptions, "dri_driver");
/* not an empty string */
if (*opt) {
dri_driver = strdup(opt);
}
}
driDestroyOptionCache(&userInitOptions);
driDestroyOptionInfo(&defaultInitOptions);
free(kernel_driver);
return dri_driver;
free(kernel_driver);
return dri_driver;
}
static char *loader_get_dri_config_device_id(void)
{
driOptionCache defaultInitOptions;
driOptionCache userInitOptions;
char *prime = NULL;
driOptionCache defaultInitOptions;
driOptionCache userInitOptions;
char *prime = NULL;
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader,
ARRAY_SIZE(__driConfigOptionsLoader));
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
"loader", NULL, NULL, NULL, 0, NULL, 0);
if (driCheckOption(&userInitOptions, "device_id", DRI_STRING))
prime = strdup(driQueryOptionstr(&userInitOptions, "device_id"));
driDestroyOptionCache(&userInitOptions);
driDestroyOptionInfo(&defaultInitOptions);
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader,
ARRAY_SIZE(__driConfigOptionsLoader));
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
"loader", NULL, NULL, NULL, 0, NULL, 0);
if (driCheckOption(&userInitOptions, "device_id", DRI_STRING)) {
prime = strdup(driQueryOptionstr(&userInitOptions, "device_id"));
}
driDestroyOptionCache(&userInitOptions);
driDestroyOptionInfo(&defaultInitOptions);
return prime;
return prime;
}
#endif
static char *drm_construct_id_path_tag(drmDevicePtr device)
{
char *tag = NULL;
char *tag = NULL;
if (device->bustype == DRM_BUS_PCI) {
if (asprintf(&tag, "pci-%04x_%02x_%02x_%1u",
device->businfo.pci->domain,
device->businfo.pci->bus,
device->businfo.pci->dev,
device->businfo.pci->func) < 0) {
return NULL;
}
} else if (device->bustype == DRM_BUS_PLATFORM ||
device->bustype == DRM_BUS_HOST1X) {
char *fullname, *name, *address;
if (device->bustype == DRM_BUS_PCI) {
if (asprintf(&tag, "pci-%04x_%02x_%02x_%1u",
device->businfo.pci->domain,
device->businfo.pci->bus,
device->businfo.pci->dev,
device->businfo.pci->func) < 0) {
return NULL;
}
} else if (device->bustype == DRM_BUS_PLATFORM ||
device->bustype == DRM_BUS_HOST1X) {
char *fullname, *name, *address;
if (device->bustype == DRM_BUS_PLATFORM)
fullname = device->businfo.platform->fullname;
else
fullname = device->businfo.host1x->fullname;
if (device->bustype == DRM_BUS_PLATFORM) {
fullname = device->businfo.platform->fullname;
} else {
fullname = device->businfo.host1x->fullname;
}
name = strrchr(fullname, '/');
if (!name)
name = strdup(fullname);
else
name = strdup(name + 1);
name = strrchr(fullname, '/');
if (!name) {
name = strdup(fullname);
} else {
name = strdup(name + 1);
}
address = strchr(name, '@');
if (address) {
*address++ = '\0';
address = strchr(name, '@');
if (address) {
*address++ = '\0';
if (asprintf(&tag, "platform-%s_%s", address, name) < 0)
tag = NULL;
} else {
if (asprintf(&tag, "platform-%s", name) < 0)
tag = NULL;
}
if (asprintf(&tag, "platform-%s_%s", address, name) < 0) {
tag = NULL;
}
} else {
if (asprintf(&tag, "platform-%s", name) < 0) {
tag = NULL;
}
}
free(name);
}
return tag;
free(name);
}
return tag;
}
static bool drm_device_matches_tag(drmDevicePtr device, const char *prime_tag)
{
char *tag = drm_construct_id_path_tag(device);
int ret;
char *tag = drm_construct_id_path_tag(device);
int ret;
if (tag == NULL)
return false;
if (tag == NULL) {
return false;
}
ret = strcmp(tag, prime_tag);
ret = strcmp(tag, prime_tag);
free(tag);
return ret == 0;
free(tag);
return ret == 0;
}
static char *drm_get_id_path_tag_for_fd(int fd)
{
drmDevicePtr device;
char *tag;
drmDevicePtr device;
char *tag;
if (drmGetDevice2(fd, 0, &device) != 0)
return NULL;
if (drmGetDevice2(fd, 0, &device) != 0) {
return NULL;
}
tag = drm_construct_id_path_tag(device);
drmFreeDevice(&device);
return tag;
tag = drm_construct_id_path_tag(device);
drmFreeDevice(&device);
return tag;
}
int loader_get_user_preferred_fd(int default_fd, bool *different_device)
int loader_get_user_preferred_fd(int default_fd,
bool *different_device)
{
const char *dri_prime = getenv("DRI_PRIME");
char *default_tag, *prime = NULL;
drmDevicePtr devices[MAX_DRM_DEVICES];
int i, num_devices, fd = -1;
const char *dri_prime = getenv("DRI_PRIME");
char *default_tag, *prime = NULL;
drmDevicePtr devices[MAX_DRM_DEVICES];
int i, num_devices, fd = -1;
if (dri_prime)
prime = strdup(dri_prime);
#ifdef USE_DRICONF
else
prime = loader_get_dri_config_device_id();
if (dri_prime) {
prime = strdup(dri_prime);
} else {
prime = loader_get_dri_config_device_id();
}
#else
if (dri_prime) {
prime = strdup(dri_prime);
}
#endif
if (prime == NULL) {
*different_device = false;
return default_fd;
}
if (prime == NULL) {
*different_device = false;
return default_fd;
}
default_tag = drm_get_id_path_tag_for_fd(default_fd);
if (default_tag == NULL)
goto err;
default_tag = drm_get_id_path_tag_for_fd(default_fd);
if (default_tag == NULL) {
goto err;
}
num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
if (num_devices <= 0)
goto err;
num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
if (num_devices <= 0) {
goto err;
}
for (i = 0; i < num_devices; i++) {
if (!(devices[i]->available_nodes & 1 << DRM_NODE_RENDER))
continue;
/* two formats of DRI_PRIME are supported:
* "1": choose any other card than the card used by default.
* id_path_tag: (for example "pci-0000_02_00_0") choose the card
* with this id_path_tag.
*/
if (!strcmp(prime,"1")) {
if (drm_device_matches_tag(devices[i], default_tag))
for (i = 0; i < num_devices; i++) {
if (!(devices[i]->available_nodes & 1 << DRM_NODE_RENDER)) {
continue;
} else {
if (!drm_device_matches_tag(devices[i], prime))
continue;
}
}
fd = loader_open_device(devices[i]->nodes[DRM_NODE_RENDER]);
break;
}
drmFreeDevices(devices, num_devices);
/* two formats of DRI_PRIME are supported:
* "1": choose any other card than the card used by default.
* id_path_tag: (for example "pci-0000_02_00_0") choose the card
* with this id_path_tag.
*/
if (!strcmp(prime, "1")) {
if (drm_device_matches_tag(devices[i], default_tag)) {
continue;
}
} else {
if (!drm_device_matches_tag(devices[i], prime)) {
continue;
}
}
if (i == num_devices)
goto err;
fd = loader_open_device(devices[i]->nodes[DRM_NODE_RENDER]);
break;
}
drmFreeDevices(devices, num_devices);
if (fd < 0)
goto err;
if (i == num_devices) {
goto err;
}
close(default_fd);
if (fd < 0) {
goto err;
}
*different_device = !!strcmp(default_tag, prime);
close(default_fd);
free(default_tag);
free(prime);
return fd;
*different_device = !!strcmp(default_tag, prime);
err:
*different_device = false;
free(default_tag);
free(prime);
return fd;
free(default_tag);
free(prime);
return default_fd;
err:
*different_device = false;
free(default_tag);
free(prime);
return default_fd;
}
#else
int
loader_open_render_node(const char *name)
int loader_open_render_node(const char *name)
{
return -1;
return -1;
}
int loader_get_user_preferred_fd(int default_fd, bool *different_device)
int loader_get_user_preferred_fd(int default_fd,
bool *different_device)
{
*different_device = false;
return default_fd;
*different_device = false;
return default_fd;
}
#endif
@ -387,133 +441,138 @@ int loader_get_user_preferred_fd(int default_fd, bool *different_device)
static bool
drm_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
{
drmDevicePtr device;
drmDevicePtr device;
if (drmGetDevice2(fd, 0, &device) != 0) {
log_(_LOADER_WARNING, "MESA-LOADER: failed to retrieve device information\n");
return false;
}
if (drmGetDevice2(fd, 0, &device) != 0) {
log_(_LOADER_WARNING, "MESA-LOADER: failed to retrieve device information\n");
return false;
}
if (device->bustype != DRM_BUS_PCI) {
drmFreeDevice(&device);
log_(_LOADER_DEBUG, "MESA-LOADER: device is not located on the PCI bus\n");
return false;
}
if (device->bustype != DRM_BUS_PCI) {
drmFreeDevice(&device);
log_(_LOADER_DEBUG, "MESA-LOADER: device is not located on the PCI bus\n");
return false;
}
*vendor_id = device->deviceinfo.pci->vendor_id;
*chip_id = device->deviceinfo.pci->device_id;
drmFreeDevice(&device);
return true;
*vendor_id = device->deviceinfo.pci->vendor_id;
*chip_id = device->deviceinfo.pci->device_id;
drmFreeDevice(&device);
return true;
}
#endif
bool
loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
bool loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
{
#if HAVE_LIBDRM
return drm_get_pci_id_for_fd(fd, vendor_id, chip_id);
return drm_get_pci_id_for_fd(fd, vendor_id, chip_id);
#endif
return false;
return false;
}
char *
loader_get_device_name_for_fd(int fd)
{
char *result = NULL;
char *result = NULL;
#if HAVE_LIBDRM
result = drmGetDeviceNameFromFd2(fd);
result = drmGetDeviceNameFromFd2(fd);
#endif
return result;
return result;
}
static char *
loader_get_pci_driver(int fd)
{
int vendor_id, chip_id, i, j;
char *driver = NULL;
int vendor_id, chip_id, i, j;
char *driver = NULL;
if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id))
return NULL;
if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) {
return NULL;
}
for (i = 0; i < ARRAY_SIZE(driver_map); i++) {
if (vendor_id != driver_map[i].vendor_id)
continue;
for (i = 0; i < ARRAY_SIZE(driver_map); i++) {
if (vendor_id != driver_map[i].vendor_id) {
continue;
}
if (driver_map[i].predicate && !driver_map[i].predicate(fd))
continue;
if (driver_map[i].predicate && !driver_map[i].predicate(fd)) {
continue;
}
if (driver_map[i].num_chips_ids == -1) {
driver = strdup(driver_map[i].driver);
goto out;
}
for (j = 0; j < driver_map[i].num_chips_ids; j++)
if (driver_map[i].chip_ids[j] == chip_id) {
if (driver_map[i].num_chips_ids == -1) {
driver = strdup(driver_map[i].driver);
goto out;
}
}
}
for (j = 0; j < driver_map[i].num_chips_ids; j++)
if (driver_map[i].chip_ids[j] == chip_id) {
driver = strdup(driver_map[i].driver);
goto out;
}
}
out:
log_(driver ? _LOADER_DEBUG : _LOADER_WARNING,
log_(driver ? _LOADER_DEBUG : _LOADER_WARNING,
"pci id for fd %d: %04x:%04x, driver %s\n",
fd, vendor_id, chip_id, driver);
return driver;
return driver;
}
char *
loader_get_driver_for_fd(int fd)
{
char *driver;
char *driver;
/* Allow an environment variable to force choosing a different driver
* binary. If that driver binary can't survive on this FD, that's the
* user's problem, but this allows vc4 simulator to run on an i965 host,
* and may be useful for some touch testing of i915 on an i965 host.
*/
if (geteuid() == getuid()) {
driver = getenv("MESA_LOADER_DRIVER_OVERRIDE");
if (driver)
return strdup(driver);
}
/* Allow an environment variable to force choosing a different driver
* binary. If that driver binary can't survive on this FD, that's the
* user's problem, but this allows vc4 simulator to run on an i965 host,
* and may be useful for some touch testing of i915 on an i965 host.
*/
if (geteuid() == getuid()) {
driver = getenv("MESA_LOADER_DRIVER_OVERRIDE");
if (driver) {
return strdup(driver);
}
}
#if defined(HAVE_LIBDRM) && defined(USE_DRICONF)
driver = loader_get_dri_config_driver(fd);
if (driver)
return driver;
driver = loader_get_dri_config_driver(fd);
if (driver) {
return driver;
}
#endif
driver = loader_get_pci_driver(fd);
if (!driver)
driver = loader_get_kernel_driver_name(fd);
driver = loader_get_pci_driver(fd);
if (!driver) {
driver = loader_get_kernel_driver_name(fd);
}
return driver;
return driver;
}
void
loader_set_logger(loader_logger *logger)
void loader_set_logger(loader_logger *logger)
{
log_ = logger;
log_ = logger;
}
char *
loader_get_extensions_name(const char *driver_name)
{
char *name = NULL;
char *name = NULL;
if (asprintf(&name, "%s_%s", __DRI_DRIVER_GET_EXTENSIONS, driver_name) < 0)
return NULL;
if (asprintf(&name, "%s_%s", __DRI_DRIVER_GET_EXTENSIONS, driver_name) < 0) {
return NULL;
}
const size_t len = strlen(name);
for (size_t i = 0; i < len; i++) {
if (name[i] == '-')
name[i] = '_';
}
const size_t len = strlen(name);
for (size_t i = 0; i < len; i++) {
if (name[i] == '-') {
name[i] = '_';
}
}
return name;
return name;
}
/**
@ -534,62 +593,66 @@ loader_open_driver_lib(const char *driver_name,
const char *default_search_path,
bool warn_on_fail)
{
char path[PATH_MAX];
const char *search_paths, *next, *end;
char path[PATH_MAX];
const char *search_paths, *next, *end;
search_paths = NULL;
if (geteuid() == getuid() && search_path_vars) {
for (int i = 0; search_path_vars[i] != NULL; i++) {
search_paths = getenv(search_path_vars[i]);
if (search_paths)
break;
}
}
if (search_paths == NULL)
search_paths = default_search_path;
search_paths = NULL;
if (geteuid() == getuid() && search_path_vars) {
for (int i = 0; search_path_vars[i] != NULL; i++) {
search_paths = getenv(search_path_vars[i]);
if (search_paths) {
break;
}
}
}
if (search_paths == NULL) {
search_paths = default_search_path;
}
void *driver = NULL;
const char *dl_error = NULL;
end = search_paths + strlen(search_paths);
for (const char *p = search_paths; p < end; p = next + 1) {
int len;
next = strchr(p, ':');
if (next == NULL)
next = end;
void *driver = NULL;
const char *dl_error = NULL;
end = search_paths + strlen(search_paths);
for (const char *p = search_paths; p < end; p = next + 1) {
int len;
next = strchr(p, ':');
if (next == NULL) {
next = end;
}
len = next - p;
len = next - p;
#if USE_ELF_TLS
snprintf(path, sizeof(path), "%.*s/tls/%s%s.so", len,
p, driver_name, lib_suffix);
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
snprintf(path, sizeof(path), "%.*s/tls/%s%s.so", len,
p, driver_name, lib_suffix);
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
#endif
if (driver == NULL) {
snprintf(path, sizeof(path), "%.*s/%s%s.so", len,
p, driver_name, lib_suffix);
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
if (driver == NULL) {
dl_error = dlerror();
log_(_LOADER_DEBUG, "MESA-LOADER: failed to open %s: %s\n",
path, dl_error);
}
}
/* not need continue to loop all paths once the driver is found */
if (driver != NULL)
break;
}
if (driver == NULL) {
snprintf(path, sizeof(path), "%.*s/%s%s.so", len,
p, driver_name, lib_suffix);
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
if (driver == NULL) {
dl_error = dlerror();
log_(_LOADER_DEBUG, "MESA-LOADER: failed to open %s: %s\n",
path, dl_error);
}
}
/* not need continue to loop all paths once the driver is found */
if (driver != NULL) {
break;
}
}
if (driver == NULL) {
if (warn_on_fail) {
log_(_LOADER_WARNING,
"MESA-LOADER: failed to open %s: %s (search paths %s, suffix %s)\n",
driver_name, dl_error, search_paths, lib_suffix);
}
return NULL;
}
if (driver == NULL) {
if (warn_on_fail) {
log_(_LOADER_WARNING,
"MESA-LOADER: failed to open %s: %s (search paths %s, suffix %s)\n",
driver_name, dl_error, search_paths, lib_suffix);
}
return NULL;
}
log_(_LOADER_DEBUG, "MESA-LOADER: dlopen(%s)\n", path);
log_(_LOADER_DEBUG, "MESA-LOADER: dlopen(%s)\n", path);
return driver;
return driver;
}
/**
@ -606,37 +669,39 @@ loader_open_driver(const char *driver_name,
void **out_driver_handle,
const char **search_path_vars)
{
char *get_extensions_name;
const struct __DRIextensionRec **extensions = NULL;
const struct __DRIextensionRec **(*get_extensions)(void);
void *driver = loader_open_driver_lib(driver_name, "_dri", search_path_vars,
DEFAULT_DRIVER_DIR, true);
char *get_extensions_name;
const struct __DRIextensionRec **extensions = NULL;
const struct __DRIextensionRec **(*get_extensions)(void);
void *driver = loader_open_driver_lib(driver_name, "_dri", search_path_vars,
DEFAULT_DRIVER_DIR, true);
if (!driver)
goto failed;
if (!driver) {
goto failed;
}
get_extensions_name = loader_get_extensions_name(driver_name);
if (get_extensions_name) {
get_extensions = dlsym(driver, get_extensions_name);
if (get_extensions) {
extensions = get_extensions();
} else {
log_(_LOADER_DEBUG, "MESA-LOADER: driver does not expose %s(): %s\n",
get_extensions_name, dlerror());
}
free(get_extensions_name);
}
get_extensions_name = loader_get_extensions_name(driver_name);
if (get_extensions_name) {
get_extensions = dlsym(driver, get_extensions_name);
if (get_extensions) {
extensions = get_extensions();
} else {
log_(_LOADER_DEBUG, "MESA-LOADER: driver does not expose %s(): %s\n",
get_extensions_name, dlerror());
}
free(get_extensions_name);
}
if (!extensions)
extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
log_(_LOADER_WARNING,
"MESA-LOADER: driver exports no extensions (%s)\n", dlerror());
dlclose(driver);
driver = NULL;
}
if (!extensions) {
extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
}
if (extensions == NULL) {
log_(_LOADER_WARNING,
"MESA-LOADER: driver exports no extensions (%s)\n", dlerror());
dlclose(driver);
driver = NULL;
}
failed:
*out_driver_handle = driver;
return extensions;
*out_driver_handle = driver;
return extensions;
}

View File

@ -38,7 +38,7 @@ struct __DRIextensionRec;
/* Helpers to figure out driver and device name, eg. from pci-id, etc. */
int
loader_open_device(const char *);
loader_open_device(const char *device_name);
int
loader_open_render_node(const char *name);

View File

@ -55,6 +55,6 @@ libloader = static_library(
c_args : loader_c_args,
gnu_symbol_visibility : 'hidden',
include_directories : [inc_include, inc_src, inc_util],
dependencies : [dep_libdrm, dep_thread],
dependencies : [dep_libdrm, dep_thread, dep_hilog],
build_by_default : false,
)