VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/spu_loader/spuload.c@ 18051

最後變更 在這個檔案從18051是 15532,由 vboxsync 提交於 16 年 前

crOpenGL: export to OSE

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 7.5 KB
 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_mem.h"
8#include "cr_environment.h"
9#include "cr_string.h"
10#include "cr_dll.h"
11#include "cr_error.h"
12#include "cr_spu.h"
13
14
15#include <iprt/param.h>
16#include <iprt/string.h>
17#include <iprt/path.h>
18
19#include <stdio.h>
20
21#ifdef WINDOWS
22#define DLL_SUFFIX ".dll"
23#define DLL_PREFIX "VBoxOGL"
24#elif defined(DARWIN)
25#define DLL_SUFFIX ".dylib"
26#define DLL_PREFIX "VBoxOGL"
27/*
28#define DLL_SUFFIX ".bundle"
29#define DLL_PREFIX ""
30*/
31#else
32#ifdef AIX
33#define DLL_SUFFIX ".o"
34#define DLL_PREFIX "VBoxOGL"
35#else
36#define DLL_SUFFIX ".so"
37#define DLL_PREFIX "VBoxOGL"
38#endif
39#endif
40
41extern void __buildDispatch( SPU *spu );
42
43static char *__findDLL( char *name, char *dir )
44{
45 static char path[8092];
46
47 if (!dir)
48 {
49#if defined(DARWIN)
50 char szSharedLibPath[8092];
51 int rc = RTPathAppPrivateArch (szSharedLibPath, sizeof(szSharedLibPath));
52 if (RT_SUCCESS(rc))
53 sprintf ( path, "%s/%s%sspu%s", szSharedLibPath, DLL_PREFIX, name, DLL_SUFFIX );
54 else
55#endif /* DARWIN */
56 sprintf ( path, "%s%sspu%s", DLL_PREFIX, name, DLL_SUFFIX );
57 }
58 else
59 {
60 sprintf ( path, "%s/%s%sspu%s", dir, DLL_PREFIX, name, DLL_SUFFIX );
61 }
62 return path;
63}
64
65/**
66 * Load a single SPU from disk and initialize it. Is there any reason
67 * to export this from the SPU loader library? */
68
69SPU * crSPULoad( SPU *child, int id, char *name, char *dir, void *server )
70{
71 SPU *the_spu;
72 char *path;
73
74 CRASSERT( name != NULL );
75
76 the_spu = (SPU*)crAlloc( sizeof( *the_spu ) );
77 the_spu->id = id;
78 the_spu->privatePtr = NULL;
79 path = __findDLL( name, dir );
80 the_spu->dll = crDLLOpen( path, 0/*resolveGlobal*/ );
81 the_spu->entry_point =
82 (SPULoadFunction) crDLLGetNoError( the_spu->dll, SPU_ENTRY_POINT_NAME );
83 if (!the_spu->entry_point)
84 {
85 crError( "Couldn't load the SPU entry point \"%s\" from SPU \"%s\"!",
86 SPU_ENTRY_POINT_NAME, name );
87 }
88
89 /* This basicall calls the SPU's SPULoad() function */
90 if (!the_spu->entry_point( &(the_spu->name), &(the_spu->super_name),
91 &(the_spu->init), &(the_spu->self),
92 &(the_spu->cleanup),
93 &(the_spu->options),
94 &(the_spu->spu_flags)) )
95 {
96 crError( "I found the SPU \"%s\", but loading it failed!", name );
97 }
98#ifdef IN_GUEST
99 if (crStrcmp(the_spu->name,"error"))
100 {
101 /* the default super/base class for an SPU is the error SPU */
102 if (the_spu->super_name == NULL)
103 {
104 the_spu->super_name = "error";
105 }
106 the_spu->superSPU = crSPULoad( child, id, the_spu->super_name, dir, server );
107 }
108#else
109 if (crStrcmp(the_spu->name,"hosterror"))
110 {
111 /* the default super/base class for an SPU is the error SPU */
112 if (the_spu->super_name == NULL)
113 {
114 the_spu->super_name = "hosterror";
115 }
116 the_spu->superSPU = crSPULoad( child, id, the_spu->super_name, dir, server );
117 }
118#endif
119 else
120 {
121 the_spu->superSPU = NULL;
122 }
123 crDebug("Initializing %s SPU", name);
124 the_spu->function_table = the_spu->init( id, child, the_spu, 0, 1 );
125 if (!the_spu->function_table) {
126 crDebug("Failed to init %s SPU", name);
127 return NULL;
128 }
129 __buildDispatch( the_spu );
130 /*crDebug( "initializing dispatch table %p (for SPU %s)", (void*)&(the_spu->dispatch_table), name );*/
131 crSPUInitDispatchTable( &(the_spu->dispatch_table) );
132 /*crDebug( "Done initializing the dispatch table for SPU %s, calling the self function", name );*/
133
134 the_spu->dispatch_table.server = server;
135 the_spu->self( &(the_spu->dispatch_table) );
136 /*crDebug( "Done with the self function" );*/
137
138 return the_spu;
139}
140
141/**
142 * Load the entire chain of SPUs and initialize all of them.
143 * This function returns the first one in the chain.
144 */
145SPU *
146crSPULoadChain( int count, int *ids, char **names, char *dir, void *server )
147{
148 int i;
149 SPU *child_spu = NULL;
150 CRASSERT( count > 0 );
151
152 for (i = count-1 ; i >= 0 ; i--)
153 {
154 int spu_id = ids[i];
155 char *spu_name = names[i];
156 SPU *the_spu, *temp;
157
158 /* This call passes the previous version of spu, which is the SPU's
159 * "child" in this chain. */
160
161 the_spu = crSPULoad( child_spu, spu_id, spu_name, dir, server );
162 if (!the_spu) {
163 return NULL;
164 }
165
166 if (child_spu != NULL)
167 {
168 /* keep track of this so that people can pass functions through but
169 * still get updated when API's change on the fly. */
170 for (temp = the_spu ; temp ; temp = temp->superSPU )
171 {
172 struct _copy_list_node *node = (struct _copy_list_node *) crAlloc( sizeof( *node ) );
173 node->copy = &(temp->dispatch_table);
174 node->next = child_spu->dispatch_table.copyList;
175 child_spu->dispatch_table.copyList = node;
176 }
177 }
178 child_spu = the_spu;
179 }
180 return child_spu;
181}
182
183
184#if 00
185/* XXXX experimental code - not used at this time */
186/**
187 * Like crSPUChangeInterface(), but don't loop over all functions in
188 * the table to search for 'old_func'.
189 */
190void
191crSPUChangeFunction(SPUDispatchTable *table, unsigned int funcOffset,
192 void *newFunc)
193{
194 SPUGenericFunction *f = (SPUGenericFunction *) table + funcOffset;
195 struct _copy_list_node *temp;
196
197 CRASSERT(funcOffset < sizeof(*table) / sizeof(SPUGenericFunction));
198
199 printf("%s\n", __FUNCTION__);
200 if (table->mark == 1)
201 return;
202 table->mark = 1;
203 *f = newFunc;
204
205 /* update all copies of this table */
206#if 1
207 for (temp = table->copyList ; temp ; temp = temp->next)
208 {
209 crSPUChangeFunction( temp->copy, funcOffset, newFunc );
210 }
211#endif
212 if (table->copy_of != NULL)
213 {
214 crSPUChangeFunction( table->copy_of, funcOffset, newFunc );
215 }
216#if 0
217 for (temp = table->copyList ; temp ; temp = temp->next)
218 {
219 crSPUChangeFunction( temp->copy, funcOffset, newFunc );
220 }
221#endif
222 table->mark = 0;
223}
224#endif
225
226
227
228/**
229 * Call the cleanup() function for each SPU in a chain, close the SPU
230 * DLLs and free the SPU objects.
231 * \param headSPU pointer to the first SPU in the chain
232 */
233void
234crSPUUnloadChain(SPU *headSPU)
235{
236 SPU *the_spu = headSPU, *next_spu;
237
238 while (the_spu)
239 {
240 crDebug("Cleaning up SPU %s", the_spu->name);
241
242 if (the_spu->cleanup)
243 the_spu->cleanup();
244
245 next_spu = the_spu->superSPU;
246 crDLLClose(the_spu->dll);
247 crFree(the_spu);
248 the_spu = next_spu;
249 }
250}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette