2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2003 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 ?
43 #ifdef USE_GLFBDEV_DRIVER
47 #include "GL/glfbdev.h"
49 #include "extensions.h"
51 #include "texformat.h"
54 #include "array_cache/acache.h"
55 #include "swrast/swrast.h"
56 #include "swrast_setup/swrast_setup.h"
58 #include "tnl/t_context.h"
59 #include "tnl/t_pipeline.h"
70 * Derived from Mesa's GLvisual class.
72 struct GLFBDevVisualRec
{
73 GLvisual glvisual
; /* base class */
74 struct fb_fix_screeninfo fix
;
75 struct fb_var_screeninfo var
;
80 * Derived from Mesa's GLframebuffer class.
82 struct GLFBDevBufferRec
{
83 GLframebuffer glframebuffer
; /* base class */
84 GLFBDevVisualPtr visual
;
85 struct fb_fix_screeninfo fix
;
86 struct fb_var_screeninfo var
;
91 GLuint rowStride
; /* in bytes */
92 GLubyte
*frontBottom
; /* pointer to last row */
93 GLubyte
*backBottom
; /* pointer to last row */
94 GLubyte
*curBottom
; /* = frontBottom or backBottom */
95 GLboolean mallocBackBuffer
;
99 * Derived from Mesa's GLcontext class.
101 struct GLFBDevContextRec
{
102 GLcontext glcontext
; /* base class */
103 GLFBDevVisualPtr visual
;
104 GLFBDevBufferPtr drawBuffer
;
105 GLFBDevBufferPtr readBuffer
;
106 GLFBDevBufferPtr curBuffer
;
111 #define GLFBDEV_CONTEXT(CTX) ((GLFBDevContextPtr) (CTX))
112 #define GLFBDEV_BUFFER(BUF) ((GLFBDevBufferPtr) (BUF))
115 /**********************************************************************/
116 /* Internal device driver functions */
117 /**********************************************************************/
120 static const GLubyte
*
121 get_string(GLcontext
*ctx
, GLenum pname
)
126 return (const GLubyte
*) "Mesa glfbdev";
134 update_state( GLcontext
*ctx
, GLuint new_state
)
136 /* not much to do here - pass it on */
137 _swrast_InvalidateState( ctx
, new_state
);
138 _swsetup_InvalidateState( ctx
, new_state
);
139 _ac_InvalidateState( ctx
, new_state
);
140 _tnl_InvalidateState( ctx
, new_state
);
145 get_buffer_size( GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
147 const GLFBDevBufferPtr fbdevbuffer
= (GLFBDevBufferPtr
) buffer
;
148 *width
= fbdevbuffer
->var
.xres_virtual
;
149 *height
= fbdevbuffer
->var
.yres_virtual
;
153 /* specifies the buffer for swrast span rendering/reading */
155 set_buffer( GLcontext
*ctx
, GLframebuffer
*buffer
, GLuint bufferBit
)
157 GLFBDevContextPtr fbdevctx
= GLFBDEV_CONTEXT(ctx
);
158 GLFBDevBufferPtr fbdevbuf
= GLFBDEV_BUFFER(buffer
);
159 fbdevctx
->curBuffer
= fbdevbuf
;
162 fbdevbuf
->curBottom
= fbdevbuf
->frontBottom
;
165 fbdevbuf
->curBottom
= fbdevbuf
->backBottom
;
168 _mesa_problem(ctx
, "bad bufferBit in set_buffer()");
174 init_core_functions( GLcontext
*ctx
)
176 ctx
->Driver
.GetString
= get_string
;
177 ctx
->Driver
.UpdateState
= update_state
;
178 ctx
->Driver
.ResizeBuffers
= _swrast_alloc_buffers
;
179 ctx
->Driver
.GetBufferSize
= get_buffer_size
;
181 ctx
->Driver
.Accum
= _swrast_Accum
;
182 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
183 ctx
->Driver
.Clear
= _swrast_Clear
; /* would be good to optimize */
184 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
185 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
186 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
187 ctx
->Driver
.DrawBuffer
= _swrast_DrawBuffer
;
189 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
190 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
191 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
192 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
193 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
194 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
195 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
196 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
198 ctx
->Driver
.CompressedTexImage1D
= _mesa_store_compressed_teximage1d
;
199 ctx
->Driver
.CompressedTexImage2D
= _mesa_store_compressed_teximage2d
;
200 ctx
->Driver
.CompressedTexImage3D
= _mesa_store_compressed_teximage3d
;
201 ctx
->Driver
.CompressedTexSubImage1D
= _mesa_store_compressed_texsubimage1d
;
202 ctx
->Driver
.CompressedTexSubImage2D
= _mesa_store_compressed_texsubimage2d
;
203 ctx
->Driver
.CompressedTexSubImage3D
= _mesa_store_compressed_texsubimage3d
;
205 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
206 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
207 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
208 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
209 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
210 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
211 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
212 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
213 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
218 * Generate code for span functions.
222 #define NAME(PREFIX) PREFIX##_B8G8R8
224 const GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx); \
225 const GLFBDevBufferPtr fbdevbuf = fbdevctx->curBuffer;
226 #define INIT_PIXEL_PTR(P, X, Y) \
227 GLubyte *P = fbdevbuf->curBottom - (Y) * fbdevbuf->rowStride + (X) * 3
228 #define INC_PIXEL_PTR(P) P += 3
229 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
230 P[0] = B; P[1] = G; P[2] = R
231 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
232 P[0] = B; P[1] = G; P[2] = R
233 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
234 R = P[2]; G = P[1]; B = P[0]; A = CHAN_MAX
236 #include "swrast/s_spantemp.h"
240 #define NAME(PREFIX) PREFIX##_B8G8R8A8
242 const GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx); \
243 const GLFBDevBufferPtr fbdevbuf = fbdevctx->curBuffer;
244 #define INIT_PIXEL_PTR(P, X, Y) \
245 GLubyte *P = fbdevbuf->curBottom - (Y) * fbdevbuf->rowStride + (X) * 4
246 #define INC_PIXEL_PTR(P) P += 4
247 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
248 P[0] = B; P[1] = G; P[2] = R; P[3] = 255
249 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
250 P[0] = B; P[1] = G; P[2] = R; P[3] = A
251 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
252 R = P[2]; G = P[1]; B = P[0]; A = P[3]
254 #include "swrast/s_spantemp.h"
257 /* 16-bit BGR (XXX implement dithering someday) */
258 #define NAME(PREFIX) PREFIX##_B5G6R5
260 const GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx); \
261 const GLFBDevBufferPtr fbdevbuf = fbdevctx->curBuffer;
262 #define INIT_PIXEL_PTR(P, X, Y) \
263 GLushort *P = (GLushort *) (fbdevbuf->curBottom - (Y) * fbdevbuf->rowStride + (X) * 2)
264 #define INC_PIXEL_PTR(P) P += 1
265 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
266 *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
267 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
268 *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
269 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
270 R = ( (((*P) >> 8) & 0xf8) | (((*P) >> 11) & 0x7) ); \
271 G = ( (((*P) >> 3) & 0xfc) | (((*P) >> 5) & 0x3) ); \
272 B = ( (((*P) << 3) & 0xf8) | (((*P) ) & 0x7) ); \
275 #include "swrast/s_spantemp.h"
278 /* 15-bit BGR (XXX implement dithering someday) */
279 #define NAME(PREFIX) PREFIX##_B5G5R5
281 const GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx); \
282 const GLFBDevBufferPtr fbdevbuf = fbdevctx->curBuffer;
283 #define INIT_PIXEL_PTR(P, X, Y) \
284 GLushort *P = (GLushort *) (fbdevbuf->curBottom - (Y) * fbdevbuf->rowStride + (X) * 2)
285 #define INC_PIXEL_PTR(P) P += 1
286 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
287 *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
288 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
289 *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
290 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
291 R = ( (((*P) >> 7) & 0xf8) | (((*P) >> 10) & 0x7) ); \
292 G = ( (((*P) >> 2) & 0xf8) | (((*P) >> 5) & 0x7) ); \
293 B = ( (((*P) << 3) & 0xf8) | (((*P) ) & 0x7) ); \
296 #include "swrast/s_spantemp.h"
299 /* 8-bit color index */
300 #define NAME(PREFIX) PREFIX##_CI8
302 const GLFBDevContextPtr fbdevctx = GLFBDEV_CONTEXT(ctx); \
303 const GLFBDevBufferPtr fbdevbuf = fbdevctx->curBuffer;
304 #define INIT_PIXEL_PTR(P, X, Y) \
305 GLubyte *P = fbdevbuf->curBottom - (Y) * fbdevbuf->rowStride + (X)
306 #define INC_PIXEL_PTR(P) P += 1
307 #define STORE_CI_PIXEL(P, CI) \
309 #define FETCH_CI_PIXEL(CI, P) \
312 #include "swrast/s_spantemp.h"
314 /**********************************************************************/
315 /* Public API functions */
316 /**********************************************************************/
320 glFBDevGetString( int str
)
324 return "Mesa Project";
325 case GLFBDEV_VERSION
:
334 glFBDevGetProcAddress( const char *procName
)
336 struct name_address
{
340 static const struct name_address functions
[] = {
341 { "glFBDevGetString", (void *) glFBDevGetString
},
342 { "glFBDevGetProcAddress", (void *) glFBDevGetProcAddress
},
343 { "glFBDevCreateVisual", (void *) glFBDevCreateVisual
},
344 { "glFBDevDestroyVisual", (void *) glFBDevDestroyVisual
},
345 { "glFBDevGetVisualAttrib", (void *) glFBDevGetVisualAttrib
},
346 { "glFBDevCreateBuffer", (void *) glFBDevCreateBuffer
},
347 { "glFBDevDestroyBuffer", (void *) glFBDevDestroyBuffer
},
348 { "glFBDevGetBufferAttrib", (void *) glFBDevGetBufferAttrib
},
349 { "glFBDevGetCurrentDrawBuffer", (void *) glFBDevGetCurrentDrawBuffer
},
350 { "glFBDevGetCurrentReadBuffer", (void *) glFBDevGetCurrentReadBuffer
},
351 { "glFBDevSwapBuffers", (void *) glFBDevSwapBuffers
},
352 { "glFBDevCreateContext", (void *) glFBDevCreateContext
},
353 { "glFBDevDestroyContext", (void *) glFBDevDestroyContext
},
354 { "glFBDevGetContextAttrib", (void *) glFBDevGetContextAttrib
},
355 { "glFBDevGetCurrentContext", (void *) glFBDevGetCurrentContext
},
356 { "glFBDevMakeCurrent", (void *) glFBDevMakeCurrent
},
359 const struct name_address
*entry
;
360 for (entry
= functions
; entry
->name
; entry
++) {
361 if (_mesa_strcmp(entry
->name
, procName
) == 0) {
365 return _glapi_get_proc_address(procName
);
370 glFBDevCreateVisual( const struct fb_fix_screeninfo
*fixInfo
,
371 const struct fb_var_screeninfo
*varInfo
,
374 GLFBDevVisualPtr vis
;
376 GLboolean rgbFlag
= GL_TRUE
, dbFlag
= GL_FALSE
, stereoFlag
= GL_FALSE
;
377 GLint redBits
= 0, greenBits
= 0, blueBits
= 0, alphaBits
= 0;
378 GLint indexBits
= 0, depthBits
= 0, stencilBits
= 0;
379 GLint accumRedBits
= 0, accumGreenBits
= 0;
380 GLint accumBlueBits
= 0, accumAlphaBits
= 0;
381 GLint numSamples
= 0;
386 vis
= CALLOC_STRUCT(GLFBDevVisualRec
);
390 vis
->fix
= *fixInfo
; /* struct assignment */
391 vis
->var
= *varInfo
; /* struct assignment */
393 for (attrib
= attribs
; attrib
&& *attrib
!= GLFBDEV_NONE
; attrib
++) {
395 case GLFBDEV_DOUBLE_BUFFER
:
398 case GLFBDEV_COLOR_INDEX
:
401 case GLFBDEV_DEPTH_SIZE
:
402 depthBits
= attrib
[1];
405 case GLFBDEV_STENCIL_SIZE
:
406 stencilBits
= attrib
[1];
409 case GLFBDEV_ACCUM_SIZE
:
410 accumRedBits
= accumGreenBits
= accumBlueBits
= accumAlphaBits
415 /* ignored for now */
418 /* unexpected token */
425 redBits
= varInfo
->red
.length
;
426 greenBits
= varInfo
->green
.length
;
427 blueBits
= varInfo
->blue
.length
;
428 alphaBits
= varInfo
->transp
.length
;
430 if ((fixInfo
->visual
== FB_VISUAL_TRUECOLOR
||
431 fixInfo
->visual
== FB_VISUAL_DIRECTCOLOR
)
432 && varInfo
->bits_per_pixel
== 24
433 && varInfo
->red
.offset
== 16
434 && varInfo
->green
.offset
== 8
435 && varInfo
->blue
.offset
== 0) {
436 vis
->pixelFormat
= PF_B8G8R8
;
438 else if ((fixInfo
->visual
== FB_VISUAL_TRUECOLOR
||
439 fixInfo
->visual
== FB_VISUAL_DIRECTCOLOR
)
440 && varInfo
->bits_per_pixel
== 32
441 && varInfo
->red
.offset
== 16
442 && varInfo
->green
.offset
== 8
443 && varInfo
->blue
.offset
== 0
444 && varInfo
->transp
.offset
== 24) {
445 vis
->pixelFormat
= PF_B8G8R8A8
;
447 else if ((fixInfo
->visual
== FB_VISUAL_TRUECOLOR
||
448 fixInfo
->visual
== FB_VISUAL_DIRECTCOLOR
)
449 && varInfo
->bits_per_pixel
== 16
450 && varInfo
->red
.offset
== 11
451 && varInfo
->green
.offset
== 5
452 && varInfo
->blue
.offset
== 0) {
453 vis
->pixelFormat
= PF_B5G6R5
;
455 else if ((fixInfo
->visual
== FB_VISUAL_TRUECOLOR
||
456 fixInfo
->visual
== FB_VISUAL_DIRECTCOLOR
)
457 && varInfo
->bits_per_pixel
== 16
458 && varInfo
->red
.offset
== 10
459 && varInfo
->green
.offset
== 5
460 && varInfo
->blue
.offset
== 0) {
461 vis
->pixelFormat
= PF_B5G5R5
;
464 _mesa_problem(NULL
, "Unsupported fbdev RGB visual/bitdepth!\n");
466 printf("fixInfo->visual = 0x%x\n", fixInfo->visual);
467 printf("varInfo->bits_per_pixel = %d\n", varInfo->bits_per_pixel);
468 printf("varInfo->red.offset = %d\n", varInfo->red.offset);
469 printf("varInfo->green.offset = %d\n", varInfo->green.offset);
470 printf("varInfo->blue.offset = %d\n", varInfo->blue.offset);
477 indexBits
= varInfo
->bits_per_pixel
;
478 if ((fixInfo
->visual
== FB_VISUAL_PSEUDOCOLOR
||
479 fixInfo
->visual
== FB_VISUAL_STATIC_PSEUDOCOLOR
)
480 && varInfo
->bits_per_pixel
== 8) {
481 vis
->pixelFormat
= PF_CI8
;
484 _mesa_problem(NULL
, "Unsupported fbdev CI visual/bitdepth!\n");
490 if (!_mesa_initialize_visual(&vis
->glvisual
, rgbFlag
, dbFlag
, stereoFlag
,
491 redBits
, greenBits
, blueBits
, alphaBits
,
492 indexBits
, depthBits
, stencilBits
,
493 accumRedBits
, accumGreenBits
,
494 accumBlueBits
, accumAlphaBits
,
496 /* something was invalid */
506 glFBDevDestroyVisual( GLFBDevVisualPtr visual
)
514 glFBDevGetVisualAttrib( const GLFBDevVisualPtr visual
, int attrib
)
524 glFBDevCreateBuffer( const struct fb_fix_screeninfo
*fixInfo
,
525 const struct fb_var_screeninfo
*varInfo
,
526 const GLFBDevVisualPtr visual
,
527 void *frontBuffer
, void *backBuffer
, size_t size
)
529 GLFBDevBufferPtr buf
;
535 if (visual
->fix
.visual
!= fixInfo
->visual
||
536 visual
->fix
.type
!= fixInfo
->type
||
537 visual
->var
.bits_per_pixel
!= varInfo
->bits_per_pixel
||
538 visual
->var
.grayscale
!= varInfo
->grayscale
||
539 visual
->var
.red
.offset
!= varInfo
->red
.offset
||
540 visual
->var
.green
.offset
!= varInfo
->green
.offset
||
541 visual
->var
.blue
.offset
!= varInfo
->blue
.offset
||
542 visual
->var
.transp
.offset
!= varInfo
->transp
.offset
) {
543 /* visual mismatch! */
547 buf
= CALLOC_STRUCT(GLFBDevBufferRec
);
551 _mesa_initialize_framebuffer(&buf
->glframebuffer
, &visual
->glvisual
,
552 visual
->glvisual
.haveDepthBuffer
,
553 visual
->glvisual
.haveStencilBuffer
,
554 visual
->glvisual
.haveAccumBuffer
,
557 buf
->fix
= *fixInfo
; /* struct assignment */
558 buf
->var
= *varInfo
; /* struct assignment */
559 buf
->visual
= visual
; /* ptr assignment */
560 buf
->frontStart
= frontBuffer
;
562 buf
->bytesPerPixel
= visual
->var
.bits_per_pixel
/ 8;
563 buf
->rowStride
= visual
->var
.xres_virtual
* buf
->bytesPerPixel
;
564 buf
->frontBottom
= (GLubyte
*) buf
->frontStart
565 + (visual
->var
.yres_virtual
- 1) * buf
->rowStride
;
567 if (visual
->glvisual
.doubleBufferMode
) {
569 buf
->backStart
= backBuffer
;
570 buf
->mallocBackBuffer
= GL_FALSE
;
573 buf
->backStart
= _mesa_malloc(size
);
574 if (!buf
->backStart
) {
575 _mesa_free_framebuffer_data(&buf
->glframebuffer
);
579 buf
->mallocBackBuffer
= GL_TRUE
;
581 buf
->backBottom
= (GLubyte
*) buf
->backStart
582 + (visual
->var
.yres_virtual
- 1) * buf
->rowStride
;
583 buf
->curBottom
= buf
->backBottom
;
586 buf
->backStart
= NULL
;
587 buf
->mallocBackBuffer
= GL_FALSE
;
588 buf
->backBottom
= NULL
;
589 buf
->curBottom
= buf
->frontBottom
;
597 glFBDevDestroyBuffer( GLFBDevBufferPtr buffer
)
600 /* check if destroying the current buffer */
601 GLFBDevBufferPtr curDraw
= glFBDevGetCurrentDrawBuffer();
602 GLFBDevBufferPtr curRead
= glFBDevGetCurrentReadBuffer();
603 if (buffer
== curDraw
|| buffer
== curRead
) {
604 glFBDevMakeCurrent( NULL
, NULL
, NULL
);
606 if (buffer
->mallocBackBuffer
) {
607 _mesa_free(buffer
->backStart
);
609 /* free the software depth, stencil, accum buffers */
610 _mesa_free_framebuffer_data(&buffer
->glframebuffer
);
617 glFBDevGetBufferAttrib( const GLFBDevBufferPtr buffer
, int attrib
)
626 glFBDevGetCurrentDrawBuffer( void )
628 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
630 return fbdevctx
->drawBuffer
;
637 glFBDevGetCurrentReadBuffer( void )
639 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
641 return fbdevctx
->readBuffer
;
648 glFBDevSwapBuffers( GLFBDevBufferPtr buffer
)
650 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
652 if (!buffer
|| !buffer
->visual
->glvisual
.doubleBufferMode
)
655 /* check if swapping currently bound buffer */
656 if (fbdevctx
->drawBuffer
== buffer
) {
657 /* flush pending rendering */
658 _mesa_notifySwapBuffers(&fbdevctx
->glcontext
);
661 ASSERT(buffer
->frontStart
);
662 ASSERT(buffer
->backStart
);
663 _mesa_memcpy(buffer
->frontStart
, buffer
->backStart
, buffer
->size
);
668 glFBDevCreateContext( const GLFBDevVisualPtr visual
, GLFBDevContextPtr share
)
670 GLFBDevContextPtr ctx
;
675 ctx
= CALLOC_STRUCT(GLFBDevContextRec
);
679 if (!_mesa_initialize_context(&ctx
->glcontext
, &visual
->glvisual
,
680 share
? &share
->glcontext
: NULL
,
681 (void *) ctx
, GL_FALSE
)) {
686 ctx
->visual
= visual
;
688 /* Create module contexts */
689 glctx
= (GLcontext
*) &ctx
->glcontext
;
690 init_core_functions( glctx
);
691 _swrast_CreateContext( glctx
);
692 _ac_CreateContext( glctx
);
693 _tnl_CreateContext( glctx
);
694 _swsetup_CreateContext( glctx
);
695 _swsetup_Wakeup( glctx
);
699 struct swrast_device_driver
*swdd
;
700 swdd
= _swrast_GetDeviceDriverReference( glctx
);
701 swdd
->SetBuffer
= set_buffer
;
702 if (visual
->pixelFormat
== PF_B8G8R8
) {
703 swdd
->WriteRGBASpan
= write_rgba_span_B8G8R8
;
704 swdd
->WriteRGBSpan
= write_rgb_span_B8G8R8
;
705 swdd
->WriteMonoRGBASpan
= write_monorgba_span_B8G8R8
;
706 swdd
->WriteRGBAPixels
= write_rgba_pixels_B8G8R8
;
707 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_B8G8R8
;
708 swdd
->ReadRGBASpan
= read_rgba_span_B8G8R8
;
709 swdd
->ReadRGBAPixels
= read_rgba_pixels_B8G8R8
;
711 else if (visual
->pixelFormat
== PF_B8G8R8A8
) {
712 swdd
->WriteRGBASpan
= write_rgba_span_B8G8R8A8
;
713 swdd
->WriteRGBSpan
= write_rgb_span_B8G8R8A8
;
714 swdd
->WriteMonoRGBASpan
= write_monorgba_span_B8G8R8A8
;
715 swdd
->WriteRGBAPixels
= write_rgba_pixels_B8G8R8A8
;
716 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_B8G8R8A8
;
717 swdd
->ReadRGBASpan
= read_rgba_span_B8G8R8A8
;
718 swdd
->ReadRGBAPixels
= read_rgba_pixels_B8G8R8A8
;
720 else if (visual
->pixelFormat
== PF_B5G6R5
) {
721 swdd
->WriteRGBASpan
= write_rgba_span_B5G6R5
;
722 swdd
->WriteRGBSpan
= write_rgb_span_B5G6R5
;
723 swdd
->WriteMonoRGBASpan
= write_monorgba_span_B5G6R5
;
724 swdd
->WriteRGBAPixels
= write_rgba_pixels_B5G6R5
;
725 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_B5G6R5
;
726 swdd
->ReadRGBASpan
= read_rgba_span_B5G6R5
;
727 swdd
->ReadRGBAPixels
= read_rgba_pixels_B5G6R5
;
729 else if (visual
->pixelFormat
== PF_B5G5R5
) {
730 swdd
->WriteRGBASpan
= write_rgba_span_B5G5R5
;
731 swdd
->WriteRGBSpan
= write_rgb_span_B5G5R5
;
732 swdd
->WriteMonoRGBASpan
= write_monorgba_span_B5G5R5
;
733 swdd
->WriteRGBAPixels
= write_rgba_pixels_B5G5R5
;
734 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_B5G5R5
;
735 swdd
->ReadRGBASpan
= read_rgba_span_B5G5R5
;
736 swdd
->ReadRGBAPixels
= read_rgba_pixels_B5G5R5
;
738 else if (visual
->pixelFormat
== PF_CI8
) {
739 swdd
->WriteCI32Span
= write_index32_span_CI8
;
740 swdd
->WriteCI8Span
= write_index8_span_CI8
;
741 swdd
->WriteMonoCISpan
= write_monoindex_span_CI8
;
742 swdd
->WriteCI32Pixels
= write_index_pixels_CI8
;
743 swdd
->WriteMonoCIPixels
= write_monoindex_pixels_CI8
;
744 swdd
->ReadCI32Span
= read_index_span_CI8
;
745 swdd
->ReadCI32Pixels
= read_index_pixels_CI8
;
748 _mesa_printf("bad pixelformat: %d\n", visual
->pixelFormat
);
752 /* use default TCL pipeline */
754 TNLcontext
*tnl
= TNL_CONTEXT(glctx
);
755 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
758 _mesa_enable_sw_extensions(glctx
);
765 glFBDevDestroyContext( GLFBDevContextPtr context
)
767 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
770 if (fbdevctx
== context
) {
771 /* destroying current context */
772 _mesa_make_current2(NULL
, NULL
, NULL
);
773 _mesa_notifyDestroy(&context
->glcontext
);
775 _mesa_free_context_data(&context
->glcontext
);
782 glFBDevGetContextAttrib( const GLFBDevContextPtr context
, int attrib
)
791 glFBDevGetCurrentContext( void )
793 GET_CURRENT_CONTEXT(ctx
);
794 return (GLFBDevContextPtr
) ctx
;
799 glFBDevMakeCurrent( GLFBDevContextPtr context
,
800 GLFBDevBufferPtr drawBuffer
,
801 GLFBDevBufferPtr readBuffer
)
803 if (context
&& drawBuffer
&& readBuffer
) {
804 /* Make sure the context's visual and the buffers' visuals match.
805 * XXX we might do this by comparing specific fields like bits_per_pixel,
806 * visual, etc. in the future.
808 if (context
->visual
!= drawBuffer
->visual
||
809 context
->visual
!= readBuffer
->visual
) {
812 _mesa_make_current2( &context
->glcontext
,
813 &drawBuffer
->glframebuffer
,
814 &readBuffer
->glframebuffer
);
815 context
->drawBuffer
= drawBuffer
;
816 context
->readBuffer
= readBuffer
;
817 context
->curBuffer
= drawBuffer
;
821 _mesa_make_current2( NULL
, NULL
, NULL
);
827 #endif /* USE_GLFBDEV_DRIVER */