coverity check bug fix going over end of array
[mesa.git] / src / mesa / drivers / directfb / idirectfbgl_mesa.c
1 /*
2 * Copyright (C) 2004-2005 Claudio Ciccani <klan@users.sf.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 *
18 * Based on glfbdev.c, written by Brian Paul.
19 *
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25
26 #include <directfb.h>
27
28 #include <direct/messages.h>
29 #include <direct/interface.h>
30 #include <direct/mem.h>
31
32 #ifdef CLAMP
33 # undef CLAMP
34 #endif
35
36 #include "GL/directfbgl.h"
37 #include "glheader.h"
38 #include "buffers.h"
39 #include "context.h"
40 #include "extensions.h"
41 #include "framebuffer.h"
42 #include "renderbuffer.h"
43 #include "imports.h"
44 #include "texformat.h"
45 #include "teximage.h"
46 #include "texstore.h"
47 #include "array_cache/acache.h"
48 #include "swrast/swrast.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "tnl/tnl.h"
51 #include "tnl/t_context.h"
52 #include "tnl/t_pipeline.h"
53 #include "drivers/common/driverfuncs.h"
54
55
56 static DFBResult
57 Probe( void *data );
58
59 static DFBResult
60 Construct( IDirectFBGL *thiz,
61 IDirectFBSurface *surface );
62
63 #include <direct/interface_implementation.h>
64
65 DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBGL, Mesa )
66
67 /*
68 * private data struct of IDirectFBGL
69 */
70 typedef struct {
71 int ref; /* reference counter */
72
73 bool locked;
74
75 IDirectFBSurface *surface;
76 DFBSurfacePixelFormat format;
77 int width;
78 int height;
79
80 struct {
81 __u8 *start;
82 __u8 *end;
83 int pitch;
84 } video;
85
86 GLvisual visual;
87 GLframebuffer framebuffer;
88 GLcontext context;
89 struct gl_renderbuffer render;
90 } IDirectFBGL_data;
91
92
93 static bool dfb_mesa_setup_visual ( GLvisual *visual,
94 DFBSurfacePixelFormat format );
95 static bool dfb_mesa_create_context ( GLcontext *context,
96 GLframebuffer *framebuffer,
97 GLvisual *visual,
98 DFBSurfacePixelFormat format,
99 IDirectFBGL_data *data );
100 static void dfb_mesa_destroy_context( GLcontext *context,
101 GLframebuffer *framebuffer );
102
103
104 static void
105 IDirectFBGL_Destruct( IDirectFBGL *thiz )
106 {
107 IDirectFBGL_data *data = (IDirectFBGL_data*) thiz->priv;
108
109 dfb_mesa_destroy_context( &data->context, &data->framebuffer );
110
111 data->surface->Release( data->surface );
112
113 DIRECT_DEALLOCATE_INTERFACE( thiz );
114 }
115
116 static DFBResult
117 IDirectFBGL_AddRef( IDirectFBGL *thiz )
118 {
119 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
120
121 data->ref++;
122
123 return DFB_OK;
124 }
125
126 static DFBResult
127 IDirectFBGL_Release( IDirectFBGL *thiz )
128 {
129 DIRECT_INTERFACE_GET_DATA( IDirectFBGL )
130
131 if (--data->ref == 0) {
132 IDirectFBGL_Destruct( thiz );
133 }
134
135 return DFB_OK;
136 }
137
138 static DFBResult
139 IDirectFBGL_Lock( IDirectFBGL *thiz )
140 {
141 IDirectFBSurface *surface;
142 int width = 0;
143 int height = 0;
144 DFBResult err;
145
146 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
147
148 if (data->locked)
149 return DFB_LOCKED;
150
151 surface = data->surface;
152 surface->GetSize( surface, &width, &height );
153
154 err = surface->Lock( surface, DSLF_READ | DSLF_WRITE,
155 (void**) &data->video.start, &data->video.pitch );
156 if (err != DFB_OK) {
157 D_ERROR( "DirectFBGL/Mesa: couldn't lock surface.\n" );
158 return err;
159 }
160 data->video.end = data->video.start + (height-1) * data->video.pitch;
161
162 data->render.Data = data->video.start;
163
164 if (data->width != width || data->height != height) {
165 data->width = width;
166 data->height = height;
167 _mesa_ResizeBuffersMESA();
168 }
169
170 data->locked = true;
171
172 return DFB_OK;
173 }
174
175 static DFBResult
176 IDirectFBGL_Unlock( IDirectFBGL *thiz )
177 {
178 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
179
180 if (!data->locked)
181 return DFB_OK;
182
183 data->surface->Unlock( data->surface );
184 data->video.start = NULL;
185 data->video.end = NULL;
186
187 data->locked = false;
188
189 return DFB_OK;
190 }
191
192 static DFBResult
193 IDirectFBGL_GetAttributes( IDirectFBGL *thiz,
194 DFBGLAttributes *attributes )
195 {
196 GLvisual *visual;
197
198 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
199
200 if (!attributes)
201 return DFB_INVARG;
202
203 visual = &data->visual;
204
205 attributes->buffer_size = visual->rgbBits ? : visual->indexBits;
206 attributes->depth_size = visual->depthBits;
207 attributes->stencil_size = visual->stencilBits;
208 attributes->aux_buffers = visual->numAuxBuffers;
209 attributes->red_size = visual->redBits;
210 attributes->green_size = visual->greenBits;
211 attributes->blue_size = visual->blueBits;
212 attributes->alpha_size = visual->alphaBits;
213 attributes->accum_red_size = visual->accumRedBits;
214 attributes->accum_green_size = visual->accumGreenBits;
215 attributes->accum_blue_size = visual->accumBlueBits;
216 attributes->accum_alpha_size = visual->accumAlphaBits;
217 attributes->double_buffer = (visual->doubleBufferMode != 0);
218 attributes->stereo = (visual->stereoMode != 0);
219
220 return DFB_OK;
221 }
222
223
224 /* exported symbols */
225
226 static DFBResult
227 Probe( void *data )
228 {
229 return DFB_OK;
230 }
231
232 static DFBResult
233 Construct( IDirectFBGL *thiz,
234 IDirectFBSurface *surface )
235 {
236 /* Allocate interface data. */
237 DIRECT_ALLOCATE_INTERFACE_DATA( thiz, IDirectFBGL );
238
239 /* Initialize interface data. */
240 data->ref = 1;
241 data->surface = surface;
242
243 surface->AddRef( surface );
244 surface->GetPixelFormat( surface, &data->format );
245 surface->GetSize( surface, &data->width, &data->height );
246
247 /* Configure visual. */
248 if (!dfb_mesa_setup_visual( &data->visual, data->format )) {
249 D_ERROR( "DirectFBGL/Mesa: failed to initialize visual.\n" );
250 surface->Release( surface );
251 return DFB_UNSUPPORTED;
252 }
253
254 /* Create context. */
255 if (!dfb_mesa_create_context( &data->context, &data->framebuffer,
256 &data->visual, data->format, data )) {
257 D_ERROR( "DirectFBGL/Mesa: failed to create context.\n" );
258 surface->Release( surface );
259 return DFB_UNSUPPORTED;
260 }
261
262 /* Assign interface pointers. */
263 thiz->AddRef = IDirectFBGL_AddRef;
264 thiz->Release = IDirectFBGL_Release;
265 thiz->Lock = IDirectFBGL_Lock;
266 thiz->Unlock = IDirectFBGL_Unlock;
267 thiz->GetAttributes = IDirectFBGL_GetAttributes;
268
269 return DFB_OK;
270 }
271
272
273 /* internal functions */
274
275 static const GLubyte*
276 get_string( GLcontext *ctx, GLenum pname )
277 {
278 switch (pname) {
279 case GL_VENDOR:
280 return "Claudio Ciccani";
281 case GL_VERSION:
282 return "1.0";
283 default:
284 return NULL;
285 }
286 }
287
288 static void
289 update_state( GLcontext *ctx, GLuint new_state )
290 {
291 _swrast_InvalidateState( ctx, new_state );
292 _swsetup_InvalidateState( ctx, new_state );
293 _ac_InvalidateState( ctx, new_state );
294 _tnl_InvalidateState( ctx, new_state );
295 }
296
297 static void
298 get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
299 {
300 GLcontext *ctx = _mesa_get_current_context();
301 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
302
303 *width = (GLuint) data->width;
304 *height = (GLuint) data->height;
305 }
306
307 static void
308 set_viewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
309 {
310 _mesa_ResizeBuffersMESA();
311 }
312
313 /* required but not used */
314 static void
315 set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
316 {
317 return;
318 }
319
320 static void
321 delete_renderbuffer( struct gl_renderbuffer *render )
322 {
323 return;
324 }
325
326 static GLboolean
327 renderbuffer_storage( GLcontext *ctx, struct gl_renderbuffer *render,
328 GLenum internalFormat, GLuint width, GLuint height )
329 {
330 return GL_TRUE;
331 }
332
333
334 /* RGB332 */
335 #define NAME(PREFIX) PREFIX##_RGB332
336 #define FORMAT GL_RGBA8
337 #define SPAN_VARS \
338 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
339 #define INIT_PIXEL_PTR(P, X, Y) \
340 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X);
341 #define INC_PIXEL_PTR(P) P += 1
342 #define STORE_PIXEL(P, X, Y, S) \
343 *P = ( (((S[RCOMP]) & 0xe0)) | (((S[GCOMP]) & 0xe0) >> 3) | ((S[BCOMP]) >> 6) )
344 #define FETCH_PIXEL(D, P) \
345 D[RCOMP] = ((*P & 0xe0) ); \
346 D[GCOMP] = ((*P & 0x1c) << 3); \
347 D[BCOMP] = ((*P & 0x03) << 6); \
348 D[ACOMP] = 0xff
349
350 #include "swrast/s_spantemp.h"
351
352 /* ARGB1555 */
353 #define NAME(PREFIX) PREFIX##_ARGB1555
354 #define FORMAT GL_RGBA8
355 #define SPAN_VARS \
356 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
357 #define INIT_PIXEL_PTR(P, X, Y) \
358 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
359 #define INC_PIXEL_PTR(P) P += 1
360 #define STORE_PIXEL(P, X, Y, S) \
361 *P = ( (((S[RCOMP]) & 0xf8) << 7) | (((S[GCOMP]) & 0xf8) << 2) | ((S[BCOMP]) >> 3) )
362 #define FETCH_PIXEL(D, P) \
363 D[RCOMP] = ((*P & 0x7c00) >> 7); \
364 D[GCOMP] = ((*P & 0x03e0) >> 2); \
365 D[BCOMP] = ((*P & 0x001f) << 3); \
366 D[ACOMP] = ((*P & 0x8000) ? 0xff : 0)
367
368 #include "swrast/s_spantemp.h"
369
370 /* RGB16 */
371 #define NAME(PREFIX) PREFIX##_RGB16
372 #define FORMAT GL_RGBA8
373 #define SPAN_VARS \
374 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
375 #define INIT_PIXEL_PTR(P, X, Y) \
376 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
377 #define INC_PIXEL_PTR(P) P += 1
378 #define STORE_PIXEL(P, X, Y, S) \
379 *P = ( (((S[RCOMP]) & 0xf8) << 8) | (((S[GCOMP]) & 0xfc) << 3) | ((S[BCOMP]) >> 3) )
380 #define FETCH_PIXEL(D, P) \
381 D[RCOMP] = ((*P & 0xf800) >> 8); \
382 D[GCOMP] = ((*P & 0x07e0) >> 3); \
383 D[BCOMP] = ((*P & 0x001f) << 3); \
384 D[ACOMP] = 0xff
385
386 #include "swrast/s_spantemp.h"
387
388 /* RGB24 */
389 #define NAME(PREFIX) PREFIX##_RGB24
390 #define FORMAT GL_RGBA8
391 #define SPAN_VARS \
392 IDirectFBGL_data *data = ctx->DriverCtx;
393 #define INIT_PIXEL_PTR(P, X, Y) \
394 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X) * 3;
395 #define INC_PIXEL_PTR(P) P += 3
396 #define STORE_PIXEL(P, X, Y, S) \
397 P[0] = S[BCOMP]; P[1] = S[GCOMP]; P[2] = S[BCOMP]
398 #define FETCH_PIXEL(D, P) \
399 D[RCOMP] = P[2]; D[GCOMP] = P[1]; D[BCOMP] = P[0]; D[ACOMP] = 0xff
400
401 #include "swrast/s_spantemp.h"
402
403 /* RGB32 */
404 #define NAME(PREFIX) PREFIX##_RGB32
405 #define FORMAT GL_RGBA8
406 #define SPAN_VARS \
407 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
408 #define INIT_PIXEL_PTR(P, X, Y) \
409 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
410 #define INC_PIXEL_PTR(P) P += 1
411 #define STORE_PIXEL(P, X, Y, S) \
412 *P = ( ((S[RCOMP]) << 16) | ((S[GCOMP]) << 8) | (S[BCOMP]) )
413 #define FETCH_PIXEL(D, P) \
414 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
415 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
416 D[BCOMP] = ((*P & 0x000000ff) ); \
417 D[ACOMP] = 0xff
418
419 #include "swrast/s_spantemp.h"
420
421 /* ARGB */
422 #define NAME(PREFIX) PREFIX##_ARGB
423 #define FORMAT GL_RGBA8
424 #define SPAN_VARS \
425 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
426 #define INIT_PIXEL_PTR(P, X, Y) \
427 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
428 #define INC_PIXEL_PTR(P) P += 1
429 #define STORE_PIXEL_RGB(P, X, Y, S) \
430 *P = ( 0xff000000 | ((S[RCOMP]) << 16) | ((S[GCOMP]) << 8) | (S[BCOMP]) )
431 #define STORE_PIXEL(P, X, Y, S) \
432 *P = ( ((S[ACOMP]) << 24) | ((S[RCOMP]) << 16) | ((S[GCOMP]) << 8) | (S[BCOMP]) )
433 #define FETCH_PIXEL(D, P) \
434 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
435 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
436 D[BCOMP] = ((*P & 0x000000ff) ); \
437 D[ACOMP] = ((*P & 0xff000000) >> 24)
438
439 #include "swrast/s_spantemp.h"
440
441 /* AiRGB */
442 #define NAME(PREFIX) PREFIX##_AiRGB
443 #define FORMAT GL_RGBA8
444 #define SPAN_VARS \
445 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
446 #define INIT_PIXEL_PTR(P, X, Y) \
447 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
448 #define INC_PIXEL_PTR(P) P += 1
449 #define STORE_PIXEL_RGB(P, X, Y, S) \
450 *P = ( ((S[RCOMP]) << 16) | ((S[GCOMP]) << 8) | (S[BCOMP]) )
451 #define STORE_PIXEL(P, X, Y, S) \
452 *P = ( ((0xff - (S[ACOMP])) << 24) | ((S[RCOMP]) << 16) | ((S[GCOMP]) << 8) | (S[BCOMP]) )
453 #define FETCH_PIXEL(D, P) \
454 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
455 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
456 D[BCOMP] = ((*P & 0x000000ff) ); \
457 D[ACOMP] = (0xff - ((*P & 0xff000000) >> 24))
458
459 #include "swrast/s_spantemp.h"
460
461
462 static bool
463 dfb_mesa_setup_visual( GLvisual *visual,
464 DFBSurfacePixelFormat format )
465 {
466 GLboolean rgbFlag = GL_TRUE;
467 GLboolean dbFlag = GL_FALSE;
468 GLboolean stereoFlag = GL_FALSE;
469 GLint redBits = 0;
470 GLint blueBits = 0;
471 GLint greenBits = 0;
472 GLint alphaBits = 0;
473 GLint indexBits = 0;
474 GLint depthBits = 0;
475 GLint stencilBits = 0;
476 GLint accumRedBits = 0;
477 GLint accumGreenBits = 0;
478 GLint accumBlueBits = 0;
479 GLint accumAlphaBits = 0;
480 GLint numSamples = 0;
481
482 /* FIXME: LUT8 support. */
483 switch (format) {
484 case DSPF_RGB332:
485 redBits = 3;
486 greenBits = 3;
487 blueBits = 2;
488 break;
489 case DSPF_ARGB1555:
490 redBits = 5;
491 greenBits = 5;
492 blueBits = 5;
493 alphaBits = 1;
494 break;
495 case DSPF_RGB16:
496 redBits = 5;
497 greenBits = 6;
498 blueBits = 5;
499 break;
500 case DSPF_ARGB:
501 case DSPF_AiRGB:
502 alphaBits = 8;
503 case DSPF_RGB24:
504 case DSPF_RGB32:
505 redBits = 8;
506 greenBits = 8;
507 blueBits = 8;
508 break;
509 default:
510 D_WARN( "unsupported pixelformat" );
511 return false;
512 }
513
514 if (rgbFlag) {
515 accumRedBits = redBits;
516 accumGreenBits = greenBits;
517 accumBlueBits = blueBits;
518 accumAlphaBits = alphaBits;
519 depthBits = redBits + greenBits + blueBits;
520 stencilBits = alphaBits;
521 } else
522 depthBits = 8;
523
524 return _mesa_initialize_visual( visual,
525 rgbFlag, dbFlag, stereoFlag,
526 redBits, greenBits, blueBits, alphaBits,
527 indexBits, depthBits, stencilBits,
528 accumRedBits, accumGreenBits,
529 accumBlueBits, accumAlphaBits,
530 numSamples );
531 }
532
533 static bool
534 dfb_mesa_create_context( GLcontext *context,
535 GLframebuffer *framebuffer,
536 GLvisual *visual,
537 DFBSurfacePixelFormat format,
538 IDirectFBGL_data *data )
539 {
540 struct dd_function_table functions;
541 struct swrast_device_driver *swdd;
542
543 _mesa_initialize_framebuffer( framebuffer, visual );
544
545 _mesa_init_driver_functions( &functions );
546 functions.GetString = get_string;
547 functions.UpdateState = update_state;
548 functions.GetBufferSize = get_buffer_size;
549 functions.Viewport = set_viewport;
550
551 if (!_mesa_initialize_context( context, visual, NULL,
552 &functions, (void*) data )) {
553 D_DEBUG( "DirectFBGL/Mesa: _mesa_initialize_context() failed.\n" );
554 _mesa_free_framebuffer_data( framebuffer );
555 return false;
556 }
557
558 _swrast_CreateContext( context );
559 _ac_CreateContext( context );
560 _tnl_CreateContext( context );
561 _swsetup_CreateContext( context );
562 _swsetup_Wakeup( context );
563
564 swdd = _swrast_GetDeviceDriverReference( context );
565 swdd->SetBuffer = set_buffer;
566
567 _mesa_init_renderbuffer( &data->render, 0 );
568 data->render.InternalFormat = GL_RGBA;
569 data->render._BaseFormat = GL_RGBA;
570 data->render.DataType = GL_UNSIGNED_BYTE;
571 data->render.Data = data->video.start;
572 data->render.Delete = delete_renderbuffer;
573 data->render.AllocStorage = renderbuffer_storage;
574
575 switch (format) {
576 case DSPF_RGB332:
577 data->render.GetRow = get_row_RGB332;
578 data->render.GetValues = get_values_RGB332;
579 data->render.PutRow = put_row_RGB332;
580 data->render.PutMonoRow = put_mono_row_RGB332;
581 data->render.PutValues = put_values_RGB332;
582 data->render.PutMonoValues = put_mono_values_RGB332;
583 break;
584 case DSPF_ARGB1555:
585 data->render.GetRow = get_row_ARGB1555;
586 data->render.GetValues = get_values_ARGB1555;
587 data->render.PutRow = put_row_ARGB1555;
588 data->render.PutMonoRow = put_mono_row_ARGB1555;
589 data->render.PutValues = put_values_ARGB1555;
590 data->render.PutMonoValues = put_mono_values_ARGB1555;
591 break;
592 case DSPF_RGB16:
593 data->render.GetRow = get_row_RGB16;
594 data->render.GetValues = get_values_RGB16;
595 data->render.PutRow = put_row_RGB16;
596 data->render.PutMonoRow = put_mono_row_RGB16;
597 data->render.PutValues = put_values_RGB16;
598 data->render.PutMonoValues = put_mono_values_RGB16;
599 break;
600 case DSPF_RGB24:
601 data->render.GetRow = get_row_RGB24;
602 data->render.GetValues = get_values_RGB24;
603 data->render.PutRow = put_row_RGB24;
604 data->render.PutMonoRow = put_mono_row_RGB24;
605 data->render.PutValues = put_values_RGB24;
606 data->render.PutMonoValues = put_mono_values_RGB24;
607 break;
608 case DSPF_RGB32:
609 data->render.GetRow = get_row_RGB32;
610 data->render.GetValues = get_values_RGB32;
611 data->render.PutRow = put_row_RGB32;
612 data->render.PutMonoRow = put_mono_row_RGB32;
613 data->render.PutValues = put_values_RGB32;
614 data->render.PutMonoValues = put_mono_values_RGB32;
615 break;
616 case DSPF_ARGB:
617 data->render.GetRow = get_row_ARGB;
618 data->render.GetValues = get_values_ARGB;
619 data->render.PutRow = put_row_ARGB;
620 data->render.PutMonoRow = put_mono_row_ARGB;
621 data->render.PutValues = put_values_ARGB;
622 data->render.PutMonoValues = put_mono_values_ARGB;
623 break;
624 case DSPF_AiRGB:
625 data->render.GetRow = get_row_AiRGB;
626 data->render.GetValues = get_values_AiRGB;
627 data->render.PutRow = put_row_AiRGB;
628 data->render.PutMonoRow = put_mono_row_AiRGB;
629 data->render.PutValues = put_values_AiRGB;
630 data->render.PutMonoValues = put_mono_values_AiRGB;
631 break;
632 default:
633 D_BUG( "unexpected pixelformat" );
634 return false;
635 }
636
637 _mesa_add_renderbuffer( framebuffer, BUFFER_FRONT_LEFT, &data->render );
638
639 _mesa_add_soft_renderbuffers( framebuffer,
640 GL_FALSE,
641 visual->haveDepthBuffer,
642 visual->haveStencilBuffer,
643 visual->haveAccumBuffer,
644 GL_FALSE,
645 GL_FALSE );
646
647 TNL_CONTEXT( context )->Driver.RunPipeline = _tnl_run_pipeline;
648
649 _mesa_enable_sw_extensions( context );
650
651 _mesa_make_current( context, framebuffer, framebuffer );
652
653 return true;
654 }
655
656 static void
657 dfb_mesa_destroy_context( GLcontext *context,
658 GLframebuffer *framebuffer )
659 {
660 _mesa_make_current( NULL, NULL, NULL );
661 _mesa_free_framebuffer_data( framebuffer );
662 _mesa_notifyDestroy( context );
663 _mesa_free_context_data( context );
664 }
665