blob: 5df2c357eee2ad66164927567e0b0eb2d9c90a55 [file] [log] [blame]
Chia-I Wu900364b2015-01-03 13:55:22 +08001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28#define _ISOC11_SOURCE /* for aligned_alloc() */
29#include <stdlib.h>
30#include <string.h>
31
32#include "icd-utils.h"
33#include "icd-alloc.h"
34
35struct icd_allocator {
36 bool initialized;
37 XGL_ALLOC_CALLBACKS callbacks;
38};
39
40static void *default_alloc(void *user_data, size_t size, size_t alignment,
41 XGL_SYSTEM_ALLOC_TYPE allocType)
42{
43 if (alignment <= 1) {
44 return malloc(size);
45 } else if (u_is_pow2(alignment)) {
46 if (alignment < sizeof(void *)) {
47 assert(u_is_pow2(sizeof(void*)));
48 alignment = sizeof(void *);
49 }
50
51 size = (size + alignment - 1) & ~(alignment - 1);
52
53 return aligned_alloc(alignment, size);
54 }
55 else {
56 return NULL;
57 }
58}
59
60static void default_free(void *user_data, void *ptr)
61{
62 free(ptr);
63}
64
65static struct icd_allocator icd_allocator = {
66 .callbacks = {
67 .pfnAlloc = default_alloc,
68 .pfnFree = default_free,
69 }
70};
71
72XGL_RESULT icd_allocator_init(const XGL_ALLOC_CALLBACKS *alloc_cb)
73{
74 if (icd_allocator.initialized) {
75 const XGL_ALLOC_CALLBACKS default_cb = {
76 NULL, default_alloc, default_free
77 };
78
79 if (!alloc_cb)
80 alloc_cb = &default_cb;
81
82 /*
83 * The spec says: Changing the callbacks on subsequent calls to
84 * xglInitAndEnumerateGpus() causes it to fail with
85 * XGL_ERROR_INVALID_POINTER error.
86 */
87 return (memcmp(&icd_allocator.callbacks, alloc_cb, sizeof(*alloc_cb)))
88 ? XGL_ERROR_INVALID_POINTER : XGL_SUCCESS;
89 }
90
91 if (alloc_cb)
92 icd_allocator.callbacks = *alloc_cb;
93 icd_allocator.initialized = true;
94
95 return XGL_SUCCESS;
96}
97
98uint32_t icd_allocator_get_id(void)
99{
100 return icd_allocator.initialized;
101}
102
103void *icd_alloc(size_t size, size_t alignment, XGL_SYSTEM_ALLOC_TYPE type)
104{
105 return icd_allocator.callbacks.pfnAlloc(icd_allocator.callbacks.pUserData,
106 size, alignment, type);
107}
108
109void icd_free(void *ptr)
110{
111 icd_allocator.callbacks.pfnFree(icd_allocator.callbacks.pUserData, ptr);
112}