2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
27 * OpenGL (Mesa) interface for fbdev.
28 * For info about fbdev:
29 * http://www.tldp.org/HOWTO/Framebuffer-HOWTO.html
32 * Colours 640x400 640x480 800x600 1024x768 1152x864 1280x1024 1600x1200
33 * --------+--------------------------------------------------------------
34 * 4 bits | ? ? 0x302 ? ? ? ?
35 * 8 bits | 0x300 0x301 0x303 0x305 0x161 0x307 0x31C
36 * 15 bits | ? 0x310 0x313 0x316 0x162 0x319 0x31D
37 * 16 bits | ? 0x311 0x314 0x317 0x163 0x31A 0x31E
38 * 24 bits | ? 0x312 0x315 0x318 ? 0x31B 0x31F
39 * 32 bits | ? ? ? ? 0x164 ?
42 #ifdef USE_GLFBDEV_DRIVER
45 #include "GL/glfbdev.h"
46 #include "main/glheader.h"
47 #include "main/buffers.h"
48 #include "main/context.h"
49 #include "main/extensions.h"
50 #include "main/fbobject.h"
51 #include "main/framebuffer.h"
52 #include "main/imports.h"
53 #include "main/renderbuffer.h"
54 #include "main/texformat.h"
55 #include "main/teximage.h"
56 #include "main/texstore.h"
58 #include "swrast/swrast.h"
59 #include "swrast_setup/swrast_setup.h"
61 #include "tnl/t_context.h"
62 #include "tnl/t_pipeline.h"
63 #include "drivers/common/driverfuncs.h"
67 * Pixel formats we support:
76 * Derived from Mesa's GLvisual class.
78 struct GLFBDevVisualRec
{
79 GLvisual glvisual
; /* base class */
80 struct fb_fix_screeninfo fix
;
81 struct fb_var_screeninfo var
;
86 * Derived from Mesa's GLframebuffer class.
88 struct GLFBDevBufferRec
{
89 GLframebuffer glframebuffer
; /* base class */
90 GLFBDevVisualPtr visual
;
91 struct fb_fix_screeninfo fix
;
92 struct fb_var_screeninfo var
;
93 size_t size
; /* color buffer size in bytes */
98 * Derived from Mesa's GLcontext class.
100 struct GLFBDevContextRec
{
101 GLcontext glcontext
; /* base class */
102 GLFBDevVisualPtr visual
;
103 GLFBDevBufferPtr drawBuffer
;
104 GLFBDevBufferPtr readBuffer
;
105 GLFBDevBufferPtr curBuffer
;
109 * Derived from Mesa's gl_renderbuffer class.
111 struct GLFBDevRenderbufferRec
{
112 struct gl_renderbuffer Base
;
113 GLubyte
*bottom
; /* pointer to last row */
114 GLuint rowStride
; /* in bytes */
115 GLboolean mallocedBuffer
;
119 /**********************************************************************/
120 /* Internal device driver functions */
121 /**********************************************************************/
124 static const GLubyte
*
125 get_string(GLcontext
*ctx
, GLenum pname
)
130 return (const GLubyte
*) "Mesa glfbdev";
138 update_state( GLcontext
*ctx
, GLuint new_state
)
140 /* not much to do here - pass it on */
141 _swrast_InvalidateState( ctx
, new_state
);
142 _swsetup_InvalidateState( ctx
, new_state
);
143 _vbo_InvalidateState( ctx
, new_state
);
144 _tnl_InvalidateState( ctx
, new_state
);
149 get_buffer_size( GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
151 const GLFBDevBufferPtr fbdevbuffer
= (GLFBDevBufferPtr
) buffer
;
152 *width
= fbdevbuffer
->var
.xres
;
153 *height
= fbdevbuffer
->var
.yres
;
158 * We only implement this function as a mechanism to check if the
159 * framebuffer size has changed (and update corresponding state).
162 viewport(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
164 GLuint newWidth
, newHeight
;
165 GLframebuffer
*buffer
;
167 buffer
= ctx
->WinSysDrawBuffer
;
168 get_buffer_size( buffer
, &newWidth
, &newHeight
);
169 if (buffer
->Width
!= newWidth
|| buffer
->Height
!= newHeight
) {
170 _mesa_resize_framebuffer(ctx
, buffer
, newWidth
, newHeight
);
173 buffer
= ctx
->WinSysReadBuffer
;
174 get_buffer_size( buffer
, &newWidth
, &newHeight
);
175 if (buffer
->Width
!= newWidth
|| buffer
->Height
!= newHeight
) {
176 _mesa_resize_framebuffer(ctx
, buffer
, newWidth
, newHeight
);
182 * Generate code for span functions.
186 #define NAME(PREFIX) PREFIX##_B8G8R8
187 #define RB_TYPE GLubyte
189 struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
190 #define INIT_PIXEL_PTR(P, X, Y) \
191 GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 3
192 #define INC_PIXEL_PTR(P) P += 3
193 #define STORE_PIXEL(DST, X, Y, VALUE) \
194 DST[0] = VALUE[BCOMP]; \
195 DST[1] = VALUE[GCOMP]; \
196 DST[2] = VALUE[RCOMP]
197 #define FETCH_PIXEL(DST, SRC) \
198 DST[RCOMP] = SRC[2]; \
199 DST[GCOMP] = SRC[1]; \
200 DST[BCOMP] = SRC[0]; \
201 DST[ACOMP] = CHAN_MAX
203 #include "swrast/s_spantemp.h"
207 #define NAME(PREFIX) PREFIX##_B8G8R8A8
208 #define RB_TYPE GLubyte
210 struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
211 #define INIT_PIXEL_PTR(P, X, Y) \
212 GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 4
213 #define INC_PIXEL_PTR(P) P += 4
214 #define STORE_PIXEL(DST, X, Y, VALUE) \
215 DST[0] = VALUE[BCOMP]; \
216 DST[1] = VALUE[GCOMP]; \
217 DST[2] = VALUE[RCOMP]; \
218 DST[3] = VALUE[ACOMP]
219 #define FETCH_PIXEL(DST, SRC) \
220 DST[RCOMP] = SRC[2]; \
221 DST[GCOMP] = SRC[1]; \
222 DST[BCOMP] = SRC[0]; \
225 #include "swrast/s_spantemp.h"
228 /* 16-bit BGR (XXX implement dithering someday) */
229 #define NAME(PREFIX) PREFIX##_B5G6R5
230 #define RB_TYPE GLubyte
232 struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
233 #define INIT_PIXEL_PTR(P, X, Y) \
234 GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
235 #define INC_PIXEL_PTR(P) P += 1
236 #define STORE_PIXEL(DST, X, Y, VALUE) \
237 DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
238 #define FETCH_PIXEL(DST, SRC) \
239 DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \
240 DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >> 5) & 0x3) ); \
241 DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
242 DST[ACOMP] = CHAN_MAX
244 #include "swrast/s_spantemp.h"
247 /* 15-bit BGR (XXX implement dithering someday) */
248 #define NAME(PREFIX) PREFIX##_B5G5R5
249 #define RB_TYPE GLubyte
251 struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
252 #define INIT_PIXEL_PTR(P, X, Y) \
253 GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
254 #define INC_PIXEL_PTR(P) P += 1
255 #define STORE_PIXEL(DST, X, Y, VALUE) \
256 DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) )
257 #define FETCH_PIXEL(DST, SRC) \
258 DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \
259 DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >> 5) & 0x7) ); \
260 DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
261 DST[ACOMP] = CHAN_MAX
263 #include "swrast/s_spantemp.h"
266 /**********************************************************************/
267 /* Public API functions */
268 /**********************************************************************/
272 glFBDevGetString( int str
)
276 return "Mesa Project";
277 case GLFBDEV_VERSION
:
286 glFBDevGetProcAddress( const char *procName
)
288 struct name_address
{
290 const GLFBDevProc func
;
292 static const struct name_address functions
[] = {
293 { "glFBDevGetString", (GLFBDevProc
) glFBDevGetString
},
294 { "glFBDevGetProcAddress", (GLFBDevProc
) glFBDevGetProcAddress
},
295 { "glFBDevCreateVisual", (GLFBDevProc
) glFBDevCreateVisual
},
296 { "glFBDevDestroyVisual", (GLFBDevProc
) glFBDevDestroyVisual
},
297 { "glFBDevGetVisualAttrib", (GLFBDevProc
) glFBDevGetVisualAttrib
},
298 { "glFBDevCreateBuffer", (GLFBDevProc
) glFBDevCreateBuffer
},
299 { "glFBDevDestroyBuffer", (GLFBDevProc
) glFBDevDestroyBuffer
},
300 { "glFBDevGetBufferAttrib", (GLFBDevProc
) glFBDevGetBufferAttrib
},
301 { "glFBDevGetCurrentDrawBuffer", (GLFBDevProc
) glFBDevGetCurrentDrawBuffer
},
302 { "glFBDevGetCurrentReadBuffer", (GLFBDevProc
) glFBDevGetCurrentReadBuffer
},
303 { "glFBDevSwapBuffers", (GLFBDevProc
) glFBDevSwapBuffers
},
304 { "glFBDevCreateContext", (GLFBDevProc
) glFBDevCreateContext
},
305 { "glFBDevDestroyContext", (GLFBDevProc
) glFBDevDestroyContext
},
306 { "glFBDevGetContextAttrib", (GLFBDevProc
) glFBDevGetContextAttrib
},
307 { "glFBDevGetCurrentContext", (GLFBDevProc
) glFBDevGetCurrentContext
},
308 { "glFBDevMakeCurrent", (GLFBDevProc
) glFBDevMakeCurrent
},
311 const struct name_address
*entry
;
312 for (entry
= functions
; entry
->name
; entry
++) {
313 if (strcmp(entry
->name
, procName
) == 0) {
317 return _glapi_get_proc_address(procName
);
322 glFBDevCreateVisual( const struct fb_fix_screeninfo
*fixInfo
,
323 const struct fb_var_screeninfo
*varInfo
,
326 GLFBDevVisualPtr vis
;
328 GLboolean dbFlag
= GL_FALSE
, stereoFlag
= GL_FALSE
;
329 GLint redBits
= 0, greenBits
= 0, blueBits
= 0, alphaBits
= 0;
330 GLint depthBits
= 0, stencilBits
= 0;
331 GLint accumRedBits
= 0, accumGreenBits
= 0;
332 GLint accumBlueBits
= 0, accumAlphaBits
= 0;
333 GLint numSamples
= 0;
338 vis
= CALLOC_STRUCT(GLFBDevVisualRec
);
342 vis
->fix
= *fixInfo
; /* struct assignment */
343 vis
->var
= *varInfo
; /* struct assignment */
345 for (attrib
= attribs
; attrib
&& *attrib
!= GLFBDEV_NONE
; attrib
++) {
347 case GLFBDEV_DOUBLE_BUFFER
:
350 case GLFBDEV_DEPTH_SIZE
:
351 depthBits
= attrib
[1];
354 case GLFBDEV_STENCIL_SIZE
:
355 stencilBits
= attrib
[1];
358 case GLFBDEV_ACCUM_SIZE
:
359 accumRedBits
= accumGreenBits
= accumBlueBits
= accumAlphaBits
364 /* ignored for now */
366 case GLFBDEV_MULTISAMPLE
:
367 numSamples
= attrib
[1];
370 case GLFBDEV_COLOR_INDEX
:
371 /* Mesa no longer supports color-index rendering. */
373 /* unexpected token */
379 redBits
= varInfo
->red
.length
;
380 greenBits
= varInfo
->green
.length
;
381 blueBits
= varInfo
->blue
.length
;
382 alphaBits
= varInfo
->transp
.length
;
384 if (fixInfo
->visual
== FB_VISUAL_TRUECOLOR
||
385 fixInfo
->visual
== FB_VISUAL_DIRECTCOLOR
) {
386 if (varInfo
->bits_per_pixel
== 24
387 && varInfo
->red
.offset
== 16
388 && varInfo
->green
.offset
== 8
389 && varInfo
->blue
.offset
== 0) {
390 vis
->pixelFormat
= PF_B8G8R8
;
392 else if (varInfo
->bits_per_pixel
== 32
393 && varInfo
->red
.offset
== 16
394 && varInfo
->green
.offset
== 8
395 && varInfo
->blue
.offset
== 0) {
396 vis
->pixelFormat
= PF_B8G8R8A8
;
398 else if (varInfo
->bits_per_pixel
== 16
399 && varInfo
->red
.offset
== 11
400 && varInfo
->green
.offset
== 5
401 && varInfo
->blue
.offset
== 0) {
402 vis
->pixelFormat
= PF_B5G6R5
;
404 else if (varInfo
->bits_per_pixel
== 16
405 && varInfo
->red
.offset
== 10
406 && varInfo
->green
.offset
== 5
407 && varInfo
->blue
.offset
== 0) {
408 vis
->pixelFormat
= PF_B5G5R5
;
411 _mesa_problem(NULL
, "Unsupported fbdev RGB visual/bitdepth!\n");
417 if (!_mesa_initialize_visual(&vis
->glvisual
, dbFlag
, stereoFlag
,
418 redBits
, greenBits
, blueBits
, alphaBits
,
419 depthBits
, stencilBits
,
420 accumRedBits
, accumGreenBits
,
421 accumBlueBits
, accumAlphaBits
,
423 /* something was invalid */
433 glFBDevDestroyVisual( GLFBDevVisualPtr visual
)
441 glFBDevGetVisualAttrib( const GLFBDevVisualPtr visual
, int attrib
)
451 delete_renderbuffer(struct gl_renderbuffer
*rb
)
453 struct GLFBDevRenderbufferRec
*frb
= (struct GLFBDevRenderbufferRec
*) rb
;
454 if (frb
->mallocedBuffer
) {
455 free(frb
->Base
.Data
);
462 renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
463 GLenum internalFormat
, GLuint width
, GLuint height
)
465 /* no-op: the renderbuffer storage is allocated just once when it's
466 * created. Never resized or reallocated.
472 static struct GLFBDevRenderbufferRec
*
473 new_glfbdev_renderbuffer(void *bufferStart
, const GLFBDevVisualPtr visual
)
475 struct GLFBDevRenderbufferRec
*rb
= CALLOC_STRUCT(GLFBDevRenderbufferRec
);
478 int pixelFormat
= visual
->pixelFormat
;
480 _mesa_init_renderbuffer(&rb
->Base
, name
);
482 rb
->Base
.Delete
= delete_renderbuffer
;
483 rb
->Base
.AllocStorage
= renderbuffer_storage
;
485 if (pixelFormat
== PF_B8G8R8
) {
486 rb
->Base
.GetRow
= get_row_B8G8R8
;
487 rb
->Base
.GetValues
= get_values_B8G8R8
;
488 rb
->Base
.PutRow
= put_row_B8G8R8
;
489 rb
->Base
.PutRowRGB
= put_row_rgb_B8G8R8
;
490 rb
->Base
.PutMonoRow
= put_mono_row_B8G8R8
;
491 rb
->Base
.PutValues
= put_values_B8G8R8
;
492 rb
->Base
.PutMonoValues
= put_mono_values_B8G8R8
;
494 else if (pixelFormat
== PF_B8G8R8A8
) {
495 rb
->Base
.GetRow
= get_row_B8G8R8A8
;
496 rb
->Base
.GetValues
= get_values_B8G8R8A8
;
497 rb
->Base
.PutRow
= put_row_B8G8R8A8
;
498 rb
->Base
.PutRowRGB
= put_row_rgb_B8G8R8A8
;
499 rb
->Base
.PutMonoRow
= put_mono_row_B8G8R8A8
;
500 rb
->Base
.PutValues
= put_values_B8G8R8A8
;
501 rb
->Base
.PutMonoValues
= put_mono_values_B8G8R8A8
;
503 else if (pixelFormat
== PF_B5G6R5
) {
504 rb
->Base
.GetRow
= get_row_B5G6R5
;
505 rb
->Base
.GetValues
= get_values_B5G6R5
;
506 rb
->Base
.PutRow
= put_row_B5G6R5
;
507 rb
->Base
.PutRowRGB
= put_row_rgb_B5G6R5
;
508 rb
->Base
.PutMonoRow
= put_mono_row_B5G6R5
;
509 rb
->Base
.PutValues
= put_values_B5G6R5
;
510 rb
->Base
.PutMonoValues
= put_mono_values_B5G6R5
;
512 else if (pixelFormat
== PF_B5G5R5
) {
513 rb
->Base
.GetRow
= get_row_B5G5R5
;
514 rb
->Base
.GetValues
= get_values_B5G5R5
;
515 rb
->Base
.PutRow
= put_row_B5G5R5
;
516 rb
->Base
.PutRowRGB
= put_row_rgb_B5G5R5
;
517 rb
->Base
.PutMonoRow
= put_mono_row_B5G5R5
;
518 rb
->Base
.PutValues
= put_values_B5G5R5
;
519 rb
->Base
.PutMonoValues
= put_mono_values_B5G5R5
;
522 rb
->Base
.InternalFormat
= GL_RGBA
;
523 rb
->Base
._BaseFormat
= GL_RGBA
;
524 rb
->Base
.DataType
= GL_UNSIGNED_BYTE
;
525 rb
->Base
.Data
= bufferStart
;
527 rb
->rowStride
= visual
->var
.xres_virtual
* visual
->var
.bits_per_pixel
/ 8;
528 rb
->bottom
= (GLubyte
*) bufferStart
529 + (visual
->var
.yres
- 1) * rb
->rowStride
;
531 rb
->Base
.Width
= visual
->var
.xres
;
532 rb
->Base
.Height
= visual
->var
.yres
;
534 rb
->Base
.RedBits
= visual
->var
.red
.length
;
535 rb
->Base
.GreenBits
= visual
->var
.green
.length
;
536 rb
->Base
.BlueBits
= visual
->var
.blue
.length
;
537 rb
->Base
.AlphaBits
= visual
->var
.transp
.length
;
539 rb
->Base
.InternalFormat
= pixelFormat
;
545 glFBDevCreateBuffer( const struct fb_fix_screeninfo
*fixInfo
,
546 const struct fb_var_screeninfo
*varInfo
,
547 const GLFBDevVisualPtr visual
,
548 void *frontBuffer
, void *backBuffer
, size_t size
)
550 struct GLFBDevRenderbufferRec
*frontrb
, *backrb
;
551 GLFBDevBufferPtr buf
;
557 /* this is to update the visual if there was a resize and the
558 buffer is created again */
559 visual
->var
= *varInfo
;
560 visual
->fix
= *fixInfo
;
562 if (visual
->fix
.visual
!= fixInfo
->visual
||
563 visual
->fix
.type
!= fixInfo
->type
||
564 visual
->var
.bits_per_pixel
!= varInfo
->bits_per_pixel
||
565 visual
->var
.grayscale
!= varInfo
->grayscale
||
566 visual
->var
.red
.offset
!= varInfo
->red
.offset
||
567 visual
->var
.green
.offset
!= varInfo
->green
.offset
||
568 visual
->var
.blue
.offset
!= varInfo
->blue
.offset
||
569 visual
->var
.transp
.offset
!= varInfo
->transp
.offset
) {
570 /* visual mismatch! */
574 buf
= CALLOC_STRUCT(GLFBDevBufferRec
);
578 /* basic framebuffer setup */
579 _mesa_initialize_window_framebuffer(&buf
->glframebuffer
, &visual
->glvisual
);
580 /* add front renderbuffer */
581 frontrb
= new_glfbdev_renderbuffer(frontBuffer
, visual
);
582 _mesa_add_renderbuffer(&buf
->glframebuffer
, BUFFER_FRONT_LEFT
,
584 /* add back renderbuffer */
585 if (visual
->glvisual
.doubleBufferMode
) {
586 const int malloced
= !backBuffer
;
588 /* malloc a back buffer */
589 backBuffer
= malloc(size
);
591 _mesa_free_framebuffer_data(&buf
->glframebuffer
);
597 backrb
= new_glfbdev_renderbuffer(backBuffer
, visual
);
602 backrb
->mallocedBuffer
= malloced
;
604 _mesa_add_renderbuffer(&buf
->glframebuffer
, BUFFER_BACK_LEFT
,
607 /* add software renderbuffers */
608 _mesa_add_soft_renderbuffers(&buf
->glframebuffer
,
609 GL_FALSE
, /* color */
610 visual
->glvisual
.haveDepthBuffer
,
611 visual
->glvisual
.haveStencilBuffer
,
612 visual
->glvisual
.haveAccumBuffer
,
613 GL_FALSE
, /* alpha */
614 GL_FALSE
/* aux bufs */);
616 buf
->fix
= *fixInfo
; /* struct assignment */
617 buf
->var
= *varInfo
; /* struct assignment */
618 buf
->visual
= visual
; /* ptr assignment */
620 buf
->bytesPerPixel
= visual
->var
.bits_per_pixel
/ 8;
627 glFBDevDestroyBuffer( GLFBDevBufferPtr buffer
)
630 /* check if destroying the current buffer */
631 GLFBDevBufferPtr curDraw
= glFBDevGetCurrentDrawBuffer();
632 GLFBDevBufferPtr curRead
= glFBDevGetCurrentReadBuffer();
633 if (buffer
== curDraw
|| buffer
== curRead
) {
634 glFBDevMakeCurrent( NULL
, NULL
, NULL
);
637 struct gl_framebuffer
*fb
= &buffer
->glframebuffer
;
638 _mesa_reference_framebuffer(&fb
, NULL
);
645 glFBDevGetBufferAttrib( const GLFBDevBufferPtr buffer
, int attrib
)
654 glFBDevGetCurrentDrawBuffer( void )
656 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
658 return fbdevctx
->drawBuffer
;
665 glFBDevGetCurrentReadBuffer( void )
667 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
669 return fbdevctx
->readBuffer
;
676 glFBDevSwapBuffers( GLFBDevBufferPtr buffer
)
678 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
679 struct GLFBDevRenderbufferRec
*frontrb
= (struct GLFBDevRenderbufferRec
*)
680 buffer
->glframebuffer
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
681 struct GLFBDevRenderbufferRec
*backrb
= (struct GLFBDevRenderbufferRec
*)
682 buffer
->glframebuffer
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
684 if (!buffer
|| !buffer
->visual
->glvisual
.doubleBufferMode
)
687 /* check if swapping currently bound buffer */
688 if (fbdevctx
->drawBuffer
== buffer
) {
689 /* flush pending rendering */
690 _mesa_notifySwapBuffers(&fbdevctx
->glcontext
);
693 ASSERT(frontrb
->Base
.Data
);
694 ASSERT(backrb
->Base
.Data
);
695 memcpy(frontrb
->Base
.Data
, backrb
->Base
.Data
, buffer
->size
);
700 glFBDevCreateContext( const GLFBDevVisualPtr visual
, GLFBDevContextPtr share
)
702 GLFBDevContextPtr ctx
;
704 struct dd_function_table functions
;
708 ctx
= CALLOC_STRUCT(GLFBDevContextRec
);
712 /* build table of device driver functions */
713 _mesa_init_driver_functions(&functions
);
714 functions
.GetString
= get_string
;
715 functions
.UpdateState
= update_state
;
716 functions
.GetBufferSize
= get_buffer_size
;
717 functions
.Viewport
= viewport
;
719 if (!_mesa_initialize_context(&ctx
->glcontext
, &visual
->glvisual
,
720 share
? &share
->glcontext
: NULL
,
721 &functions
, (void *) ctx
)) {
726 ctx
->visual
= visual
;
728 /* Create module contexts */
729 glctx
= (GLcontext
*) &ctx
->glcontext
;
730 _swrast_CreateContext( glctx
);
731 _vbo_CreateContext( glctx
);
732 _tnl_CreateContext( glctx
);
733 _swsetup_CreateContext( glctx
);
734 _swsetup_Wakeup( glctx
);
736 /* use default TCL pipeline */
738 TNLcontext
*tnl
= TNL_CONTEXT(glctx
);
739 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
742 _mesa_enable_sw_extensions(glctx
);
743 _mesa_enable_1_3_extensions(glctx
);
744 _mesa_enable_1_4_extensions(glctx
);
745 _mesa_enable_1_5_extensions(glctx
);
746 _mesa_enable_2_0_extensions(glctx
);
747 _mesa_enable_2_1_extensions(glctx
);
754 glFBDevDestroyContext( GLFBDevContextPtr context
)
756 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
759 GLcontext
*mesaCtx
= &context
->glcontext
;
761 _swsetup_DestroyContext( mesaCtx
);
762 _swrast_DestroyContext( mesaCtx
);
763 _tnl_DestroyContext( mesaCtx
);
764 _vbo_DestroyContext( mesaCtx
);
766 if (fbdevctx
== context
) {
767 /* destroying current context */
768 _mesa_make_current(NULL
, NULL
, NULL
);
770 _mesa_free_context_data(&context
->glcontext
);
777 glFBDevGetContextAttrib( const GLFBDevContextPtr context
, int attrib
)
786 glFBDevGetCurrentContext( void )
788 GET_CURRENT_CONTEXT(ctx
);
789 return (GLFBDevContextPtr
) ctx
;
794 glFBDevMakeCurrent( GLFBDevContextPtr context
,
795 GLFBDevBufferPtr drawBuffer
,
796 GLFBDevBufferPtr readBuffer
)
798 if (context
&& drawBuffer
&& readBuffer
) {
799 /* Make sure the context's visual and the buffers' visuals match.
800 * XXX we might do this by comparing specific fields like bits_per_pixel,
801 * visual, etc. in the future.
803 if (context
->visual
!= drawBuffer
->visual
||
804 context
->visual
!= readBuffer
->visual
) {
807 _mesa_make_current( &context
->glcontext
,
808 &drawBuffer
->glframebuffer
,
809 &readBuffer
->glframebuffer
);
810 context
->drawBuffer
= drawBuffer
;
811 context
->readBuffer
= readBuffer
;
812 context
->curBuffer
= drawBuffer
;
816 _mesa_make_current( NULL
, NULL
, NULL
);
822 #endif /* USE_GLFBDEV_DRIVER */