VirtualBox

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

Last change on this file since 31781 was 30440, checked in by vboxsync, 15 years ago

crOpenGL: wddm friendly windows info tracking + more consistent updates (disabled except windows yet)

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

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