VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/vboxdri_drv.c@ 53361

最後變更 在這個檔案從53361是 33540,由 vboxsync 提交於 14 年 前

*: spelling fixes, thanks Timeless!

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 22.5 KB
 
1/*
2 * Mesa 3-D graphics library
3 * Version: 6.3
4 *
5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25/* Minimal swrast-based dri loadable driver.
26 *
27 * Todo:
28 * -- Use malloced (rather than framebuffer) memory for backbuffer
29 * -- 32bpp is hardwired -- fix
30 *
31 * NOTES:
32 * -- No mechanism for cliprects or resize notification --
33 * assumes this is a fullscreen device.
34 * -- No locking -- assumes this is the only driver accessing this
35 * device.
36 * -- Doesn't (yet) make use of any acceleration or other interfaces
37 * provided by fb. Would be entirely happy working against any
38 * fullscreen interface.
39 * -- HOWEVER: only a small number of pixelformats are supported, and
40 * the mechanism for choosing between them makes some assumptions
41 * that may not be valid everywhere.
42 */
43
44#include "driver.h"
45#include "drm.h"
46#include "utils.h"
47#include "drirenderbuffer.h"
48
49#include "buffers.h"
50#include "extensions.h"
51#include "framebuffer.h"
52#include "renderbuffer.h"
53#include "vbo/vbo.h"
54#include "swrast/swrast.h"
55#include "swrast_setup/swrast_setup.h"
56#include "tnl/tnl.h"
57#include "tnl/t_context.h"
58#include "tnl/t_pipeline.h"
59#include "drivers/common/driverfuncs.h"
60
61#define need_GL_VERSION_1_3
62#define need_GL_VERSION_1_4
63#define need_GL_VERSION_1_5
64#define need_GL_VERSION_2_0
65#define need_GL_VERSION_2_1
66
67/* sw extensions for imaging */
68#define need_GL_EXT_blend_color
69#define need_GL_EXT_blend_minmax
70#define need_GL_EXT_convolution
71#define need_GL_EXT_histogram
72#define need_GL_SGI_color_table
73
74/* sw extensions not associated with some GL version */
75#define need_GL_ARB_shader_objects
76#define need_GL_ARB_vertex_program
77#define need_GL_APPLE_vertex_array_object
78#define need_GL_ATI_fragment_shader
79#define need_GL_EXT_depth_bounds_test
80#define need_GL_EXT_framebuffer_object
81#define need_GL_EXT_framebuffer_blit
82#define need_GL_EXT_gpu_program_parameters
83#define need_GL_EXT_paletted_texture
84#define need_GL_IBM_multimode_draw_arrays
85#define need_GL_MESA_resize_buffers
86#define need_GL_NV_vertex_program
87#define need_GL_NV_fragment_program
88
89#include "extension_helper.h"
90
91const struct dri_extension card_extensions[] =
92{
93 { "GL_VERSION_1_3", GL_VERSION_1_3_functions },
94 { "GL_VERSION_1_4", GL_VERSION_1_4_functions },
95 { "GL_VERSION_1_5", GL_VERSION_1_5_functions },
96 { "GL_VERSION_2_0", GL_VERSION_2_0_functions },
97 { "GL_VERSION_2_1", GL_VERSION_2_1_functions },
98
99 { "GL_EXT_blend_color", GL_EXT_blend_color_functions },
100 { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
101 { "GL_EXT_convolution", GL_EXT_convolution_functions },
102 { "GL_EXT_histogram", GL_EXT_histogram_functions },
103 { "GL_SGI_color_table", GL_SGI_color_table_functions },
104
105 { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
106 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
107 { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions },
108 { "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions },
109 { "GL_EXT_depth_bounds_test", GL_EXT_depth_bounds_test_functions },
110 { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
111 { "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions },
112 { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
113 { "GL_EXT_paletted_texture", GL_EXT_paletted_texture_functions },
114 { "GL_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_functions },
115 { "GL_MESA_resize_buffers", GL_MESA_resize_buffers_functions },
116 { "GL_NV_vertex_program", GL_NV_vertex_program_functions },
117 { "GL_NV_fragment_program", GL_NV_fragment_program_functions },
118 { NULL, NULL }
119};
120
121void fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis);
122
123typedef struct {
124 GLcontext *glCtx; /* Mesa context */
125
126 struct {
127 __DRIcontextPrivate *context;
128 __DRIscreenPrivate *screen;
129 __DRIdrawablePrivate *drawable; /* drawable bound to this ctx */
130 } dri;
131
132} fbContext, *fbContextPtr;
133
134#define FB_CONTEXT(ctx) ((fbContextPtr)(ctx->DriverCtx))
135
136
137static const GLubyte *
138get_string(GLcontext *ctx, GLenum pname)
139{
140 (void) ctx;
141 switch (pname) {
142 case GL_RENDERER:
143 return (const GLubyte *) "Mesa dumb framebuffer";
144 default:
145 return NULL;
146 }
147}
148
149
150static void
151update_state( GLcontext *ctx, GLuint new_state )
152{
153 /* not much to do here - pass it on */
154 _swrast_InvalidateState( ctx, new_state );
155 _swsetup_InvalidateState( ctx, new_state );
156 _vbo_InvalidateState( ctx, new_state );
157 _tnl_InvalidateState( ctx, new_state );
158}
159
160
161/**
162 * Called by ctx->Driver.GetBufferSize from in core Mesa to query the
163 * current framebuffer size.
164 */
165static void
166get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
167{
168 GET_CURRENT_CONTEXT(ctx);
169 fbContextPtr fbmesa = FB_CONTEXT(ctx);
170
171 *width = fbmesa->dri.drawable->w;
172 *height = fbmesa->dri.drawable->h;
173}
174
175
176static void
177updateFramebufferSize(GLcontext *ctx)
178{
179 fbContextPtr fbmesa = FB_CONTEXT(ctx);
180 struct gl_framebuffer *fb = ctx->WinSysDrawBuffer;
181 if (fbmesa->dri.drawable->w != fb->Width ||
182 fbmesa->dri.drawable->h != fb->Height) {
183 driUpdateFramebufferSize(ctx, fbmesa->dri.drawable);
184 }
185}
186
187static void
188viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
189{
190 /* XXX this should be called after we acquire the DRI lock, not here */
191 updateFramebufferSize(ctx);
192}
193
194
195static void
196init_core_functions( struct dd_function_table *functions )
197{
198 functions->GetString = get_string;
199 functions->UpdateState = update_state;
200 functions->GetBufferSize = get_buffer_size;
201 functions->Viewport = viewport;
202
203 functions->Clear = _swrast_Clear; /* could accelerate with blits */
204}
205
206
207/*
208 * Generate code for span functions.
209 */
210
211/* 24-bit BGR */
212#define NAME(PREFIX) PREFIX##_B8G8R8
213#define RB_TYPE GLubyte
214#define SPAN_VARS \
215 driRenderbuffer *drb = (driRenderbuffer *) rb;
216#define INIT_PIXEL_PTR(P, X, Y) \
217 GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 3;
218#define INC_PIXEL_PTR(P) P += 3
219#define STORE_PIXEL(DST, X, Y, VALUE) \
220 DST[0] = VALUE[BCOMP]; \
221 DST[1] = VALUE[GCOMP]; \
222 DST[2] = VALUE[RCOMP]
223#define FETCH_PIXEL(DST, SRC) \
224 DST[RCOMP] = SRC[2]; \
225 DST[GCOMP] = SRC[1]; \
226 DST[BCOMP] = SRC[0]; \
227 DST[ACOMP] = 0xff
228
229#include "swrast/s_spantemp.h"
230
231
232/* 32-bit BGRA */
233#define NAME(PREFIX) PREFIX##_B8G8R8A8
234#define RB_TYPE GLubyte
235#define SPAN_VARS \
236 driRenderbuffer *drb = (driRenderbuffer *) rb;
237#define INIT_PIXEL_PTR(P, X, Y) \
238 GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 4;
239#define INC_PIXEL_PTR(P) P += 4
240#define STORE_PIXEL(DST, X, Y, VALUE) \
241 DST[0] = VALUE[BCOMP]; \
242 DST[1] = VALUE[GCOMP]; \
243 DST[2] = VALUE[RCOMP]; \
244 DST[3] = VALUE[ACOMP]
245#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
246 DST[0] = VALUE[BCOMP]; \
247 DST[1] = VALUE[GCOMP]; \
248 DST[2] = VALUE[RCOMP]; \
249 DST[3] = 0xff
250#define FETCH_PIXEL(DST, SRC) \
251 DST[RCOMP] = SRC[2]; \
252 DST[GCOMP] = SRC[1]; \
253 DST[BCOMP] = SRC[0]; \
254 DST[ACOMP] = SRC[3]
255
256#include "swrast/s_spantemp.h"
257
258
259/* 16-bit BGR (XXX implement dithering someday) */
260#define NAME(PREFIX) PREFIX##_B5G6R5
261#define RB_TYPE GLubyte
262#define SPAN_VARS \
263 driRenderbuffer *drb = (driRenderbuffer *) rb;
264#define INIT_PIXEL_PTR(P, X, Y) \
265 GLushort *P = (GLushort *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 2;
266#define INC_PIXEL_PTR(P) P += 1
267#define STORE_PIXEL(DST, X, Y, VALUE) \
268 DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
269#define FETCH_PIXEL(DST, SRC) \
270 DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \
271 DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >> 5) & 0x3) ); \
272 DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
273 DST[ACOMP] = 0xff
274
275#include "swrast/s_spantemp.h"
276
277
278/* 15-bit BGR (XXX implement dithering someday) */
279#define NAME(PREFIX) PREFIX##_B5G5R5
280#define RB_TYPE GLubyte
281#define SPAN_VARS \
282 driRenderbuffer *drb = (driRenderbuffer *) rb;
283#define INIT_PIXEL_PTR(P, X, Y) \
284 GLushort *P = (GLushort *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 2;
285#define INC_PIXEL_PTR(P) P += 1
286#define STORE_PIXEL(DST, X, Y, VALUE) \
287 DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) )
288#define FETCH_PIXEL(DST, SRC) \
289 DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \
290 DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >> 5) & 0x7) ); \
291 DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
292 DST[ACOMP] = 0xff
293
294#include "swrast/s_spantemp.h"
295
296
297/* 8-bit color index */
298#define NAME(PREFIX) PREFIX##_CI8
299#define CI_MODE
300#define RB_TYPE GLubyte
301#define SPAN_VARS \
302 driRenderbuffer *drb = (driRenderbuffer *) rb;
303#define INIT_PIXEL_PTR(P, X, Y) \
304 GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X);
305#define INC_PIXEL_PTR(P) P += 1
306#define STORE_PIXEL(DST, X, Y, VALUE) \
307 *DST = VALUE[0]
308#define FETCH_PIXEL(DST, SRC) \
309 DST = SRC[0]
310
311#include "swrast/s_spantemp.h"
312
313
314
315void
316fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
317{
318 ASSERT(drb->Base.InternalFormat == GL_RGBA);
319 if (drb->Base.InternalFormat == GL_RGBA) {
320 if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
321 drb->Base.GetRow = get_row_B5G6R5;
322 drb->Base.GetValues = get_values_B5G6R5;
323 drb->Base.PutRow = put_row_B5G6R5;
324 drb->Base.PutMonoRow = put_mono_row_B5G6R5;
325 drb->Base.PutRowRGB = put_row_rgb_B5G6R5;
326 drb->Base.PutValues = put_values_B5G6R5;
327 drb->Base.PutMonoValues = put_mono_values_B5G6R5;
328 }
329 else if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) {
330 drb->Base.GetRow = get_row_B5G5R5;
331 drb->Base.GetValues = get_values_B5G5R5;
332 drb->Base.PutRow = put_row_B5G5R5;
333 drb->Base.PutMonoRow = put_mono_row_B5G5R5;
334 drb->Base.PutRowRGB = put_row_rgb_B5G5R5;
335 drb->Base.PutValues = put_values_B5G5R5;
336 drb->Base.PutMonoValues = put_mono_values_B5G5R5;
337 }
338 else if (vis->redBits == 8 && vis->greenBits == 8 && vis->blueBits == 8
339 && vis->alphaBits == 8) {
340 drb->Base.GetRow = get_row_B8G8R8A8;
341 drb->Base.GetValues = get_values_B8G8R8A8;
342 drb->Base.PutRow = put_row_B8G8R8A8;
343 drb->Base.PutMonoRow = put_mono_row_B8G8R8A8;
344 drb->Base.PutRowRGB = put_row_rgb_B8G8R8A8;
345 drb->Base.PutValues = put_values_B8G8R8A8;
346 drb->Base.PutMonoValues = put_mono_values_B8G8R8A8;
347 }
348 else if (vis->redBits == 8 && vis->greenBits == 8 && vis->blueBits == 8
349 && vis->alphaBits == 0) {
350 drb->Base.GetRow = get_row_B8G8R8;
351 drb->Base.GetValues = get_values_B8G8R8;
352 drb->Base.PutRow = put_row_B8G8R8;
353 drb->Base.PutMonoRow = put_mono_row_B8G8R8;
354 drb->Base.PutRowRGB = put_row_rgb_B8G8R8;
355 drb->Base.PutValues = put_values_B8G8R8;
356 drb->Base.PutMonoValues = put_mono_values_B8G8R8;
357 }
358 else if (vis->indexBits == 8) {
359 drb->Base.GetRow = get_row_CI8;
360 drb->Base.GetValues = get_values_CI8;
361 drb->Base.PutRow = put_row_CI8;
362 drb->Base.PutMonoRow = put_mono_row_CI8;
363 drb->Base.PutValues = put_values_CI8;
364 drb->Base.PutMonoValues = put_mono_values_CI8;
365 }
366 }
367 else {
368 /* hardware z/stencil/etc someday */
369 }
370}
371
372
373static void
374fbDestroyScreen( __DRIscreenPrivate *sPriv )
375{
376}
377
378
379static const __DRIconfig **fbFillInModes(unsigned pixel_bits,
380 unsigned depth_bits,
381 unsigned stencil_bits,
382 GLboolean have_back_buffer)
383{
384 unsigned deep = (depth_bits > 17);
385
386 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
387 * enough to add support. Basically, if a context is created with an
388 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
389 * will never be used.
390 */
391
392 static const GLenum db_modes[2] = { GLX_NONE, GLX_SWAP_UNDEFINED_OML };
393 uint8_t depth_bits_array[4];
394 uint8_t stencil_bits_array[4];
395 if(deep) {
396 depth_bits_array[0] = 0;
397 depth_bits_array[1] = 24;
398 stencil_bits_array[0] = 0;
399 stencil_bits_array[1] = 8;
400 } else {
401 depth_bits_array[0] = depth_bits;
402 depth_bits_array[1] = 0;
403 depth_bits_array[2] = depth_bits;
404 depth_bits_array[3] = 0;
405 stencil_bits_array[0] = 0;
406 stencil_bits_array[1] = 0;
407 stencil_bits_array[2] = 8;
408 stencil_bits_array[3] = 8;
409 }
410
411 return driCreateConfigs(
412 deep ? GL_RGBA : GL_RGB,
413 deep ? GL_UNSIGNED_INT_8_8_8_8 : GL_UNSIGNED_SHORT_5_6_5,
414 depth_bits_array,
415 stencil_bits_array,
416 deep ? 2 : 4,
417 db_modes, 2);
418}
419
420/**
421 * This is the driver specific part of the createNewScreen entry point.
422 * Called when using legacy DRI.
423 *
424 * return the __GLcontextModes supported by this driver
425 */
426static const __DRIconfig **fbInitScreen(__DRIscreenPrivate *psp)
427{
428 static const __DRIversion ddx_expected = { 1, 0, 0 };
429 static const __DRIversion dri_expected = { 4, 0, 0 };
430 static const __DRIversion drm_expected = { 1, 0, 0 };
431
432
433 if ( ! driCheckDriDdxDrmVersions2( "vboxvideo",
434 & psp->dri_version, & dri_expected,
435 & psp->ddx_version, & ddx_expected,
436 & psp->drm_version, & drm_expected ) ) {
437 return NULL;
438 }
439
440 driInitExtensions( NULL, card_extensions, GL_FALSE );
441
442 return fbFillInModes( psp->fbBPP,
443 (psp->fbBPP == 16) ? 16 : 24,
444 (psp->fbBPP == 16) ? 0 : 8,
445 1);
446}
447
448/* Create the device specific context.
449 */
450static GLboolean
451fbCreateContext( const __GLcontextModes *glVisual,
452 __DRIcontextPrivate *driContextPriv,
453 void *sharedContextPrivate)
454{
455 fbContextPtr fbmesa;
456 GLcontext *ctx, *shareCtx;
457 struct dd_function_table functions;
458
459 assert(glVisual);
460 assert(driContextPriv);
461
462 /* Allocate the Fb context */
463 fbmesa = (fbContextPtr) _mesa_calloc( sizeof(*fbmesa) );
464 if ( !fbmesa )
465 return GL_FALSE;
466
467 /* Init default driver functions then plug in our FBdev-specific functions
468 */
469 _mesa_init_driver_functions(&functions);
470 init_core_functions(&functions);
471
472 /* Allocate the Mesa context */
473 if (sharedContextPrivate)
474 shareCtx = ((fbContextPtr) sharedContextPrivate)->glCtx;
475 else
476 shareCtx = NULL;
477
478 ctx = fbmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
479 &functions, (void *) fbmesa);
480 if (!fbmesa->glCtx) {
481 _mesa_free(fbmesa);
482 return GL_FALSE;
483 }
484 driContextPriv->driverPrivate = fbmesa;
485
486 /* Create module contexts */
487 _swrast_CreateContext( ctx );
488 _vbo_CreateContext( ctx );
489 _tnl_CreateContext( ctx );
490 _swsetup_CreateContext( ctx );
491 _swsetup_Wakeup( ctx );
492
493
494 /* use default TCL pipeline */
495 {
496 TNLcontext *tnl = TNL_CONTEXT(ctx);
497 tnl->Driver.RunPipeline = _tnl_run_pipeline;
498 }
499
500 _mesa_enable_sw_extensions(ctx);
501
502 return GL_TRUE;
503}
504
505
506static void
507fbDestroyContext( __DRIcontextPrivate *driContextPriv )
508{
509 GET_CURRENT_CONTEXT(ctx);
510 fbContextPtr fbmesa = (fbContextPtr) driContextPriv->driverPrivate;
511 fbContextPtr current = ctx ? FB_CONTEXT(ctx) : NULL;
512
513 /* check if we're deleting the currently bound context */
514 if (fbmesa == current) {
515 _mesa_make_current(NULL, NULL, NULL);
516 }
517
518 /* Free fb context resources */
519 if ( fbmesa ) {
520 _swsetup_DestroyContext( fbmesa->glCtx );
521 _tnl_DestroyContext( fbmesa->glCtx );
522 _vbo_DestroyContext( fbmesa->glCtx );
523 _swrast_DestroyContext( fbmesa->glCtx );
524
525 /* free the Mesa context */
526 fbmesa->glCtx->DriverCtx = NULL;
527 _mesa_destroy_context( fbmesa->glCtx );
528
529 _mesa_free( fbmesa );
530 }
531}
532
533
534/* Create and initialize the Mesa and driver specific pixmap buffer
535 * data.
536 */
537static GLboolean
538fbCreateBuffer( __DRIscreenPrivate *driScrnPriv,
539 __DRIdrawablePrivate *driDrawPriv,
540 const __GLcontextModes *mesaVis,
541 GLboolean isPixmap )
542{
543 struct gl_framebuffer *mesa_framebuffer;
544
545 if (isPixmap) {
546 return GL_FALSE; /* not implemented */
547 }
548 else {
549 const GLboolean swDepth = mesaVis->depthBits > 0;
550 const GLboolean swAlpha = mesaVis->alphaBits > 0;
551 const GLboolean swAccum = mesaVis->accumRedBits > 0;
552 const GLboolean swStencil = mesaVis->stencilBits > 0;
553
554 mesa_framebuffer = _mesa_create_framebuffer(mesaVis);
555 if (!mesa_framebuffer)
556 return 0;
557
558 /* XXX double-check these parameters (bpp vs cpp, etc) */
559 {
560 driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA,
561 driScrnPriv->pFB,
562 driScrnPriv->fbBPP / 8,
563 driScrnPriv->fbOrigin,
564 driScrnPriv->fbStride,
565 driDrawPriv);
566 fbSetSpanFunctions(drb, mesaVis);
567 _mesa_add_renderbuffer(mesa_framebuffer,
568 BUFFER_FRONT_LEFT, &drb->Base);
569 }
570 if (mesaVis->doubleBufferMode) {
571 /* XXX what are the correct origin/stride values? */
572 GLvoid *backBuf = _mesa_malloc(driScrnPriv->fbStride
573 * driScrnPriv->fbHeight);
574 driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA,
575 backBuf,
576 driScrnPriv->fbBPP /8,
577 driScrnPriv->fbOrigin,
578 driScrnPriv->fbStride,
579 driDrawPriv);
580 fbSetSpanFunctions(drb, mesaVis);
581 _mesa_add_renderbuffer(mesa_framebuffer,
582 BUFFER_BACK_LEFT, &drb->Base);
583 }
584
585 _mesa_add_soft_renderbuffers(mesa_framebuffer,
586 GL_FALSE, /* color */
587 swDepth,
588 swStencil,
589 swAccum,
590 swAlpha, /* or always zero? */
591 GL_FALSE /* aux */);
592
593 driDrawPriv->driverPrivate = mesa_framebuffer;
594
595 return 1;
596 }
597}
598
599
600static void
601fbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
602{
603 _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
604}
605
606
607
608/* If the backbuffer is on a videocard, this is extraordinarily slow!
609 */
610static void
611fbSwapBuffers( __DRIdrawablePrivate *dPriv )
612{
613 struct gl_framebuffer *mesa_framebuffer = (struct gl_framebuffer *)dPriv->driverPrivate;
614 struct gl_renderbuffer * front_renderbuffer = mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
615 void *frontBuffer = front_renderbuffer->Data;
616 int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch;
617 void *backBuffer = mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data;
618
619 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
620 fbContextPtr fbmesa = (fbContextPtr) dPriv->driContextPriv->driverPrivate;
621 GLcontext *ctx = fbmesa->glCtx;
622
623 if (ctx->Visual.doubleBufferMode) {
624 int i;
625 int offset = 0;
626 char *tmp = _mesa_malloc(currentPitch);
627
628 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering commands */
629
630 ASSERT(frontBuffer);
631 ASSERT(backBuffer);
632
633 for (i = 0; i < dPriv->h; i++) {
634 _mesa_memcpy(tmp, (char *) backBuffer + offset,
635 currentPitch);
636 _mesa_memcpy((char *) frontBuffer + offset, tmp,
637 currentPitch);
638 offset += currentPitch;
639 }
640
641 _mesa_free(tmp);
642 }
643 }
644 else {
645 /* XXX this shouldn't be an error but we can't handle it for now */
646 _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n");
647 }
648}
649
650
651/* Force the context `c' to be the current context and associate with it
652 * buffer `b'.
653 */
654static GLboolean
655fbMakeCurrent( __DRIcontextPrivate *driContextPriv,
656 __DRIdrawablePrivate *driDrawPriv,
657 __DRIdrawablePrivate *driReadPriv )
658{
659 if ( driContextPriv ) {
660 fbContextPtr newFbCtx =
661 (fbContextPtr) driContextPriv->driverPrivate;
662
663 newFbCtx->dri.drawable = driDrawPriv;
664
665 _mesa_make_current( newFbCtx->glCtx,
666 driDrawPriv->driverPrivate,
667 driReadPriv->driverPrivate);
668 } else {
669 _mesa_make_current( NULL, NULL, NULL );
670 }
671
672 return GL_TRUE;
673}
674
675
676/* Force the context `c' to be unbound from its buffer.
677 */
678static GLboolean
679fbUnbindContext( __DRIcontextPrivate *driContextPriv )
680{
681 return GL_TRUE;
682}
683
684const struct __DriverAPIRec driDriverAPI = {
685 .InitScreen = fbInitScreen,
686 .DestroyScreen = fbDestroyScreen,
687 .CreateContext = fbCreateContext,
688 .DestroyContext = fbDestroyContext,
689 .CreateBuffer = fbCreateBuffer,
690 .DestroyBuffer = fbDestroyBuffer,
691 .SwapBuffers = fbSwapBuffers,
692 .MakeCurrent = fbMakeCurrent,
693 .UnbindContext = fbUnbindContext,
694};
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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