2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 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 ?
41 #ifdef USE_GLFBDEV_DRIVER
45 #include "GL/glfbdev.h"
48 #include "extensions.h"
50 #include "framebuffer.h"
52 #include "renderbuffer.h"
53 #include "texformat.h"
56 #include "array_cache/acache.h"
57 #include "swrast/swrast.h"
58 #include "swrast_setup/swrast_setup.h"
60 #include "tnl/t_context.h"
61 #include "tnl/t_pipeline.h"
62 #include "drivers/common/driverfuncs.h"
73 * Derived from Mesa's GLvisual class.
75 struct GLFBDevVisualRec
{
76 GLvisual glvisual
; /* base class */
77 struct fb_fix_screeninfo fix
;
78 struct fb_var_screeninfo var
;
83 * Derived from Mesa's GLframebuffer class.
85 struct GLFBDevBufferRec
{
86 GLframebuffer glframebuffer
; /* base class */
87 GLFBDevVisualPtr visual
;
88 struct fb_fix_screeninfo fix
;
89 struct fb_var_screeninfo var
;
90 size_t size
; /* color buffer size in bytes */
95 * Derived from Mesa's GLcontext class.
97 struct GLFBDevContextRec
{
98 GLcontext glcontext
; /* base class */
99 GLFBDevVisualPtr visual
;
100 GLFBDevBufferPtr drawBuffer
;
101 GLFBDevBufferPtr readBuffer
;
102 GLFBDevBufferPtr curBuffer
;
106 * Derived from Mesa's gl_renderbuffer class.
108 struct GLFBDevRenderbufferRec
{
109 struct gl_renderbuffer Base
;
110 GLubyte
*bottom
; /* pointer to last row */
111 GLuint rowStride
; /* in bytes */
112 GLboolean mallocedBuffer
;
117 #define GLFBDEV_CONTEXT(CTX) ((GLFBDevContextPtr) (CTX))
118 #define GLFBDEV_BUFFER(BUF) ((GLFBDevBufferPtr) (BUF))
121 /**********************************************************************/
122 /* Internal device driver functions */
123 /**********************************************************************/
126 static const GLubyte
*
127 get_string(GLcontext
*ctx
, GLenum pname
)
132 return (const GLubyte
*) "Mesa glfbdev";
140 update_state( GLcontext
*ctx
, GLuint new_state
)
142 /* not much to do here - pass it on */
143 _swrast_InvalidateState( ctx
, new_state
);
144 _swsetup_InvalidateState( ctx
, new_state
);
145 _ac_InvalidateState( ctx
, new_state
);
146 _tnl_InvalidateState( ctx
, new_state
);
151 get_buffer_size( GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
153 const GLFBDevBufferPtr fbdevbuffer
= GLFBDEV_BUFFER(buffer
);
154 *width
= fbdevbuffer
->var
.xres_virtual
;
155 *height
= fbdevbuffer
->var
.yres_virtual
;
160 viewport(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
162 /* poll for window size change and realloc software Z/stencil/etc if needed */
163 _mesa_ResizeBuffersMESA();
167 /* specifies the buffer for swrast span rendering/reading */
169 set_buffer( GLcontext
*ctx
, GLframebuffer
*buffer
, GLuint bufferBit
)
171 /* this is a no-op when using the new gl_renderbuffer span functions. */
176 * Generate code for span functions.
180 #define NAME(PREFIX) PREFIX##_B8G8R8
181 #define FORMAT GL_RGBA8
183 struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
184 #define INIT_PIXEL_PTR(P, X, Y) \
185 GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 3
186 #define INC_PIXEL_PTR(P) P += 3
187 #define STORE_PIXEL(DST, X, Y, VALUE) \
188 DST[0] = VALUE[BCOMP]; \
189 DST[1] = VALUE[GCOMP]; \
190 DST[2] = VALUE[RCOMP]
191 #define FETCH_PIXEL(DST, SRC) \
192 DST[RCOMP] = SRC[2]; \
193 DST[GCOMP] = SRC[1]; \
194 DST[BCOMP] = SRC[0]; \
195 DST[ACOMP] = CHAN_MAX
197 #include "swrast/s_spantemp2.h"
201 #define NAME(PREFIX) PREFIX##_B8G8R8A8
202 #define FORMAT GL_RGBA8
204 struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
205 #define INIT_PIXEL_PTR(P, X, Y) \
206 GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 4
207 #define INC_PIXEL_PTR(P) P += 4
208 #define STORE_PIXEL(DST, X, Y, VALUE) \
209 DST[0] = VALUE[BCOMP]; \
210 DST[1] = VALUE[GCOMP]; \
211 DST[2] = VALUE[RCOMP]; \
212 DST[3] = VALUE[ACOMP]
213 #define FETCH_PIXEL(DST, SRC) \
214 DST[RCOMP] = SRC[2]; \
215 DST[GCOMP] = SRC[1]; \
216 DST[BCOMP] = SRC[0]; \
219 #include "swrast/s_spantemp2.h"
222 /* 16-bit BGR (XXX implement dithering someday) */
223 #define NAME(PREFIX) PREFIX##_B5G6R5
224 #define FORMAT GL_RGBA8
226 struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
227 #define INIT_PIXEL_PTR(P, X, Y) \
228 GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
229 #define INC_PIXEL_PTR(P) P += 1
230 #define STORE_PIXEL(DST, X, Y, VALUE) \
231 DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
232 #define FETCH_PIXEL(DST, SRC) \
233 DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \
234 DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >> 5) & 0x3) ); \
235 DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
236 DST[ACOMP] = CHAN_MAX
238 #include "swrast/s_spantemp2.h"
241 /* 15-bit BGR (XXX implement dithering someday) */
242 #define NAME(PREFIX) PREFIX##_B5G5R5
243 #define FORMAT GL_RGBA8
245 struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
246 #define INIT_PIXEL_PTR(P, X, Y) \
247 GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
248 #define INC_PIXEL_PTR(P) P += 1
249 #define STORE_PIXEL(DST, X, Y, VALUE) \
250 DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) )
251 #define FETCH_PIXEL(DST, SRC) \
252 DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \
253 DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >> 5) & 0x7) ); \
254 DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
255 DST[ACOMP] = CHAN_MAX
257 #include "swrast/s_spantemp2.h"
260 /* 8-bit color index */
261 #define NAME(PREFIX) PREFIX##_CI8
262 #define FORMAT GL_COLOR_INDEX8_EXT
264 struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
265 #define INIT_PIXEL_PTR(P, X, Y) \
266 GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X)
267 #define INC_PIXEL_PTR(P) P += 1
268 #define STORE_PIXEL(DST, X, Y, VALUE) \
270 #define FETCH_PIXEL(DST, SRC) \
273 #include "swrast/s_spantemp2.h"
278 /**********************************************************************/
279 /* Public API functions */
280 /**********************************************************************/
284 glFBDevGetString( int str
)
288 return "Mesa Project";
289 case GLFBDEV_VERSION
:
298 glFBDevGetProcAddress( const char *procName
)
300 struct name_address
{
302 const GLFBDevProc func
;
304 static const struct name_address functions
[] = {
305 { "glFBDevGetString", (GLFBDevProc
) glFBDevGetString
},
306 { "glFBDevGetProcAddress", (GLFBDevProc
) glFBDevGetProcAddress
},
307 { "glFBDevCreateVisual", (GLFBDevProc
) glFBDevCreateVisual
},
308 { "glFBDevDestroyVisual", (GLFBDevProc
) glFBDevDestroyVisual
},
309 { "glFBDevGetVisualAttrib", (GLFBDevProc
) glFBDevGetVisualAttrib
},
310 { "glFBDevCreateBuffer", (GLFBDevProc
) glFBDevCreateBuffer
},
311 { "glFBDevDestroyBuffer", (GLFBDevProc
) glFBDevDestroyBuffer
},
312 { "glFBDevGetBufferAttrib", (GLFBDevProc
) glFBDevGetBufferAttrib
},
313 { "glFBDevGetCurrentDrawBuffer", (GLFBDevProc
) glFBDevGetCurrentDrawBuffer
},
314 { "glFBDevGetCurrentReadBuffer", (GLFBDevProc
) glFBDevGetCurrentReadBuffer
},
315 { "glFBDevSwapBuffers", (GLFBDevProc
) glFBDevSwapBuffers
},
316 { "glFBDevCreateContext", (GLFBDevProc
) glFBDevCreateContext
},
317 { "glFBDevDestroyContext", (GLFBDevProc
) glFBDevDestroyContext
},
318 { "glFBDevGetContextAttrib", (GLFBDevProc
) glFBDevGetContextAttrib
},
319 { "glFBDevGetCurrentContext", (GLFBDevProc
) glFBDevGetCurrentContext
},
320 { "glFBDevMakeCurrent", (GLFBDevProc
) glFBDevMakeCurrent
},
323 const struct name_address
*entry
;
324 for (entry
= functions
; entry
->name
; entry
++) {
325 if (_mesa_strcmp(entry
->name
, procName
) == 0) {
329 return _glapi_get_proc_address(procName
);
334 glFBDevCreateVisual( const struct fb_fix_screeninfo
*fixInfo
,
335 const struct fb_var_screeninfo
*varInfo
,
338 GLFBDevVisualPtr vis
;
340 GLboolean rgbFlag
= GL_TRUE
, dbFlag
= GL_FALSE
, stereoFlag
= GL_FALSE
;
341 GLint redBits
= 0, greenBits
= 0, blueBits
= 0, alphaBits
= 0;
342 GLint indexBits
= 0, depthBits
= 0, stencilBits
= 0;
343 GLint accumRedBits
= 0, accumGreenBits
= 0;
344 GLint accumBlueBits
= 0, accumAlphaBits
= 0;
345 GLint numSamples
= 0;
350 vis
= CALLOC_STRUCT(GLFBDevVisualRec
);
354 vis
->fix
= *fixInfo
; /* struct assignment */
355 vis
->var
= *varInfo
; /* struct assignment */
357 for (attrib
= attribs
; attrib
&& *attrib
!= GLFBDEV_NONE
; attrib
++) {
359 case GLFBDEV_DOUBLE_BUFFER
:
362 case GLFBDEV_COLOR_INDEX
:
365 case GLFBDEV_DEPTH_SIZE
:
366 depthBits
= attrib
[1];
369 case GLFBDEV_STENCIL_SIZE
:
370 stencilBits
= attrib
[1];
373 case GLFBDEV_ACCUM_SIZE
:
374 accumRedBits
= accumGreenBits
= accumBlueBits
= accumAlphaBits
379 /* ignored for now */
382 /* unexpected token */
389 redBits
= varInfo
->red
.length
;
390 greenBits
= varInfo
->green
.length
;
391 blueBits
= varInfo
->blue
.length
;
392 alphaBits
= varInfo
->transp
.length
;
394 if ((fixInfo
->visual
== FB_VISUAL_TRUECOLOR
||
395 fixInfo
->visual
== FB_VISUAL_DIRECTCOLOR
)
396 && varInfo
->bits_per_pixel
== 24
397 && varInfo
->red
.offset
== 16
398 && varInfo
->green
.offset
== 8
399 && varInfo
->blue
.offset
== 0) {
400 vis
->pixelFormat
= PF_B8G8R8
;
402 else if ((fixInfo
->visual
== FB_VISUAL_TRUECOLOR
||
403 fixInfo
->visual
== FB_VISUAL_DIRECTCOLOR
)
404 && varInfo
->bits_per_pixel
== 32
405 && varInfo
->red
.offset
== 16
406 && varInfo
->green
.offset
== 8
407 && varInfo
->blue
.offset
== 0
408 && varInfo
->transp
.offset
== 24) {
409 vis
->pixelFormat
= PF_B8G8R8A8
;
411 else if ((fixInfo
->visual
== FB_VISUAL_TRUECOLOR
||
412 fixInfo
->visual
== FB_VISUAL_DIRECTCOLOR
)
413 && varInfo
->bits_per_pixel
== 16
414 && varInfo
->red
.offset
== 11
415 && varInfo
->green
.offset
== 5
416 && varInfo
->blue
.offset
== 0) {
417 vis
->pixelFormat
= PF_B5G6R5
;
419 else if ((fixInfo
->visual
== FB_VISUAL_TRUECOLOR
||
420 fixInfo
->visual
== FB_VISUAL_DIRECTCOLOR
)
421 && varInfo
->bits_per_pixel
== 16
422 && varInfo
->red
.offset
== 10
423 && varInfo
->green
.offset
== 5
424 && varInfo
->blue
.offset
== 0) {
425 vis
->pixelFormat
= PF_B5G5R5
;
428 _mesa_problem(NULL
, "Unsupported fbdev RGB visual/bitdepth!\n");
430 printf("fixInfo->visual = 0x%x\n", fixInfo->visual);
431 printf("varInfo->bits_per_pixel = %d\n", varInfo->bits_per_pixel);
432 printf("varInfo->red.offset = %d\n", varInfo->red.offset);
433 printf("varInfo->green.offset = %d\n", varInfo->green.offset);
434 printf("varInfo->blue.offset = %d\n", varInfo->blue.offset);
441 indexBits
= varInfo
->bits_per_pixel
;
442 if ((fixInfo
->visual
== FB_VISUAL_PSEUDOCOLOR
||
443 fixInfo
->visual
== FB_VISUAL_STATIC_PSEUDOCOLOR
)
444 && varInfo
->bits_per_pixel
== 8) {
445 vis
->pixelFormat
= PF_CI8
;
448 _mesa_problem(NULL
, "Unsupported fbdev CI visual/bitdepth!\n");
454 if (!_mesa_initialize_visual(&vis
->glvisual
, rgbFlag
, dbFlag
, stereoFlag
,
455 redBits
, greenBits
, blueBits
, alphaBits
,
456 indexBits
, depthBits
, stencilBits
,
457 accumRedBits
, accumGreenBits
,
458 accumBlueBits
, accumAlphaBits
,
460 /* something was invalid */
470 glFBDevDestroyVisual( GLFBDevVisualPtr visual
)
478 glFBDevGetVisualAttrib( const GLFBDevVisualPtr visual
, int attrib
)
488 delete_renderbuffer(struct gl_renderbuffer
*rb
)
490 struct GLFBDevRenderbufferRec
*frb
= (struct GLFBDevRenderbufferRec
*) rb
;
491 if (frb
->mallocedBuffer
) {
492 _mesa_free(frb
->Base
.Data
);
499 renderbuffer_storage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
500 GLenum internalFormat
, GLuint width
, GLuint height
)
502 /* no-op: the renderbuffer storage is allocated just once when it's
503 * created. Never resized or reallocated.
509 static struct GLFBDevRenderbufferRec
*
510 new_glfbdev_renderbuffer(void *bufferStart
, int pixelFormat
)
512 struct GLFBDevRenderbufferRec
*rb
= CALLOC_STRUCT(GLFBDevRenderbufferRec
);
515 _mesa_init_renderbuffer(&rb
->Base
, name
);
517 rb
->Base
.Delete
= delete_renderbuffer
;
518 rb
->Base
.AllocStorage
= renderbuffer_storage
;
520 if (pixelFormat
== PF_B8G8R8
) {
521 rb
->Base
.GetRow
= get_row_B8G8R8
;
522 rb
->Base
.GetValues
= get_values_B8G8R8
;
523 rb
->Base
.PutRow
= put_row_B8G8R8
;
524 rb
->Base
.PutMonoRow
= put_mono_row_B8G8R8
;
525 rb
->Base
.PutValues
= put_values_B8G8R8
;
526 rb
->Base
.PutMonoValues
= put_mono_values_B8G8R8
;
528 else if (pixelFormat
== PF_B8G8R8A8
) {
529 rb
->Base
.GetRow
= get_row_B8G8R8A8
;
530 rb
->Base
.GetValues
= get_values_B8G8R8A8
;
531 rb
->Base
.PutRow
= put_row_B8G8R8A8
;
532 rb
->Base
.PutMonoRow
= put_mono_row_B8G8R8A8
;
533 rb
->Base
.PutValues
= put_values_B8G8R8A8
;
534 rb
->Base
.PutMonoValues
= put_mono_values_B8G8R8A8
;
536 else if (pixelFormat
== PF_B5G6R5
) {
537 rb
->Base
.GetRow
= get_row_B5G6R5
;
538 rb
->Base
.GetValues
= get_values_B5G6R5
;
539 rb
->Base
.PutRow
= put_row_B5G6R5
;
540 rb
->Base
.PutMonoRow
= put_mono_row_B5G6R5
;
541 rb
->Base
.PutValues
= put_values_B5G6R5
;
542 rb
->Base
.PutMonoValues
= put_mono_values_B5G6R5
;
544 else if (pixelFormat
== PF_B5G5R5
) {
545 rb
->Base
.GetRow
= get_row_B5G5R5
;
546 rb
->Base
.GetValues
= get_values_B5G5R5
;
547 rb
->Base
.PutRow
= put_row_B5G5R5
;
548 rb
->Base
.PutMonoRow
= put_mono_row_B5G5R5
;
549 rb
->Base
.PutValues
= put_values_B5G5R5
;
550 rb
->Base
.PutMonoValues
= put_mono_values_B5G5R5
;
552 else if (pixelFormat
== PF_CI8
) {
553 rb
->Base
.GetRow
= get_row_CI8
;
554 rb
->Base
.GetValues
= get_values_CI8
;
555 rb
->Base
.PutRow
= put_row_CI8
;
556 rb
->Base
.PutMonoRow
= put_mono_row_CI8
;
557 rb
->Base
.PutValues
= put_values_CI8
;
558 rb
->Base
.PutMonoValues
= put_mono_values_CI8
;
561 if (pixelFormat
== PF_CI8
) {
562 rb
->Base
.InternalFormat
= GL_COLOR_INDEX8_EXT
;
563 rb
->Base
._BaseFormat
= GL_COLOR_INDEX
;
566 rb
->Base
.InternalFormat
= GL_RGBA
;
567 rb
->Base
._BaseFormat
= GL_RGBA
;
569 rb
->Base
.DataType
= GL_UNSIGNED_BYTE
;
570 rb
->Base
.Data
= bufferStart
;
577 glFBDevCreateBuffer( const struct fb_fix_screeninfo
*fixInfo
,
578 const struct fb_var_screeninfo
*varInfo
,
579 const GLFBDevVisualPtr visual
,
580 void *frontBuffer
, void *backBuffer
, size_t size
)
582 struct GLFBDevRenderbufferRec
*frontrb
, *backrb
;
583 GLFBDevBufferPtr buf
;
589 if (visual
->fix
.visual
!= fixInfo
->visual
||
590 visual
->fix
.type
!= fixInfo
->type
||
591 visual
->var
.bits_per_pixel
!= varInfo
->bits_per_pixel
||
592 visual
->var
.grayscale
!= varInfo
->grayscale
||
593 visual
->var
.red
.offset
!= varInfo
->red
.offset
||
594 visual
->var
.green
.offset
!= varInfo
->green
.offset
||
595 visual
->var
.blue
.offset
!= varInfo
->blue
.offset
||
596 visual
->var
.transp
.offset
!= varInfo
->transp
.offset
) {
597 /* visual mismatch! */
601 buf
= CALLOC_STRUCT(GLFBDevBufferRec
);
605 /* basic framebuffer setup */
606 _mesa_initialize_framebuffer(&buf
->glframebuffer
, &visual
->glvisual
);
607 /* add front renderbuffer */
608 frontrb
= new_glfbdev_renderbuffer(frontBuffer
, visual
->pixelFormat
);
609 _mesa_add_renderbuffer(&buf
->glframebuffer
, BUFFER_FRONT_LEFT
,
611 /* add back renderbuffer */
612 if (visual
->glvisual
.doubleBufferMode
) {
613 backrb
= new_glfbdev_renderbuffer(backBuffer
, visual
->pixelFormat
);
614 _mesa_add_renderbuffer(&buf
->glframebuffer
, BUFFER_BACK_LEFT
,
617 /* add software renderbuffers */
618 _mesa_add_soft_renderbuffers(&buf
->glframebuffer
,
619 GL_FALSE
, /* color */
620 visual
->glvisual
.haveDepthBuffer
,
621 visual
->glvisual
.haveStencilBuffer
,
622 visual
->glvisual
.haveAccumBuffer
,
623 GL_FALSE
, /* alpha */
624 GL_FALSE
/* aux bufs */);
628 buf
->fix
= *fixInfo
; /* struct assignment */
629 buf
->var
= *varInfo
; /* struct assignment */
630 buf
->visual
= visual
; /* ptr assignment */
632 buf
->bytesPerPixel
= visual
->var
.bits_per_pixel
/ 8;
633 frontrb
->rowStride
= visual
->var
.xres_virtual
* buf
->bytesPerPixel
;
634 frontrb
->bottom
= (GLubyte
*) frontrb
->Base
.Data
635 + (visual
->var
.yres_virtual
- 1) * frontrb
->rowStride
;
637 if (visual
->glvisual
.doubleBufferMode
) {
639 /* malloc a back buffer */
640 backrb
->Base
.Data
= _mesa_malloc(size
);
641 if (!backrb
->Base
.Data
) {
642 _mesa_free_framebuffer_data(&buf
->glframebuffer
);
646 backrb
->mallocedBuffer
= GL_TRUE
;
648 backrb
->rowStride
= frontrb
->rowStride
;
649 backrb
->bottom
= (GLubyte
*) backrb
->Base
.Data
650 + (visual
->var
.yres_virtual
- 1) * backrb
->rowStride
;
653 backrb
->bottom
= NULL
;
654 backrb
->rowStride
= 0;
662 glFBDevDestroyBuffer( GLFBDevBufferPtr buffer
)
665 /* check if destroying the current buffer */
666 GLFBDevBufferPtr curDraw
= glFBDevGetCurrentDrawBuffer();
667 GLFBDevBufferPtr curRead
= glFBDevGetCurrentReadBuffer();
668 if (buffer
== curDraw
|| buffer
== curRead
) {
669 glFBDevMakeCurrent( NULL
, NULL
, NULL
);
671 /* free the software depth, stencil, accum buffers */
672 _mesa_free_framebuffer_data(&buffer
->glframebuffer
);
679 glFBDevGetBufferAttrib( const GLFBDevBufferPtr buffer
, int attrib
)
688 glFBDevGetCurrentDrawBuffer( void )
690 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
692 return fbdevctx
->drawBuffer
;
699 glFBDevGetCurrentReadBuffer( void )
701 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
703 return fbdevctx
->readBuffer
;
710 glFBDevSwapBuffers( GLFBDevBufferPtr buffer
)
712 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
713 struct GLFBDevRenderbufferRec
*frontrb
= (struct GLFBDevRenderbufferRec
*)
714 buffer
->glframebuffer
.Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
715 struct GLFBDevRenderbufferRec
*backrb
= (struct GLFBDevRenderbufferRec
*)
716 buffer
->glframebuffer
.Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
718 if (!buffer
|| !buffer
->visual
->glvisual
.doubleBufferMode
)
721 /* check if swapping currently bound buffer */
722 if (fbdevctx
->drawBuffer
== buffer
) {
723 /* flush pending rendering */
724 _mesa_notifySwapBuffers(&fbdevctx
->glcontext
);
727 ASSERT(frontrb
->Base
.Data
);
728 ASSERT(backrb
->Base
.Data
);
729 _mesa_memcpy(frontrb
->Base
.Data
, backrb
->Base
.Data
, buffer
->size
);
734 glFBDevCreateContext( const GLFBDevVisualPtr visual
, GLFBDevContextPtr share
)
736 GLFBDevContextPtr ctx
;
738 struct dd_function_table functions
;
742 ctx
= CALLOC_STRUCT(GLFBDevContextRec
);
746 /* build table of device driver functions */
747 _mesa_init_driver_functions(&functions
);
748 functions
.GetString
= get_string
;
749 functions
.UpdateState
= update_state
;
750 functions
.GetBufferSize
= get_buffer_size
;
751 functions
.Viewport
= viewport
;
753 if (!_mesa_initialize_context(&ctx
->glcontext
, &visual
->glvisual
,
754 share
? &share
->glcontext
: NULL
,
755 &functions
, (void *) ctx
)) {
760 ctx
->visual
= visual
;
762 /* Create module contexts */
763 glctx
= (GLcontext
*) &ctx
->glcontext
;
764 _swrast_CreateContext( glctx
);
765 _ac_CreateContext( glctx
);
766 _tnl_CreateContext( glctx
);
767 _swsetup_CreateContext( glctx
);
768 _swsetup_Wakeup( glctx
);
772 struct swrast_device_driver
*swdd
;
773 swdd
= _swrast_GetDeviceDriverReference( glctx
);
774 swdd
->SetBuffer
= set_buffer
;
777 swdd
->WriteRGBASpan
= NULL
;
778 swdd
->WriteRGBSpan
= NULL
;
779 swdd
->WriteMonoRGBASpan
= NULL
;
780 swdd
->WriteRGBAPixels
= NULL
;
781 swdd
->WriteMonoRGBAPixels
= NULL
;
782 swdd
->ReadRGBASpan
= NULL
;
783 swdd
->ReadRGBAPixels
= NULL
;
786 /* use default TCL pipeline */
788 TNLcontext
*tnl
= TNL_CONTEXT(glctx
);
789 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
792 _mesa_enable_sw_extensions(glctx
);
799 glFBDevDestroyContext( GLFBDevContextPtr context
)
801 GLFBDevContextPtr fbdevctx
= glFBDevGetCurrentContext();
804 if (fbdevctx
== context
) {
805 /* destroying current context */
806 _mesa_make_current(NULL
, NULL
, NULL
);
807 _mesa_notifyDestroy(&context
->glcontext
);
809 _mesa_free_context_data(&context
->glcontext
);
816 glFBDevGetContextAttrib( const GLFBDevContextPtr context
, int attrib
)
825 glFBDevGetCurrentContext( void )
827 GET_CURRENT_CONTEXT(ctx
);
828 return (GLFBDevContextPtr
) ctx
;
833 glFBDevMakeCurrent( GLFBDevContextPtr context
,
834 GLFBDevBufferPtr drawBuffer
,
835 GLFBDevBufferPtr readBuffer
)
837 if (context
&& drawBuffer
&& readBuffer
) {
838 /* Make sure the context's visual and the buffers' visuals match.
839 * XXX we might do this by comparing specific fields like bits_per_pixel,
840 * visual, etc. in the future.
842 if (context
->visual
!= drawBuffer
->visual
||
843 context
->visual
!= readBuffer
->visual
) {
846 _mesa_make_current( &context
->glcontext
,
847 &drawBuffer
->glframebuffer
,
848 &readBuffer
->glframebuffer
);
849 context
->drawBuffer
= drawBuffer
;
850 context
->readBuffer
= readBuffer
;
851 context
->curBuffer
= drawBuffer
;
855 _mesa_make_current( NULL
, NULL
, NULL
);