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

Commit 6c65610f authored by Elliott Hughes's avatar Elliott Hughes Committed by Automerger Merge Worker
Browse files

Merge "libvulkan: refactor for _FORTIFY_SOURCE=3 support." into main am: 78275975

parents 3ea3bd3e 78275975
Loading
Loading
Loading
Loading
+32 −8
Original line number Diff line number Diff line
@@ -41,14 +41,9 @@ cc_aconfig_library {
    aconfig_declarations: "libvulkan_flags",
}

cc_library_shared {
    name: "libvulkan",
    llndk: {
        symbol_file: "libvulkan.map.txt",
        export_llndk_headers: [
            "vulkan_headers",
        ],
    },
cc_defaults {
    name: "libvulkan_defaults",

    sanitize: {
        misc_undefined: ["integer"],
    },
@@ -81,6 +76,34 @@ cc_library_shared {
        "-Wno-global-constructors",
        "-Wno-zero-length-array",
    ],
}

cc_library {
    name: "libvulkanallocator",
    defaults: ["libvulkan_defaults"],
    cflags: [
        // This code uses malloc_usable_size(),
        // and thus can't be built with _FORTIFY_SOURCE=3.
        "-U_FORTIFY_SOURCE",
        "-D_FORTIFY_SOURCE=2",
    ],
    srcs: [
        "allocator.cpp",
    ],
    header_libs: [
        "vulkan_headers",
    ],
}

cc_library_shared {
    name: "libvulkan",
    defaults: ["libvulkan_defaults"],
    llndk: {
        symbol_file: "libvulkan.map.txt",
        export_llndk_headers: [
            "vulkan_headers",
        ],
    },

    srcs: [
        "api.cpp",
@@ -124,6 +147,7 @@ cc_library_shared {
    ],
    static_libs: [
        "libgrallocusage",
        "libvulkanallocator",
        "libvulkanflags",
    ],
}
+113 −0
Original line number Diff line number Diff line
/*
 * Copyright 2025 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.
 */

#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include "allocator.h"

#include <stdlib.h>

#include <algorithm>

#include <log/log.h>

// #define ENABLE_ALLOC_CALLSTACKS 1
#if ENABLE_ALLOC_CALLSTACKS
#include <utils/CallStack.h>
#define ALOGD_CALLSTACK(...)                             \
    do {                                                 \
        ALOGD(__VA_ARGS__);                              \
        android::CallStack callstack;                    \
        callstack.update();                              \
        callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, "  "); \
    } while (false)
#else
#define ALOGD_CALLSTACK(...) \
    do {                     \
    } while (false)
#endif

namespace vulkan {
namespace driver {

namespace {

VKAPI_ATTR void* DefaultAllocate(void*,
                                 size_t size,
                                 size_t alignment,
                                 VkSystemAllocationScope) {
    void* ptr = nullptr;
    // Vulkan requires 'alignment' to be a power of two, but posix_memalign
    // additionally requires that it be at least sizeof(void*).
    int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
    ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
                    ret, ptr);
    return ret == 0 ? ptr : nullptr;
}

// This function is marked `noinline` so that LLVM can't infer an object size
// for FORTIFY through it, given that it's abusing malloc_usable_size().
__attribute__((__noinline__))
VKAPI_ATTR void* DefaultReallocate(void*,
                                   void* ptr,
                                   size_t size,
                                   size_t alignment,
                                   VkSystemAllocationScope) {
    if (size == 0) {
        free(ptr);
        return nullptr;
    }

    // TODO(b/143295633): Right now we never shrink allocations; if the new
    // request is smaller than the existing chunk, we just continue using it.
    // Right now the loader never reallocs, so this doesn't matter. If that
    // changes, or if this code is copied into some other project, this should
    // probably have a heuristic to allocate-copy-free when doing so will save
    // "enough" space.
    size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
    if (size <= old_size)
        return ptr;

    void* new_ptr = nullptr;
    if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
        return nullptr;
    if (ptr) {
        memcpy(new_ptr, ptr, std::min(old_size, size));
        free(ptr);
    }
    return new_ptr;
}

VKAPI_ATTR void DefaultFree(void*, void* ptr) {
    ALOGD_CALLSTACK("Free: %p", ptr);
    free(ptr);
}

}  // anonymous namespace

const VkAllocationCallbacks& GetDefaultAllocator() {
    static const VkAllocationCallbacks kDefaultAllocCallbacks = {
        .pUserData = nullptr,
        .pfnAllocation = DefaultAllocate,
        .pfnReallocation = DefaultReallocate,
        .pfnFree = DefaultFree,
    };

    return kDefaultAllocCallbacks;
}

}  // namespace driver
}  // namespace vulkan
+25 −0
Original line number Diff line number Diff line
/*
 * Copyright 2025 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 <vulkan/vulkan.h>

namespace vulkan {
namespace driver {

const VkAllocationCallbacks& GetDefaultAllocator();

}  // namespace driver
}  // namespace vulkan
+0 −75
Original line number Diff line number Diff line
@@ -50,22 +50,6 @@ using namespace com::android::graphics::libvulkan;

extern "C" android_namespace_t* android_get_exported_namespace(const char*);

// #define ENABLE_ALLOC_CALLSTACKS 1
#if ENABLE_ALLOC_CALLSTACKS
#include <utils/CallStack.h>
#define ALOGD_CALLSTACK(...)                             \
    do {                                                 \
        ALOGD(__VA_ARGS__);                              \
        android::CallStack callstack;                    \
        callstack.update();                              \
        callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, "  "); \
    } while (false)
#else
#define ALOGD_CALLSTACK(...) \
    do {                     \
    } while (false)
#endif

namespace vulkan {
namespace driver {

@@ -829,54 +813,6 @@ void CreateInfoWrapper::FilterExtension(const char* name) {
    }
}

VKAPI_ATTR void* DefaultAllocate(void*,
                                 size_t size,
                                 size_t alignment,
                                 VkSystemAllocationScope) {
    void* ptr = nullptr;
    // Vulkan requires 'alignment' to be a power of two, but posix_memalign
    // additionally requires that it be at least sizeof(void*).
    int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
    ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
                    ret, ptr);
    return ret == 0 ? ptr : nullptr;
}

VKAPI_ATTR void* DefaultReallocate(void*,
                                   void* ptr,
                                   size_t size,
                                   size_t alignment,
                                   VkSystemAllocationScope) {
    if (size == 0) {
        free(ptr);
        return nullptr;
    }

    // TODO(b/143295633): Right now we never shrink allocations; if the new
    // request is smaller than the existing chunk, we just continue using it.
    // Right now the loader never reallocs, so this doesn't matter. If that
    // changes, or if this code is copied into some other project, this should
    // probably have a heuristic to allocate-copy-free when doing so will save
    // "enough" space.
    size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
    if (size <= old_size)
        return ptr;

    void* new_ptr = nullptr;
    if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
        return nullptr;
    if (ptr) {
        memcpy(new_ptr, ptr, std::min(old_size, size));
        free(ptr);
    }
    return new_ptr;
}

VKAPI_ATTR void DefaultFree(void*, void* ptr) {
    ALOGD_CALLSTACK("Free: %p", ptr);
    free(ptr);
}

InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
    void* data_mem = allocator.pfnAllocation(
        allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
@@ -916,17 +852,6 @@ bool OpenHAL() {
    return Hal::Open();
}

const VkAllocationCallbacks& GetDefaultAllocator() {
    static const VkAllocationCallbacks kDefaultAllocCallbacks = {
        .pUserData = nullptr,
        .pfnAllocation = DefaultAllocate,
        .pfnReallocation = DefaultReallocate,
        .pfnFree = DefaultFree,
    };

    return kDefaultAllocCallbacks;
}

PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
    const ProcHook* hook = GetProcHook(pName);
    if (!hook)
+1 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <vulkan/vulkan.h>
#include <hardware/hwvulkan.h>

#include "allocator.h"
#include "api_gen.h"
#include "driver_gen.h"
#include "debug_report.h"
@@ -102,7 +103,6 @@ struct DeviceData {
};

bool OpenHAL();
const VkAllocationCallbacks& GetDefaultAllocator();

void QueryPresentationProperties(
    VkPhysicalDevice physicalDevice,