VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c@ 44326

最後變更 在這個檔案從44326是 44290,由 vboxsync 提交於 12 年 前

crOpenGL: saved state fixes & improvements

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 13.6 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_error.h"
9#include "cr_mem.h"
10#include "cr_pixeldata.h"
11#include <iprt/err.h>
12
13void crStateDiffContext( CRContext *from, CRContext *to )
14{
15 CRbitvalue *bitID = from->bitid;
16 CRStateBits *sb = GetCurrentBits();
17
18 /*crDebug( "Diffing two contexts!" ); */
19
20 if (CHECKDIRTY(sb->transform.dirty, bitID))
21 {
22 crStateTransformDiff( &(sb->transform), bitID, from, to );
23 }
24 if (CHECKDIRTY(sb->pixel.dirty, bitID))
25 {
26 crStatePixelDiff( &(sb->pixel), bitID, from, to );
27 }
28 if (CHECKDIRTY(sb->viewport.dirty, bitID))
29 {
30 crStateViewportDiff( &(sb->viewport), bitID, from, to );
31 }
32 if (CHECKDIRTY(sb->fog.dirty, bitID))
33 {
34 crStateFogDiff( &(sb->fog), bitID, from, to );
35 }
36 if (CHECKDIRTY(sb->texture.dirty, bitID))
37 {
38 crStateTextureDiff( &(sb->texture), bitID, from, to );
39 }
40 if (CHECKDIRTY(sb->lists.dirty, bitID))
41 {
42 crStateListsDiff( &(sb->lists), bitID, from, to );
43 }
44 if (CHECKDIRTY(sb->buffer.dirty, bitID))
45 {
46 crStateBufferDiff( &(sb->buffer), bitID, from, to );
47 }
48#ifdef CR_ARB_vertex_buffer_object
49 if (CHECKDIRTY(sb->bufferobject.dirty, bitID))
50 {
51 crStateBufferObjectDiff( &(sb->bufferobject), bitID, from, to );
52 }
53#endif
54 if (CHECKDIRTY(sb->client.dirty, bitID))
55 {
56 crStateClientDiff(&(sb->client), bitID, from, to );
57 }
58 if (CHECKDIRTY(sb->hint.dirty, bitID))
59 {
60 crStateHintDiff( &(sb->hint), bitID, from, to );
61 }
62 if (CHECKDIRTY(sb->lighting.dirty, bitID))
63 {
64 crStateLightingDiff( &(sb->lighting), bitID, from, to );
65 }
66 if (CHECKDIRTY(sb->line.dirty, bitID))
67 {
68 crStateLineDiff( &(sb->line), bitID, from, to );
69 }
70 if (CHECKDIRTY(sb->occlusion.dirty, bitID))
71 {
72 crStateOcclusionDiff( &(sb->occlusion), bitID, from, to );
73 }
74 if (CHECKDIRTY(sb->point.dirty, bitID))
75 {
76 crStatePointDiff( &(sb->point), bitID, from, to );
77 }
78 if (CHECKDIRTY(sb->polygon.dirty, bitID))
79 {
80 crStatePolygonDiff( &(sb->polygon), bitID, from, to );
81 }
82 if (CHECKDIRTY(sb->program.dirty, bitID))
83 {
84 crStateProgramDiff( &(sb->program), bitID, from, to );
85 }
86 if (CHECKDIRTY(sb->stencil.dirty, bitID))
87 {
88 crStateStencilDiff( &(sb->stencil), bitID, from, to );
89 }
90 if (CHECKDIRTY(sb->eval.dirty, bitID))
91 {
92 crStateEvaluatorDiff( &(sb->eval), bitID, from, to );
93 }
94#ifdef CR_ARB_imaging
95 if (CHECKDIRTY(sb->imaging.dirty, bitID))
96 {
97 crStateImagingDiff( &(sb->imaging), bitID, from, to );
98 }
99#endif
100#if 0
101 if (CHECKDIRTY(sb->selection.dirty, bitID))
102 {
103 crStateSelectionDiff( &(sb->selection), bitID, from, to );
104 }
105#endif
106#ifdef CR_NV_register_combiners
107 if (CHECKDIRTY(sb->regcombiner.dirty, bitID) && to->extensions.NV_register_combiners)
108 {
109 crStateRegCombinerDiff( &(sb->regcombiner), bitID, from, to );
110 }
111#endif
112#ifdef CR_ARB_multisample
113 if (CHECKDIRTY(sb->multisample.dirty, bitID) &&
114 from->extensions.ARB_multisample)
115 {
116 crStateMultisampleDiff( &(sb->multisample), bitID, from, to );
117 }
118#endif
119 if (CHECKDIRTY(sb->current.dirty, bitID))
120 {
121 crStateCurrentDiff( &(sb->current), bitID, from, to );
122 }
123}
124
125void crStateFreeFBImage(CRContext *to)
126{
127 if (to->buffer.pFrontImg)
128 {
129 crFree(to->buffer.pFrontImg);
130 to->buffer.pFrontImg = NULL;
131 }
132 if (to->buffer.pBackImg)
133 {
134 crFree(to->buffer.pBackImg);
135 to->buffer.pBackImg = NULL;
136 }
137
138 to->buffer.storedWidth = 0;
139 to->buffer.storedHeight = 0;
140}
141
142int crStateAcquireFBImage(CRContext *to)
143{
144 CRBufferState *pBuf = &to->buffer;
145 CRPixelPackState packing = to->client.pack;
146 GLint cbData;
147 void *pFbData, *pBbData;
148
149 crStateFreeFBImage(to);
150
151 if (!to->buffer.width || !to->buffer.height)
152 return VINF_SUCCESS;
153
154 cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pBuf->width * pBuf->height;
155 pFbData = crAlloc(cbData);
156 if (!pFbData)
157 return VERR_NO_MEMORY;
158 pBbData = crAlloc(cbData);
159 if (!pBbData)
160 {
161 crFree(pFbData);
162 return VERR_NO_MEMORY;
163 }
164
165 diff_api.PixelStorei(GL_PACK_SKIP_ROWS, 0);
166 diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, 0);
167 diff_api.PixelStorei(GL_PACK_ALIGNMENT, 1);
168 diff_api.PixelStorei(GL_PACK_ROW_LENGTH, 0);
169 diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
170 diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, 0);
171 diff_api.PixelStorei(GL_PACK_SWAP_BYTES, 0);
172 diff_api.PixelStorei(GL_PACK_LSB_FIRST, 0);
173
174 if (to->framebufferobject.readFB)
175 {
176 diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
177 }
178 if (to->bufferobject.packBuffer->hwid>0)
179 {
180 diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
181 }
182
183 pBuf->storedWidth = pBuf->width;
184 pBuf->storedHeight = pBuf->height;
185 diff_api.ReadBuffer(GL_FRONT);
186 diff_api.ReadPixels(0, 0, pBuf->width, pBuf->height, GL_RGBA, GL_UNSIGNED_BYTE, pFbData);
187 to->buffer.pFrontImg = pFbData;
188
189 diff_api.ReadBuffer(GL_BACK);
190 diff_api.ReadPixels(0, 0, pBuf->width, pBuf->height, GL_RGBA, GL_UNSIGNED_BYTE, pBbData);
191 to->buffer.pBackImg = pBbData;
192
193 if (to->bufferobject.packBuffer->hwid>0)
194 {
195 diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, to->bufferobject.packBuffer->hwid);
196 }
197 if (to->framebufferobject.readFB)
198 {
199 diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, to->framebufferobject.readFB->hwid);
200 }
201 diff_api.ReadBuffer(to->framebufferobject.readFB ?
202 to->framebufferobject.readFB->readbuffer : to->buffer.readBuffer);
203
204 diff_api.PixelStorei(GL_PACK_SKIP_ROWS, packing.skipRows);
205 diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, packing.skipPixels);
206 diff_api.PixelStorei(GL_PACK_ALIGNMENT, packing.alignment);
207 diff_api.PixelStorei(GL_PACK_ROW_LENGTH, packing.rowLength);
208 diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, packing.imageHeight);
209 diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, packing.skipImages);
210 diff_api.PixelStorei(GL_PACK_SWAP_BYTES, packing.swapBytes);
211 diff_api.PixelStorei(GL_PACK_LSB_FIRST, packing.psLSBFirst);
212 return VINF_SUCCESS;
213}
214
215void crStateApplyFBImage(CRContext *to)
216{
217 if (to->buffer.pFrontImg || to->buffer.pBackImg)
218 {
219 CRBufferState *pBuf = &to->buffer;
220 CRPixelPackState unpack = to->client.unpack;
221
222 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
223 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
224 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
225 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
226 diff_api.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
227 diff_api.PixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
228 diff_api.PixelStorei(GL_UNPACK_SWAP_BYTES, 0);
229 diff_api.PixelStorei(GL_UNPACK_LSB_FIRST, 0);
230
231 if (to->framebufferobject.drawFB)
232 {
233 diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
234 }
235
236 if (to->bufferobject.unpackBuffer->hwid>0)
237 {
238 diff_api.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
239 }
240
241 diff_api.Disable(GL_ALPHA_TEST);
242 diff_api.Disable(GL_SCISSOR_TEST);
243 diff_api.Disable(GL_BLEND);
244 diff_api.Disable(GL_COLOR_LOGIC_OP);
245
246 if (pBuf->pFrontImg)
247 {
248 diff_api.DrawBuffer(GL_FRONT);
249 diff_api.WindowPos2iARB(0, 0);
250 diff_api.DrawPixels(pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBuf->pFrontImg);
251 crDebug("Applied %ix%i fb image", pBuf->storedWidth, pBuf->storedHeight);
252 crFree(pBuf->pFrontImg);
253 pBuf->pFrontImg = NULL;
254 }
255
256 if (pBuf->pBackImg)
257 {
258 diff_api.DrawBuffer(GL_BACK);
259 diff_api.WindowPos2iARB(0, 0);
260 diff_api.DrawPixels(pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBuf->pBackImg);
261 crDebug("Applied %ix%i bb image", pBuf->storedWidth, pBuf->storedHeight);
262 crFree(pBuf->pBackImg);
263 pBuf->pBackImg = NULL;
264 }
265
266 diff_api.WindowPos3fvARB(to->current.rasterAttrib[VERT_ATTRIB_POS]);
267 if (to->bufferobject.unpackBuffer->hwid>0)
268 {
269 diff_api.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, to->bufferobject.unpackBuffer->hwid);
270 }
271 if (to->framebufferobject.drawFB)
272 {
273 diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, to->framebufferobject.drawFB->hwid);
274 }
275 diff_api.DrawBuffer(to->framebufferobject.drawFB ?
276 to->framebufferobject.drawFB->drawbuffer[0] : to->buffer.drawBuffer);
277 if (to->buffer.alphaTest)
278 {
279 diff_api.Enable(GL_ALPHA_TEST);
280 }
281 if (to->viewport.scissorTest)
282 {
283 diff_api.Enable(GL_SCISSOR_TEST);
284 }
285 if (to->buffer.blend)
286 {
287 diff_api.Enable(GL_BLEND);
288 }
289 if (to->buffer.logicOp)
290 {
291 diff_api.Enable(GL_COLOR_LOGIC_OP);
292 }
293
294 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, unpack.skipRows);
295 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, unpack.skipPixels);
296 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, unpack.alignment);
297 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, unpack.rowLength);
298 diff_api.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, unpack.imageHeight);
299 diff_api.PixelStorei(GL_UNPACK_SKIP_IMAGES, unpack.skipImages);
300 diff_api.PixelStorei(GL_UNPACK_SWAP_BYTES, unpack.swapBytes);
301 diff_api.PixelStorei(GL_UNPACK_LSB_FIRST, unpack.psLSBFirst);
302
303 diff_api.Finish();
304 }
305}
306
307void crStateSwitchContext( CRContext *from, CRContext *to )
308{
309 CRbitvalue *bitID = to->bitid;
310 CRStateBits *sb = GetCurrentBits();
311
312 if (CHECKDIRTY(sb->attrib.dirty, bitID))
313 {
314 crStateAttribSwitch(&(sb->attrib), bitID, from, to );
315 }
316 if (CHECKDIRTY(sb->transform.dirty, bitID))
317 {
318 crStateTransformSwitch( &(sb->transform), bitID, from, to );
319 }
320 if (CHECKDIRTY(sb->pixel.dirty, bitID))
321 {
322 crStatePixelSwitch(&(sb->pixel), bitID, from, to );
323 }
324 if (CHECKDIRTY(sb->viewport.dirty, bitID))
325 {
326 crStateViewportSwitch(&(sb->viewport), bitID, from, to );
327 }
328 if (CHECKDIRTY(sb->fog.dirty, bitID))
329 {
330 crStateFogSwitch(&(sb->fog), bitID, from, to );
331 }
332 if (CHECKDIRTY(sb->texture.dirty, bitID))
333 {
334 crStateTextureSwitch( &(sb->texture), bitID, from, to );
335 }
336 if (CHECKDIRTY(sb->lists.dirty, bitID))
337 {
338 crStateListsSwitch(&(sb->lists), bitID, from, to );
339 }
340 if (CHECKDIRTY(sb->buffer.dirty, bitID))
341 {
342 crStateBufferSwitch( &(sb->buffer), bitID, from, to );
343 }
344#ifdef CR_ARB_vertex_buffer_object
345 if (CHECKDIRTY(sb->bufferobject.dirty, bitID))
346 {
347 crStateBufferObjectSwitch( &(sb->bufferobject), bitID, from, to );
348 }
349#endif
350 if (CHECKDIRTY(sb->client.dirty, bitID))
351 {
352 crStateClientSwitch( &(sb->client), bitID, from, to );
353 }
354#if 0
355 if (CHECKDIRTY(sb->hint.dirty, bitID))
356 {
357 crStateHintSwitch( &(sb->hint), bitID, from, to );
358 }
359#endif
360 if (CHECKDIRTY(sb->lighting.dirty, bitID))
361 {
362 crStateLightingSwitch( &(sb->lighting), bitID, from, to );
363 }
364 if (CHECKDIRTY(sb->occlusion.dirty, bitID))
365 {
366 crStateOcclusionSwitch( &(sb->occlusion), bitID, from, to );
367 }
368 if (CHECKDIRTY(sb->line.dirty, bitID))
369 {
370 crStateLineSwitch( &(sb->line), bitID, from, to );
371 }
372 if (CHECKDIRTY(sb->point.dirty, bitID))
373 {
374 crStatePointSwitch( &(sb->point), bitID, from, to );
375 }
376 if (CHECKDIRTY(sb->polygon.dirty, bitID))
377 {
378 crStatePolygonSwitch( &(sb->polygon), bitID, from, to );
379 }
380 if (CHECKDIRTY(sb->program.dirty, bitID))
381 {
382 crStateProgramSwitch( &(sb->program), bitID, from, to );
383 }
384 if (CHECKDIRTY(sb->stencil.dirty, bitID))
385 {
386 crStateStencilSwitch( &(sb->stencil), bitID, from, to );
387 }
388 if (CHECKDIRTY(sb->eval.dirty, bitID))
389 {
390 crStateEvaluatorSwitch( &(sb->eval), bitID, from, to );
391 }
392#ifdef CR_ARB_imaging
393 if (CHECKDIRTY(sb->imaging.dirty, bitID))
394 {
395 crStateImagingSwitch( &(sb->imaging), bitID, from, to );
396 }
397#endif
398#if 0
399 if (CHECKDIRTY(sb->selection.dirty, bitID))
400 {
401 crStateSelectionSwitch( &(sb->selection), bitID, from, to );
402 }
403#endif
404#ifdef CR_NV_register_combiners
405 if (CHECKDIRTY(sb->regcombiner.dirty, bitID) && to->extensions.NV_register_combiners)
406 {
407 crStateRegCombinerSwitch( &(sb->regcombiner), bitID, from, to );
408 }
409#endif
410#ifdef CR_ARB_multisample
411 if (CHECKDIRTY(sb->multisample.dirty, bitID))
412 {
413 crStateMultisampleSwitch( &(sb->multisample), bitID, from, to );
414 }
415#endif
416#ifdef CR_ARB_multisample
417 if (CHECKDIRTY(sb->multisample.dirty, bitID))
418 {
419 crStateMultisampleSwitch(&(sb->multisample), bitID, from, to );
420 }
421#endif
422#ifdef CR_EXT_framebuffer_object
423 /*Note, this should go after crStateTextureSwitch*/
424 crStateFramebufferObjectSwitch(from, to);
425#endif
426#ifdef CR_OPENGL_VERSION_2_0
427 crStateGLSLSwitch(from, to);
428#endif
429 if (CHECKDIRTY(sb->current.dirty, bitID))
430 {
431 crStateCurrentSwitch( &(sb->current), bitID, from, to );
432 }
433
434#ifdef WINDOWS
435 crStateApplyFBImage(to);
436#endif
437}
438
439void crStateSyncHWErrorState(CRContext *ctx)
440{
441 GLenum err;
442 while ((err = diff_api.GetError()) != GL_NO_ERROR)
443 {
444 if (ctx->error != GL_NO_ERROR)
445 ctx->error = err;
446 }
447}
448
449void crStateSwitchPrepare(CRContext *toCtx, CRContext *fromCtx, GLuint idDrawFBO, GLuint idReadFBO)
450{
451 if (!fromCtx)
452 return;
453
454 if (g_bVBoxEnableDiffOnMakeCurrent && toCtx && toCtx != fromCtx)
455 crStateSyncHWErrorState(fromCtx);
456
457#ifdef CR_EXT_framebuffer_object
458 crStateFramebufferObjectDisableHW(fromCtx, idDrawFBO, idReadFBO);
459#endif
460}
461
462void crStateSwitchPostprocess(CRContext *toCtx, CRContext *fromCtx, GLuint idDrawFBO, GLuint idReadFBO)
463{
464 if (!toCtx)
465 return;
466
467 if (g_bVBoxEnableDiffOnMakeCurrent && fromCtx && toCtx != fromCtx)
468 {
469 GLenum err;
470 while ((err = diff_api.GetError()) != GL_NO_ERROR)
471 {
472 crWarning("gl error (0x%x) after context switch, ignoring..", err);
473 }
474 }
475#ifdef CR_EXT_framebuffer_object
476 crStateFramebufferObjectReenableHW(fromCtx, toCtx, idDrawFBO, idReadFBO);
477#endif
478}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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