Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/hgl/GLRendererRoster.cpp
4558 views
1
/*
2
* Copyright 2006-2012 Haiku, Inc. All Rights Reserved.
3
* Distributed under the terms of the MIT License.
4
*
5
* Authors:
6
* Philippe Houdoin <[email protected]>
7
* Alexander von Gluck IV <[email protected]>
8
*/
9
10
11
#include <driver_settings.h>
12
#include <image.h>
13
14
#include <kernel/image.h>
15
#include <private/system/safemode_defs.h>
16
17
#include <Directory.h>
18
#include <FindDirectory.h>
19
#include <Path.h>
20
#include <strings.h>
21
#include "GLRendererRoster.h"
22
23
#include <new>
24
#include <string.h>
25
#include <stdio.h>
26
27
28
extern "C" status_t _kern_get_safemode_option(const char* parameter,
29
char* buffer, size_t* _bufferSize);
30
31
GLRendererRoster *GLRendererRoster::fInstance = NULL;
32
33
GLRendererRoster *GLRendererRoster::Roster()
34
{
35
if (fInstance == NULL) {
36
fInstance = new GLRendererRoster();
37
}
38
return fInstance;
39
}
40
41
GLRendererRoster::GLRendererRoster()
42
:
43
fSafeMode(false),
44
fABISubDirectory(NULL)
45
{
46
char parameter[32];
47
size_t parameterLength = sizeof(parameter);
48
49
if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE,
50
parameter, &parameterLength) == B_OK) {
51
if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on")
52
|| !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes")
53
|| !strcasecmp(parameter, "enable") || !strcmp(parameter, "1"))
54
fSafeMode = true;
55
}
56
57
if (_kern_get_safemode_option(B_SAFEMODE_DISABLE_USER_ADD_ONS,
58
parameter, &parameterLength) == B_OK) {
59
if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on")
60
|| !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes")
61
|| !strcasecmp(parameter, "enable") || !strcmp(parameter, "1"))
62
fSafeMode = true;
63
}
64
65
// We might run in compatibility mode on a system with a different ABI. The
66
// renderers matching our ABI can usually be found in respective
67
// subdirectories of the opengl add-ons directories.
68
system_info info;
69
if (get_system_info(&info) == B_OK
70
&& (info.abi & B_HAIKU_ABI_MAJOR)
71
!= (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR)) {
72
switch (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR) {
73
case B_HAIKU_ABI_GCC_2:
74
fABISubDirectory = "gcc2";
75
break;
76
case B_HAIKU_ABI_GCC_4:
77
fABISubDirectory = "gcc4";
78
break;
79
}
80
}
81
82
AddDefaultPaths();
83
}
84
85
86
GLRendererRoster::~GLRendererRoster()
87
{
88
89
}
90
91
92
BGLRenderer*
93
GLRendererRoster::GetRenderer(BGLView *view, ulong options)
94
{
95
for (
96
RendererMap::const_iterator iterator = fRenderers.begin();
97
iterator != fRenderers.end();
98
iterator++
99
) {
100
renderer_item item = *iterator;
101
BGLRenderer* renderer;
102
renderer = item.entry(view, options);
103
return renderer;
104
}
105
return NULL;
106
}
107
108
109
void
110
GLRendererRoster::AddDefaultPaths()
111
{
112
// add user directories first, so that they can override system renderers
113
const directory_which paths[] = {
114
B_USER_NONPACKAGED_ADDONS_DIRECTORY,
115
B_USER_ADDONS_DIRECTORY,
116
B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
117
B_SYSTEM_ADDONS_DIRECTORY,
118
};
119
120
for (uint32 i = fSafeMode ? 4 : 0;
121
i < sizeof(paths) / sizeof(paths[0]); i++) {
122
BPath path;
123
status_t status = find_directory(paths[i], &path, true);
124
if (status == B_OK && path.Append("opengl") == B_OK)
125
AddPath(path.Path());
126
}
127
}
128
129
130
status_t
131
GLRendererRoster::AddPath(const char* path)
132
{
133
BDirectory directory(path);
134
status_t status = directory.InitCheck();
135
if (status < B_OK)
136
return status;
137
138
// if a subdirectory for our ABI exists, use that instead
139
if (fABISubDirectory != NULL) {
140
BEntry entry(&directory, fABISubDirectory);
141
if (entry.IsDirectory()) {
142
status = directory.SetTo(&entry);
143
if (status != B_OK)
144
return status;
145
}
146
}
147
148
node_ref nodeRef;
149
status = directory.GetNodeRef(&nodeRef);
150
if (status < B_OK)
151
return status;
152
153
int32 count = 0;
154
int32 files = 0;
155
156
entry_ref ref;
157
BEntry entry;
158
while (directory.GetNextRef(&ref) == B_OK) {
159
entry.SetTo(&ref, true);
160
if (entry.InitCheck() == B_OK && !entry.IsFile())
161
continue;
162
163
if (CreateRenderer(ref) == B_OK)
164
count++;
165
166
files++;
167
}
168
169
if (files != 0 && count == 0)
170
return B_BAD_VALUE;
171
172
return B_OK;
173
}
174
175
176
status_t
177
GLRendererRoster::AddRenderer(InstantiateRenderer entry,
178
image_id image, const entry_ref* ref, ino_t node)
179
{
180
renderer_item item;
181
item.entry = entry;
182
item.image = image;
183
item.node = node;
184
if (ref != NULL)
185
item.ref = *ref;
186
187
try {
188
fRenderers.push_back(item);
189
} catch (...) {
190
return B_NO_MEMORY;
191
}
192
193
return B_OK;
194
}
195
196
197
status_t
198
GLRendererRoster::CreateRenderer(const entry_ref& ref)
199
{
200
BEntry entry(&ref, true);
201
node_ref nodeRef;
202
status_t status = entry.GetNodeRef(&nodeRef);
203
if (status < B_OK)
204
return status;
205
206
BPath path(&ref);
207
printf("OpenGL load add-on: %s\n", path.Path());
208
209
image_id image = load_add_on(path.Path());
210
if (image < B_OK)
211
return image;
212
213
InstantiateRenderer instantiate_renderer;
214
215
status = get_image_symbol(
216
image, "instantiate_gl_renderer",
217
B_SYMBOL_TYPE_TEXT, (void**)&instantiate_renderer
218
);
219
220
if (status == B_OK) {
221
if ((status = AddRenderer(instantiate_renderer, image, &ref, nodeRef.node)) != B_OK) {
222
unload_add_on(image);
223
return status;
224
}
225
printf("OpenGL add-on registered: %s\n", path.Path());
226
return B_OK;
227
}
228
229
printf("OpenGL add-on failed to instantiate: %s\n", path.Path());
230
unload_add_on(image);
231
232
return status;
233
}
234
235