VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c@ 22155

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

crOpenGL: add GL_EXT_framebuffer_object support

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 12.2 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 "state.h"
8#include "cr_mem.h"
9#include "cr_error.h"
10#include "cr_spu.h"
11
12#ifdef CHROMIUM_THREADSAFE
13CRtsd __contextTSD;
14#else
15CRContext *__currentContext = NULL;
16#endif
17
18CRStateBits *__currentBits = NULL;
19GLboolean g_availableContexts[CR_MAX_CONTEXTS];
20
21static CRContext *defaultContext = NULL;
22
23
24
25/**
26 * Allocate a new shared state object.
27 * Contains texture objects, display lists, etc.
28 */
29static CRSharedState *
30crStateAllocShared(void)
31{
32 CRSharedState *s = (CRSharedState *) crCalloc(sizeof(CRSharedState));
33 if (s) {
34 s->textureTable = crAllocHashtable();
35 s->dlistTable = crAllocHashtable();
36 s->refCount = 1; /* refcount is number of contexts using this state */
37 }
38 return s;
39}
40
41
42
43/**
44 * Callback used for crFreeHashtable().
45 */
46static void
47DeleteTextureCallback(void *texObj)
48{
49 crStateDeleteTextureObject((CRTextureObj *) texObj);
50}
51
52
53/**
54 * Decrement shared state's refcount and delete when it hits zero.
55 */
56static void
57crStateFreeShared(CRSharedState *s)
58{
59 s->refCount--;
60 if (s->refCount <= 0) {
61 crFreeHashtable(s->textureTable, DeleteTextureCallback);
62 crFreeHashtable(s->dlistTable, crFree); /* call crFree for each entry */
63 crFree(s);
64 }
65}
66
67
68/*
69 * Helper for crStateCreateContext, below.
70 */
71static CRContext *
72crStateCreateContextId(int i, const CRLimitsState *limits,
73 GLint visBits, CRContext *shareCtx)
74{
75 CRContext *ctx = (CRContext *) crCalloc( sizeof( *ctx ) );
76 int j;
77 int node32 = i >> 5;
78 int node = i & 0x1f;
79
80 ctx->id = i;
81 ctx->flush_func = NULL;
82 for (j=0;j<CR_MAX_BITARRAY;j++){
83 if (j == node32) {
84 ctx->bitid[j] = (1 << node);
85 } else {
86 ctx->bitid[j] = 0;
87 }
88 ctx->neg_bitid[j] = ~(ctx->bitid[j]);
89 }
90
91 if (shareCtx) {
92 CRASSERT(shareCtx->shared);
93 ctx->shared = shareCtx->shared;
94 ctx->shared->refCount ++;
95 }
96 else {
97 ctx->shared = crStateAllocShared();
98 }
99
100 /* use Chromium's OpenGL defaults */
101 crStateLimitsInit( &(ctx->limits) );
102 crStateExtensionsInit( &(ctx->limits), &(ctx->extensions) );
103
104 crStateBufferObjectInit( ctx ); /* must precede client state init! */
105 crStateClientInit( &(ctx->client) );
106
107 crStateBufferInit( ctx );
108 crStateCurrentInit( ctx );
109 crStateEvaluatorInit( ctx );
110 crStateFogInit( ctx );
111 crStateHintInit( ctx );
112 crStateLightingInit( ctx );
113 crStateLineInit( ctx );
114 crStateListsInit( ctx );
115 crStateMultisampleInit( ctx );
116 crStateOcclusionInit( ctx );
117 crStatePixelInit( ctx );
118 crStatePolygonInit( ctx );
119 crStatePointInit( ctx );
120 crStateProgramInit( ctx );
121 crStateRegCombinerInit( ctx );
122 crStateStencilInit( ctx );
123 crStateTextureInit( ctx );
124 crStateTransformInit( ctx );
125 crStateViewportInit ( ctx );
126 crStateFramebufferObjectInit(ctx);
127
128 /* This has to come last. */
129 crStateAttribInit( &(ctx->attrib) );
130
131 ctx->renderMode = GL_RENDER;
132
133 /* Initialize values that depend on the visual mode */
134 if (visBits & CR_DOUBLE_BIT) {
135 ctx->limits.doubleBuffer = GL_TRUE;
136 }
137 if (visBits & CR_RGB_BIT) {
138 ctx->limits.redBits = 8;
139 ctx->limits.greenBits = 8;
140 ctx->limits.blueBits = 8;
141 if (visBits & CR_ALPHA_BIT) {
142 ctx->limits.alphaBits = 8;
143 }
144 }
145 else {
146 ctx->limits.indexBits = 8;
147 }
148 if (visBits & CR_DEPTH_BIT) {
149 ctx->limits.depthBits = 24;
150 }
151 if (visBits & CR_STENCIL_BIT) {
152 ctx->limits.stencilBits = 8;
153 }
154 if (visBits & CR_ACCUM_BIT) {
155 ctx->limits.accumRedBits = 16;
156 ctx->limits.accumGreenBits = 16;
157 ctx->limits.accumBlueBits = 16;
158 if (visBits & CR_ALPHA_BIT) {
159 ctx->limits.accumAlphaBits = 16;
160 }
161 }
162 if (visBits & CR_STEREO_BIT) {
163 ctx->limits.stereo = GL_TRUE;
164 }
165 if (visBits & CR_MULTISAMPLE_BIT) {
166 ctx->limits.sampleBuffers = 1;
167 ctx->limits.samples = 4;
168 ctx->multisample.enabled = GL_TRUE;
169 }
170
171 if (visBits & CR_OVERLAY_BIT) {
172 ctx->limits.level = 1;
173 }
174
175 return ctx;
176}
177
178/*@todo crStateAttribDestroy*/
179static void
180crStateFreeContext(CRContext *ctx)
181{
182 crStateClientDestroy( &(ctx->client) );
183 crStateLimitsDestroy( &(ctx->limits) );
184 crStateBufferObjectDestroy( ctx );
185 crStateEvaluatorDestroy( ctx );
186 crStateListsDestroy( ctx );
187 crStateLightingDestroy( ctx );
188 crStateOcclusionDestroy( ctx );
189 crStateProgramDestroy( ctx );
190 crStateTextureDestroy( ctx );
191 crStateTransformDestroy( ctx );
192 crStateFreeShared(ctx->shared);
193 crStateFramebufferObjectDestroy(ctx);
194 crFree( ctx );
195}
196
197
198/*
199 * Allocate the state (dirty) bits data structures.
200 * This should be called before we create any contexts.
201 * We'll also create the default/NULL context at this time and make
202 * it the current context by default. This means that if someone
203 * tries to set GL state before calling MakeCurrent() they'll be
204 * modifying the default state object, and not segfaulting on a NULL
205 * pointer somewhere.
206 */
207void crStateInit(void)
208{
209 unsigned int i;
210
211 /* Purely initialize the context bits */
212 if (!__currentBits) {
213 __currentBits = (CRStateBits *) crCalloc( sizeof(CRStateBits) );
214 crStateClientInitBits( &(__currentBits->client) );
215 crStateLightingInitBits( &(__currentBits->lighting) );
216 } else
217 crWarning("State tracker is being re-initialized..\n");
218
219 for (i=0;i<CR_MAX_CONTEXTS;i++)
220 g_availableContexts[i] = 0;
221
222 if (defaultContext) {
223 /* Free the default/NULL context.
224 * Ensures context bits are reset */
225 crStateFreeContext(defaultContext);
226 }
227
228 /* Reset diff_api */
229 crMemZero(&diff_api, sizeof(SPUDispatchTable));
230
231 /* Allocate the default/NULL context */
232 defaultContext = crStateCreateContextId(0, NULL, CR_RGB_BIT, NULL);
233 CRASSERT(g_availableContexts[0] == 0);
234 g_availableContexts[0] = 1; /* in use forever */
235
236#ifdef CHROMIUM_THREADSAFE
237 crSetTSD(&__contextTSD, defaultContext);
238#else
239 __currentContext = defaultContext;
240#endif
241}
242
243
244
245/*
246 * Notes on context switching and the "default context".
247 *
248 * See the paper "Tracking Graphics State for Networked Rendering"
249 * by Ian Buck, Greg Humphries and Pat Hanrahan for background
250 * information about how the state tracker and context switching
251 * works.
252 *
253 * When we make a new context current, we call crStateSwitchContext()
254 * in order to transform the 'from' context into the 'to' context
255 * (i.e. the old context to the new context). The transformation
256 * is accomplished by calling GL functions through the 'diff_api'
257 * so that the downstream GL machine (represented by the __currentContext
258 * structure) is updated to reflect the new context state. Finally,
259 * we point __currentContext to the new context.
260 *
261 * A subtle problem we have to deal with is context destruction.
262 * This issue arose while testing with Glean. We found that when
263 * the currently bound context was getting destroyed that state
264 * tracking was incorrect when a subsequent new context was activated.
265 * In DestroyContext, the __hwcontext was being set to NULL and effectively
266 * going away. Later in MakeCurrent we had no idea what the state of the
267 * downstream GL machine was (since __hwcontext was gone). This meant
268 * we had nothing to 'diff' against and the downstream GL machine was
269 * in an unknown state.
270 *
271 * The solution to this problem is the "default/NULL" context. The
272 * default context is created the first time CreateContext is called
273 * and is never freed. Whenever we get a crStateMakeCurrent(NULL) call
274 * or destroy the currently bound context in crStateDestroyContext()
275 * we call crStateSwitchContext() to switch to the default context and
276 * then set the __currentContext pointer to point to the default context.
277 * This ensures that the dirty bits are updated and the diff_api functions
278 * are called to keep the downstream GL machine in a known state.
279 * Finally, the __hwcontext variable is no longer needed now.
280 *
281 * Yeah, this is kind of a mind-bender, but it really solves the problem
282 * pretty cleanly.
283 *
284 * -Brian
285 */
286
287
288CRContext *
289crStateCreateContext(const CRLimitsState *limits, GLint visBits, CRContext *share)
290{
291 int i;
292
293 /* Must have created the default context via crStateInit() first */
294 CRASSERT(defaultContext);
295
296 for (i = 1 ; i < CR_MAX_CONTEXTS ; i++)
297 {
298 if (!g_availableContexts[i])
299 {
300 g_availableContexts[i] = 1; /* it's no longer available */
301 return crStateCreateContextId( i, limits, visBits, share );
302 }
303 }
304 crError( "Out of available contexts in crStateCreateContexts (max %d)",
305 CR_MAX_CONTEXTS );
306 /* never get here */
307 return NULL;
308}
309
310CRContext *
311crStateCreateContextEx(const CRLimitsState *limits, GLint visBits, CRContext *share, GLint presetID)
312{
313 if (presetID>0)
314 {
315 CRASSERT(!g_availableContexts[presetID]);
316 g_availableContexts[presetID] = 1;
317 return crStateCreateContextId(presetID, limits, visBits, share);
318 }
319 else return crStateCreateContext(limits, visBits, share);
320}
321
322void crStateDestroyContext( CRContext *ctx )
323{
324 CRContext *current = GetCurrentContext();
325
326 if (current == ctx) {
327 /* destroying the current context - have to be careful here */
328 CRASSERT(defaultContext);
329 /* Check to see if the differencer exists first,
330 we may not have one, aka the packspu */
331 if (diff_api.AlphaFunc)
332 crStateSwitchContext(current, defaultContext);
333#ifdef CHROMIUM_THREADSAFE
334 crSetTSD(&__contextTSD, defaultContext);
335#else
336 __currentContext = defaultContext;
337#endif
338 /* ensure matrix state is also current */
339 crStateMatrixMode(defaultContext->transform.matrixMode);
340 }
341 g_availableContexts[ctx->id] = 0;
342
343 crStateFreeContext(ctx);
344}
345
346
347void crStateMakeCurrent( CRContext *ctx )
348{
349 CRContext *current = GetCurrentContext();
350
351 if (ctx == NULL)
352 ctx = defaultContext;
353
354 if (current == ctx)
355 return; /* no-op */
356
357 CRASSERT(ctx);
358
359 if (current) {
360 /* Check to see if the differencer exists first,
361 we may not have one, aka the packspu */
362 if (diff_api.AlphaFunc)
363 crStateSwitchContext( current, ctx );
364 }
365
366#ifdef CHROMIUM_THREADSAFE
367 crSetTSD(&__contextTSD, ctx);
368#else
369 __currentContext = ctx;
370#endif
371
372 /* ensure matrix state is also current */
373 crStateMatrixMode(ctx->transform.matrixMode);
374}
375
376
377/*
378 * As above, but don't call crStateSwitchContext().
379 */
380void crStateSetCurrent( CRContext *ctx )
381{
382 CRContext *current = GetCurrentContext();
383
384 if (ctx == NULL)
385 ctx = defaultContext;
386
387 if (current == ctx)
388 return; /* no-op */
389
390 CRASSERT(ctx);
391
392#ifdef CHROMIUM_THREADSAFE
393 crSetTSD(&__contextTSD, ctx);
394#else
395 __currentContext = ctx;
396#endif
397
398 /* ensure matrix state is also current */
399 crStateMatrixMode(ctx->transform.matrixMode);
400}
401
402
403CRContext *crStateGetCurrent(void)
404{
405 return GetCurrentContext();
406}
407
408
409void crStateUpdateColorBits(void)
410{
411 /* This is a hack to force updating the 'current' attribs */
412 CRStateBits *sb = GetCurrentBits();
413 FILLDIRTY(sb->current.dirty);
414 FILLDIRTY(sb->current.vertexAttrib[VERT_ATTRIB_COLOR0]);
415}
416
417
418void STATE_APIENTRY
419crStateChromiumParameteriCR( GLenum target, GLint value )
420{
421 /* This no-op function helps smooth code-gen */
422}
423
424void STATE_APIENTRY
425crStateChromiumParameterfCR( GLenum target, GLfloat value )
426{
427 /* This no-op function helps smooth code-gen */
428}
429
430void STATE_APIENTRY
431crStateChromiumParametervCR( GLenum target, GLenum type, GLsizei count, const GLvoid *values )
432{
433 /* This no-op function helps smooth code-gen */
434}
435
436void STATE_APIENTRY
437crStateGetChromiumParametervCR( GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid *values )
438{
439 /* This no-op function helps smooth code-gen */
440}
441
442void STATE_APIENTRY
443crStateReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
444 GLenum format, GLenum type, GLvoid *pixels )
445{
446 /* This no-op function helps smooth code-gen */
447}
448
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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