diff --git a/dmabufheap/BUILD.gn b/dmabufheap/BUILD.gn new file mode 100644 index 0000000..19b7c8d --- /dev/null +++ b/dmabufheap/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2022 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. + +import("//build/ohos.gni") + +config("libdmabufheap_config") { + include_dirs = [ "include" ] +} + +ohos_shared_library("libdmabufheap") { + sources = [ "src/dmabuf_alloc.c" ] + include_dirs = [ "include" ] + deps = [ "//utils/native/base:utils" ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + public_configs = [ ":libdmabufheap_config" ] + subsystem_name = "utils" + part_name = "utils_memory" +} diff --git a/dmabufheap/include/dmabuf_alloc.h b/dmabufheap/include/dmabuf_alloc.h new file mode 100644 index 0000000..7e15867 --- /dev/null +++ b/dmabufheap/include/dmabuf_alloc.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022 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 LIB_DMA_BUF_HEAP_H +#define LIB_DMA_BUF_HEAP_H + +#include +#include + +#undef LOG_TAG +#define LOG_TAG "dmabufheap" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* End of #if __cplusplus */ +#endif /* End of #ifdef __cplusplus */ + +typedef enum { + DMA_BUF_HEAP_BUF_SYNC_RW = DMA_BUF_SYNC_RW, + DMA_BUF_HEAP_BUF_SYNC_READ = DMA_BUF_SYNC_READ, + DMA_BUF_HEAP_BUF_SYNC_WRITE = DMA_BUF_SYNC_WRITE, +} DmabufHeapBufferSyncType; + +typedef struct { + unsigned int fd; + size_t size; +} DmabufHeapBuffer; + +int DmabufHeapOpen(const char *heapName); + +int DmabufHeapClose(unsigned int fd); + +int DmabufHeapBufferAlloc(unsigned int heapFd, DmabufHeapBuffer *buffer); + +int DmabufHeapBufferFree(DmabufHeapBuffer *buffer); + +int DmabufHeapBufferSyncStart(unsigned int bufferFd, DmabufHeapBufferSyncType syncType); + +int DmabufHeapBufferSyncEnd(unsigned int bufferFd, DmabufHeapBufferSyncType syncType); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* End of #if __cplusplus */ +#endif /* End of #ifdef __cplusplus */ + +#endif /* LIB_DMA_BUF_HEAP_H */ \ No newline at end of file diff --git a/dmabufheap/ohos.build b/dmabufheap/ohos.build new file mode 100644 index 0000000..8f8fc8f --- /dev/null +++ b/dmabufheap/ohos.build @@ -0,0 +1,12 @@ +{ + "subsystem": "utils", + "parts": { + "utils_memory": { + "module_list": [ + "//utils/dmabufheap:libdmabufheap" + ], + "inner_kits": [], + "test_list": [] + } + } +} \ No newline at end of file diff --git a/dmabufheap/src/dmabuf_alloc.c b/dmabufheap/src/dmabuf_alloc.c new file mode 100644 index 0000000..8230882 --- /dev/null +++ b/dmabufheap/src/dmabuf_alloc.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2022 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "hilog/log.h" +#include "dmabuf_alloc.h" + +#define DMA_BUF_HEAP_ROOT "/dev/dma_heap/" +#define HEAP_ROOT_LEN strlen(DMA_BUF_HEAP_ROOT) +#define HEAP_NAME_MAX_LEN 128 +#define HEAP_PATH_LEN (HEAP_ROOT_LEN + HEAP_NAME_MAX_LEN + 1) + +static bool IsHeapNameValid(const char *heapName) +{ + if ((heapName == NULL) || (strlen(heapName) == 0) || + (strlen(heapName) >= HEAP_NAME_MAX_LEN)) { + return false; + } + + return true; +} + +static bool IsSyncTypeValid(DmabufHeapBufferSyncType syncType) +{ + switch (syncType) { + case DMA_BUF_HEAP_BUF_SYNC_RW: + case DMA_BUF_HEAP_BUF_SYNC_READ: + case DMA_BUF_HEAP_BUF_SYNC_WRITE: + return true; + default: + return false; + } +} + +int DmabufHeapOpen(const char *heapName) +{ + if (!IsHeapNameValid(heapName)) { + HILOG_ERROR(LOG_CORE, "heapName is wrong, name = %s.", (heapName == NULL) ? "NULL" : heapName); + return -EINVAL; + } + + char heapPath[HEAP_PATH_LEN] = DMA_BUF_HEAP_ROOT; + errno_t ret = strcat_s(heapPath, HEAP_PATH_LEN, heapName); + if (ret != EOK) { + HILOG_ERROR(LOG_CORE, "strcat_s is wrong, heapName = %s, ret = %d.", heapName, ret); + return -EINVAL; + } + + return open(heapPath, O_RDONLY | O_CLOEXEC); +} + +int DmabufHeapClose(unsigned int fd) +{ + return close(fd); +} + +int DmabufHeapBufferAlloc(unsigned int heapFd, DmabufHeapBuffer *buffer) +{ + if (buffer->size == 0) { + HILOG_ERROR(LOG_CORE, "alloc buffer size is wrong."); + return -EINVAL; + } + + struct dma_heap_allocation_data data = { + .len = buffer->size, + .fd_flags = O_RDWR | O_CLOEXEC, + }; + int ret = ioctl(heapFd, DMA_HEAP_IOCTL_ALLOC, &data); + if (ret < 0) { + HILOG_ERROR(LOG_CORE, "alloc buffer failed, size = %zu, ret = %d.", buffer->size, ret); + return ret; + } + + buffer->fd = data.fd; + return ret; +} + +int DmabufHeapBufferFree(DmabufHeapBuffer *buffer) +{ + return close(buffer->fd); +} + +int DmabufHeapBufferSyncStart(unsigned int fd, DmabufHeapBufferSyncType syncType) +{ + if (!IsSyncTypeValid(syncType)) { + HILOG_ERROR(LOG_CORE, "buffer start syncType is wrong, syncType = %u.", syncType); + return -EINVAL; + } + + struct dma_buf_sync sync = {0}; + sync.flags = DMA_BUF_SYNC_START | syncType; + return ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync); +} + +int DmabufHeapBufferSyncEnd(unsigned int fd, DmabufHeapBufferSyncType syncType) +{ + if (!IsSyncTypeValid(syncType)) { + HILOG_ERROR(LOG_CORE, "buffer end syncType is wrong, syncType = %u.", syncType); + return -EINVAL; + } + + struct dma_buf_sync sync = {0}; + sync.flags = DMA_BUF_SYNC_END | syncType; + return ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync); +} \ No newline at end of file