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:
77
* Derived from Mesa's GLvisual class.
79
struct GLFBDevVisualRec {
80
GLvisual glvisual; /* base class */
81
struct fb_fix_screeninfo fix;
82
struct fb_var_screeninfo var;
87
* Derived from Mesa's GLframebuffer class.
89
struct GLFBDevBufferRec {
90
GLframebuffer glframebuffer; /* base class */
91
GLFBDevVisualPtr visual;
92
struct fb_fix_screeninfo fix;
93
struct fb_var_screeninfo var;
94
size_t size; /* color buffer size in bytes */
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;
110
* Derived from Mesa's gl_renderbuffer class.
112
struct GLFBDevRenderbufferRec {
113
struct gl_renderbuffer Base;
114
GLubyte *bottom; /* pointer to last row */
115
GLuint rowStride; /* in bytes */
116
GLboolean mallocedBuffer;
120
/**********************************************************************/
121
/* Internal device driver functions */
122
/**********************************************************************/
125
static const GLubyte *
126
get_string(GLcontext *ctx, GLenum pname)
131
return (const GLubyte *) "Mesa glfbdev";
139
update_state( GLcontext *ctx, GLuint new_state )
141
/* not much to do here - pass it on */
142
_swrast_InvalidateState( ctx, new_state );
143
_swsetup_InvalidateState( ctx, new_state );
144
_vbo_InvalidateState( ctx, new_state );
145
_tnl_InvalidateState( ctx, new_state );
150
get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
152
const GLFBDevBufferPtr fbdevbuffer = (GLFBDevBufferPtr) buffer;
153
*width = fbdevbuffer->var.xres;
154
*height = fbdevbuffer->var.yres;
159
* We only implement this function as a mechanism to check if the
160
* framebuffer size has changed (and update corresponding state).
163
viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
165
GLuint newWidth, newHeight;
166
GLframebuffer *buffer;
168
buffer = ctx->WinSysDrawBuffer;
169
get_buffer_size( buffer, &newWidth, &newHeight );
170
if (buffer->Width != newWidth || buffer->Height != newHeight) {
171
_mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
174
buffer = ctx->WinSysReadBuffer;
175
get_buffer_size( buffer, &newWidth, &newHeight );
176
if (buffer->Width != newWidth || buffer->Height != newHeight) {
177
_mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
183
* Generate code for span functions.
187
#define NAME(PREFIX) PREFIX##_B8G8R8
188
#define RB_TYPE GLubyte
190
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
191
#define INIT_PIXEL_PTR(P, X, Y) \
192
GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 3
193
#define INC_PIXEL_PTR(P) P += 3
194
#define STORE_PIXEL(DST, X, Y, VALUE) \
195
DST[0] = VALUE[BCOMP]; \
196
DST[1] = VALUE[GCOMP]; \
197
DST[2] = VALUE[RCOMP]
198
#define FETCH_PIXEL(DST, SRC) \
199
DST[RCOMP] = SRC[2]; \
200
DST[GCOMP] = SRC[1]; \
201
DST[BCOMP] = SRC[0]; \
202
DST[ACOMP] = CHAN_MAX
204
#include "swrast/s_spantemp.h"
208
#define NAME(PREFIX) PREFIX##_B8G8R8A8
209
#define RB_TYPE GLubyte
211
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
212
#define INIT_PIXEL_PTR(P, X, Y) \
213
GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 4
214
#define INC_PIXEL_PTR(P) P += 4
215
#define STORE_PIXEL(DST, X, Y, VALUE) \
216
DST[0] = VALUE[BCOMP]; \
217
DST[1] = VALUE[GCOMP]; \
218
DST[2] = VALUE[RCOMP]; \
219
DST[3] = VALUE[ACOMP]
220
#define FETCH_PIXEL(DST, SRC) \
221
DST[RCOMP] = SRC[2]; \
222
DST[GCOMP] = SRC[1]; \
223
DST[BCOMP] = SRC[0]; \
226
#include "swrast/s_spantemp.h"
229
/* 16-bit BGR (XXX implement dithering someday) */
230
#define NAME(PREFIX) PREFIX##_B5G6R5
231
#define RB_TYPE GLubyte
233
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
234
#define INIT_PIXEL_PTR(P, X, Y) \
235
GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
236
#define INC_PIXEL_PTR(P) P += 1
237
#define STORE_PIXEL(DST, X, Y, VALUE) \
238
DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
239
#define FETCH_PIXEL(DST, SRC) \
240
DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \
241
DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >> 5) & 0x3) ); \
242
DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
243
DST[ACOMP] = CHAN_MAX
245
#include "swrast/s_spantemp.h"
248
/* 15-bit BGR (XXX implement dithering someday) */
249
#define NAME(PREFIX) PREFIX##_B5G5R5
250
#define RB_TYPE GLubyte
252
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
253
#define INIT_PIXEL_PTR(P, X, Y) \
254
GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
255
#define INC_PIXEL_PTR(P) P += 1
256
#define STORE_PIXEL(DST, X, Y, VALUE) \
257
DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) )
258
#define FETCH_PIXEL(DST, SRC) \
259
DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \
260
DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >> 5) & 0x7) ); \
261
DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
262
DST[ACOMP] = CHAN_MAX
264
#include "swrast/s_spantemp.h"
267
/* 8-bit color index */
268
#define NAME(PREFIX) PREFIX##_CI8
270
#define RB_TYPE GLubyte
272
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
273
#define INIT_PIXEL_PTR(P, X, Y) \
274
GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X)
275
#define INC_PIXEL_PTR(P) P += 1
276
#define STORE_PIXEL(DST, X, Y, VALUE) \
278
#define FETCH_PIXEL(DST, SRC) \
281
#include "swrast/s_spantemp.h"
286
/**********************************************************************/
287
/* Public API functions */
288
/**********************************************************************/
292
glFBDevGetString( int str )
296
return "Mesa Project";
297
case GLFBDEV_VERSION:
306
glFBDevGetProcAddress( const char *procName )
308
struct name_address {
310
const GLFBDevProc func;
312
static const struct name_address functions[] = {
313
{ "glFBDevGetString", (GLFBDevProc) glFBDevGetString },
314
{ "glFBDevGetProcAddress", (GLFBDevProc) glFBDevGetProcAddress },
315
{ "glFBDevCreateVisual", (GLFBDevProc) glFBDevCreateVisual },
316
{ "glFBDevDestroyVisual", (GLFBDevProc) glFBDevDestroyVisual },
317
{ "glFBDevGetVisualAttrib", (GLFBDevProc) glFBDevGetVisualAttrib },
318
{ "glFBDevCreateBuffer", (GLFBDevProc) glFBDevCreateBuffer },
319
{ "glFBDevDestroyBuffer", (GLFBDevProc) glFBDevDestroyBuffer },
320
{ "glFBDevGetBufferAttrib", (GLFBDevProc) glFBDevGetBufferAttrib },
321
{ "glFBDevGetCurrentDrawBuffer", (GLFBDevProc) glFBDevGetCurrentDrawBuffer },
322
{ "glFBDevGetCurrentReadBuffer", (GLFBDevProc) glFBDevGetCurrentReadBuffer },
323
{ "glFBDevSwapBuffers", (GLFBDevProc) glFBDevSwapBuffers },
324
{ "glFBDevCreateContext", (GLFBDevProc) glFBDevCreateContext },
325
{ "glFBDevDestroyContext", (GLFBDevProc) glFBDevDestroyContext },
326
{ "glFBDevGetContextAttrib", (GLFBDevProc) glFBDevGetContextAttrib },
327
{ "glFBDevGetCurrentContext", (GLFBDevProc) glFBDevGetCurrentContext },
328
{ "glFBDevMakeCurrent", (GLFBDevProc) glFBDevMakeCurrent },
331
const struct name_address *entry;
332
for (entry = functions; entry->name; entry++) {
333
if (_mesa_strcmp(entry->name, procName) == 0) {
337
return _glapi_get_proc_address(procName);
342
glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
343
const struct fb_var_screeninfo *varInfo,
346
GLFBDevVisualPtr vis;
348
GLboolean rgbFlag = GL_TRUE, dbFlag = GL_FALSE, stereoFlag = GL_FALSE;
349
GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits = 0;
350
GLint indexBits = 0, depthBits = 0, stencilBits = 0;
351
GLint accumRedBits = 0, accumGreenBits = 0;
352
GLint accumBlueBits = 0, accumAlphaBits = 0;
353
GLint numSamples = 0;
358
vis = CALLOC_STRUCT(GLFBDevVisualRec);
362
vis->fix = *fixInfo; /* struct assignment */
363
vis->var = *varInfo; /* struct assignment */
365
for (attrib = attribs; attrib && *attrib != GLFBDEV_NONE; attrib++) {
367
case GLFBDEV_DOUBLE_BUFFER:
370
case GLFBDEV_COLOR_INDEX:
373
case GLFBDEV_DEPTH_SIZE:
374
depthBits = attrib[1];
377
case GLFBDEV_STENCIL_SIZE:
378
stencilBits = attrib[1];
381
case GLFBDEV_ACCUM_SIZE:
382
accumRedBits = accumGreenBits = accumBlueBits = accumAlphaBits
387
/* ignored for now */
389
case GLFBDEV_MULTISAMPLE:
390
numSamples = attrib[1];
394
/* unexpected token */
401
redBits = varInfo->red.length;
402
greenBits = varInfo->green.length;
403
blueBits = varInfo->blue.length;
404
alphaBits = varInfo->transp.length;
406
if (fixInfo->visual == FB_VISUAL_TRUECOLOR ||
407
fixInfo->visual == FB_VISUAL_DIRECTCOLOR) {
408
if (varInfo->bits_per_pixel == 24
409
&& varInfo->red.offset == 16
410
&& varInfo->green.offset == 8
411
&& varInfo->blue.offset == 0) {
412
vis->pixelFormat = PF_B8G8R8;
414
else if (varInfo->bits_per_pixel == 32
415
&& varInfo->red.offset == 16
416
&& varInfo->green.offset == 8
417
&& varInfo->blue.offset == 0) {
418
vis->pixelFormat = PF_B8G8R8A8;
420
else if (varInfo->bits_per_pixel == 16
421
&& varInfo->red.offset == 11
422
&& varInfo->green.offset == 5
423
&& varInfo->blue.offset == 0) {
424
vis->pixelFormat = PF_B5G6R5;
426
else if (varInfo->bits_per_pixel == 16
427
&& varInfo->red.offset == 10
428
&& varInfo->green.offset == 5
429
&& varInfo->blue.offset == 0) {
430
vis->pixelFormat = PF_B5G5R5;
433
_mesa_problem(NULL, "Unsupported fbdev RGB visual/bitdepth!\n");
440
indexBits = varInfo->bits_per_pixel;
441
if ((fixInfo->visual == FB_VISUAL_PSEUDOCOLOR ||
442
fixInfo->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
443
&& varInfo->bits_per_pixel == 8) {
444
vis->pixelFormat = PF_CI8;
447
_mesa_problem(NULL, "Unsupported fbdev CI visual/bitdepth!\n");
453
if (!_mesa_initialize_visual(&vis->glvisual, rgbFlag, dbFlag, stereoFlag,
454
redBits, greenBits, blueBits, alphaBits,
455
indexBits, depthBits, stencilBits,
456
accumRedBits, accumGreenBits,
457
accumBlueBits, accumAlphaBits,
459
/* something was invalid */
469
glFBDevDestroyVisual( GLFBDevVisualPtr visual )
477
glFBDevGetVisualAttrib( const GLFBDevVisualPtr visual, int attrib)
487
delete_renderbuffer(struct gl_renderbuffer *rb)
489
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
490
if (frb->mallocedBuffer) {
491
_mesa_free(frb->Base.Data);
498
renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
499
GLenum internalFormat, GLuint width, GLuint height)
501
/* no-op: the renderbuffer storage is allocated just once when it's
502
* created. Never resized or reallocated.
508
static struct GLFBDevRenderbufferRec *
509
new_glfbdev_renderbuffer(void *bufferStart, const GLFBDevVisualPtr visual)
511
struct GLFBDevRenderbufferRec *rb = CALLOC_STRUCT(GLFBDevRenderbufferRec);
514
int pixelFormat = visual->pixelFormat;
516
_mesa_init_renderbuffer(&rb->Base, name);
518
rb->Base.Delete = delete_renderbuffer;
519
rb->Base.AllocStorage = renderbuffer_storage;
521
if (pixelFormat == PF_B8G8R8) {
522
rb->Base.GetRow = get_row_B8G8R8;
523
rb->Base.GetValues = get_values_B8G8R8;
524
rb->Base.PutRow = put_row_B8G8R8;
525
rb->Base.PutRowRGB = put_row_rgb_B8G8R8;
526
rb->Base.PutMonoRow = put_mono_row_B8G8R8;
527
rb->Base.PutValues = put_values_B8G8R8;
528
rb->Base.PutMonoValues = put_mono_values_B8G8R8;
530
else if (pixelFormat == PF_B8G8R8A8) {
531
rb->Base.GetRow = get_row_B8G8R8A8;
532
rb->Base.GetValues = get_values_B8G8R8A8;
533
rb->Base.PutRow = put_row_B8G8R8A8;
534
rb->Base.PutRowRGB = put_row_rgb_B8G8R8A8;
535
rb->Base.PutMonoRow = put_mono_row_B8G8R8A8;
536
rb->Base.PutValues = put_values_B8G8R8A8;
537
rb->Base.PutMonoValues = put_mono_values_B8G8R8A8;
539
else if (pixelFormat == PF_B5G6R5) {
540
rb->Base.GetRow = get_row_B5G6R5;
541
rb->Base.GetValues = get_values_B5G6R5;
542
rb->Base.PutRow = put_row_B5G6R5;
543
rb->Base.PutRowRGB = put_row_rgb_B5G6R5;
544
rb->Base.PutMonoRow = put_mono_row_B5G6R5;
545
rb->Base.PutValues = put_values_B5G6R5;
546
rb->Base.PutMonoValues = put_mono_values_B5G6R5;
548
else if (pixelFormat == PF_B5G5R5) {
549
rb->Base.GetRow = get_row_B5G5R5;
550
rb->Base.GetValues = get_values_B5G5R5;
551
rb->Base.PutRow = put_row_B5G5R5;
552
rb->Base.PutRowRGB = put_row_rgb_B5G5R5;
553
rb->Base.PutMonoRow = put_mono_row_B5G5R5;
554
rb->Base.PutValues = put_values_B5G5R5;
555
rb->Base.PutMonoValues = put_mono_values_B5G5R5;
557
else if (pixelFormat == PF_CI8) {
558
rb->Base.GetRow = get_row_CI8;
559
rb->Base.GetValues = get_values_CI8;
560
rb->Base.PutRow = put_row_CI8;
561
rb->Base.PutMonoRow = put_mono_row_CI8;
562
rb->Base.PutValues = put_values_CI8;
563
rb->Base.PutMonoValues = put_mono_values_CI8;
566
if (pixelFormat == PF_CI8) {
567
rb->Base.InternalFormat = GL_COLOR_INDEX8_EXT;
568
rb->Base._BaseFormat = GL_COLOR_INDEX;
571
rb->Base.InternalFormat = GL_RGBA;
572
rb->Base._BaseFormat = GL_RGBA;
574
rb->Base.DataType = GL_UNSIGNED_BYTE;
575
rb->Base.Data = bufferStart;
577
rb->rowStride = visual->var.xres_virtual * visual->var.bits_per_pixel / 8;
578
rb->bottom = (GLubyte *) bufferStart
579
+ (visual->var.yres - 1) * rb->rowStride;
581
rb->Base.Width = visual->var.xres;
582
rb->Base.Height = visual->var.yres;
584
rb->Base.RedBits = visual->var.red.length;
585
rb->Base.GreenBits = visual->var.green.length;
586
rb->Base.BlueBits = visual->var.blue.length;
587
rb->Base.AlphaBits = visual->var.transp.length;
589
rb->Base.InternalFormat = pixelFormat;
595
glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
596
const struct fb_var_screeninfo *varInfo,
597
const GLFBDevVisualPtr visual,
598
void *frontBuffer, void *backBuffer, size_t size )
600
struct GLFBDevRenderbufferRec *frontrb, *backrb;
601
GLFBDevBufferPtr buf;
607
/* this is to update the visual if there was a resize and the
608
buffer is created again */
609
visual->var = *varInfo;
610
visual->fix = *fixInfo;
612
if (visual->fix.visual != fixInfo->visual ||
613
visual->fix.type != fixInfo->type ||
614
visual->var.bits_per_pixel != varInfo->bits_per_pixel ||
615
visual->var.grayscale != varInfo->grayscale ||
616
visual->var.red.offset != varInfo->red.offset ||
617
visual->var.green.offset != varInfo->green.offset ||
618
visual->var.blue.offset != varInfo->blue.offset ||
619
visual->var.transp.offset != varInfo->transp.offset) {
620
/* visual mismatch! */
624
buf = CALLOC_STRUCT(GLFBDevBufferRec);
628
/* basic framebuffer setup */
629
_mesa_initialize_framebuffer(&buf->glframebuffer, &visual->glvisual);
630
/* add front renderbuffer */
631
frontrb = new_glfbdev_renderbuffer(frontBuffer, visual);
632
_mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_FRONT_LEFT,
634
/* add back renderbuffer */
635
if (visual->glvisual.doubleBufferMode) {
636
const int malloced = !backBuffer;
638
/* malloc a back buffer */
639
backBuffer = _mesa_malloc(size);
641
_mesa_free_framebuffer_data(&buf->glframebuffer);
647
backrb = new_glfbdev_renderbuffer(backBuffer, visual);
652
backrb->mallocedBuffer = malloced;
654
_mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_BACK_LEFT,
657
/* add software renderbuffers */
658
_mesa_add_soft_renderbuffers(&buf->glframebuffer,
659
GL_FALSE, /* color */
660
visual->glvisual.haveDepthBuffer,
661
visual->glvisual.haveStencilBuffer,
662
visual->glvisual.haveAccumBuffer,
663
GL_FALSE, /* alpha */
664
GL_FALSE /* aux bufs */);
666
buf->fix = *fixInfo; /* struct assignment */
667
buf->var = *varInfo; /* struct assignment */
668
buf->visual = visual; /* ptr assignment */
670
buf->bytesPerPixel = visual->var.bits_per_pixel / 8;
677
glFBDevDestroyBuffer( GLFBDevBufferPtr buffer )
680
/* check if destroying the current buffer */
681
GLFBDevBufferPtr curDraw = glFBDevGetCurrentDrawBuffer();
682
GLFBDevBufferPtr curRead = glFBDevGetCurrentReadBuffer();
683
if (buffer == curDraw || buffer == curRead) {
684
glFBDevMakeCurrent( NULL, NULL, NULL);
687
struct gl_framebuffer *fb = &buffer->glframebuffer;
688
_mesa_unreference_framebuffer(&fb);
695
glFBDevGetBufferAttrib( const GLFBDevBufferPtr buffer, int attrib)
704
glFBDevGetCurrentDrawBuffer( void )
706
GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
708
return fbdevctx->drawBuffer;
715
glFBDevGetCurrentReadBuffer( void )
717
GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
719
return fbdevctx->readBuffer;
726
glFBDevSwapBuffers( GLFBDevBufferPtr buffer )
728
GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
729
struct GLFBDevRenderbufferRec *frontrb = (struct GLFBDevRenderbufferRec *)
730
buffer->glframebuffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
731
struct GLFBDevRenderbufferRec *backrb = (struct GLFBDevRenderbufferRec *)
732
buffer->glframebuffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
734
if (!buffer || !buffer->visual->glvisual.doubleBufferMode)
737
/* check if swapping currently bound buffer */
738
if (fbdevctx->drawBuffer == buffer) {
739
/* flush pending rendering */
740
_mesa_notifySwapBuffers(&fbdevctx->glcontext);
743
ASSERT(frontrb->Base.Data);
744
ASSERT(backrb->Base.Data);
745
_mesa_memcpy(frontrb->Base.Data, backrb->Base.Data, buffer->size);
750
glFBDevCreateContext( const GLFBDevVisualPtr visual, GLFBDevContextPtr share )
752
GLFBDevContextPtr ctx;
754
struct dd_function_table functions;
758
ctx = CALLOC_STRUCT(GLFBDevContextRec);
762
/* build table of device driver functions */
763
_mesa_init_driver_functions(&functions);
764
functions.GetString = get_string;
765
functions.UpdateState = update_state;
766
functions.GetBufferSize = get_buffer_size;
767
functions.Viewport = viewport;
769
if (!_mesa_initialize_context(&ctx->glcontext, &visual->glvisual,
770
share ? &share->glcontext : NULL,
771
&functions, (void *) ctx)) {
776
ctx->visual = visual;
778
/* Create module contexts */
779
glctx = (GLcontext *) &ctx->glcontext;
780
_swrast_CreateContext( glctx );
781
_vbo_CreateContext( glctx );
782
_tnl_CreateContext( glctx );
783
_swsetup_CreateContext( glctx );
784
_swsetup_Wakeup( glctx );
786
/* use default TCL pipeline */
788
TNLcontext *tnl = TNL_CONTEXT(glctx);
789
tnl->Driver.RunPipeline = _tnl_run_pipeline;
792
_mesa_enable_sw_extensions(glctx);
793
_mesa_enable_1_3_extensions(glctx);
794
_mesa_enable_1_4_extensions(glctx);
795
_mesa_enable_1_5_extensions(glctx);
796
_mesa_enable_2_0_extensions(glctx);
797
_mesa_enable_2_1_extensions(glctx);
804
glFBDevDestroyContext( GLFBDevContextPtr context )
806
GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
809
GLcontext *mesaCtx = &context->glcontext;
811
_swsetup_DestroyContext( mesaCtx );
812
_swrast_DestroyContext( mesaCtx );
813
_tnl_DestroyContext( mesaCtx );
814
_vbo_DestroyContext( mesaCtx );
816
if (fbdevctx == context) {
817
/* destroying current context */
818
_mesa_make_current(NULL, NULL, NULL);
820
_mesa_free_context_data(&context->glcontext);
827
glFBDevGetContextAttrib( const GLFBDevContextPtr context, int attrib)
836
glFBDevGetCurrentContext( void )
838
GET_CURRENT_CONTEXT(ctx);
839
return (GLFBDevContextPtr) ctx;
844
glFBDevMakeCurrent( GLFBDevContextPtr context,
845
GLFBDevBufferPtr drawBuffer,
846
GLFBDevBufferPtr readBuffer )
848
if (context && drawBuffer && readBuffer) {
849
/* Make sure the context's visual and the buffers' visuals match.
850
* XXX we might do this by comparing specific fields like bits_per_pixel,
851
* visual, etc. in the future.
853
if (context->visual != drawBuffer->visual ||
854
context->visual != readBuffer->visual) {
857
_mesa_make_current( &context->glcontext,
858
&drawBuffer->glframebuffer,
859
&readBuffer->glframebuffer );
860
context->drawBuffer = drawBuffer;
861
context->readBuffer = readBuffer;
862
context->curBuffer = drawBuffer;
866
_mesa_make_current( NULL, NULL, NULL );
872
#endif /* USE_GLFBDEV_DRIVER */