Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / beos / GLView.cpp
1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.1
4  * 
5  * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
6  * 
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:
13  * 
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  * 
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.
23  */
24
25
26 #include <assert.h>
27 #include <stdio.h>
28
29 extern "C" {
30
31 #include "glheader.h"
32 #include "version.h"
33 #include "buffers.h"
34 #include "bufferobj.h"
35 #include "context.h"
36 #include "colormac.h"
37 #include "depth.h"
38 #include "extensions.h"
39 #include "macros.h"
40 #include "matrix.h"
41 #include "mtypes.h"
42 #include "texformat.h"
43 #include "texobj.h"
44 #include "teximage.h"
45 #include "texstore.h"
46 #include "vbo/vbo.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "swrast/s_context.h"
50 #include "swrast/s_depth.h"
51 #include "swrast/s_lines.h"
52 #include "swrast/s_triangle.h"
53 #include "tnl/tnl.h"
54 #include "tnl/t_context.h"
55 #include "tnl/t_pipeline.h"
56
57 #include "drivers/common/driverfuncs.h"
58
59 }       // extern "C"
60
61 #include <interface/Screen.h>
62 #include <GLView.h>
63
64 // BeOS component ordering for B_RGBA32 bitmap format
65 #if B_HOST_IS_LENDIAN
66         #define BE_RCOMP 2
67         #define BE_GCOMP 1
68         #define BE_BCOMP 0
69         #define BE_ACOMP 3
70
71         #define PACK_B_RGBA32(color) (color[BCOMP] | (color[GCOMP] << 8) | \
72                                                         (color[RCOMP] << 16) | (color[ACOMP] << 24))
73
74         #define PACK_B_RGB32(color) (color[BCOMP] | (color[GCOMP] << 8) | \
75                                                         (color[RCOMP] << 16) | 0xFF000000)
76 #else
77         // Big Endian B_RGBA32 bitmap format
78         #define BE_RCOMP 1
79         #define BE_GCOMP 2
80         #define BE_BCOMP 3
81         #define BE_ACOMP 0
82
83         #define PACK_B_RGBA32(color) (color[ACOMP] | (color[RCOMP] << 8) | \
84                                                         (color[GCOMP] << 16) | (color[BCOMP] << 24))
85
86         #define PACK_B_RGB32(color) ((color[RCOMP] << 8) | (color[GCOMP] << 16) | \
87                                                         (color[BCOMP] << 24) | 0xFF000000)
88 #endif
89
90 #define FLIP(coord) (LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y-(coord) - 1) 
91
92 const char * color_space_name(color_space space);
93
94 //
95 // This object hangs off of the BGLView object.  We have to use
96 // Be's BGLView class as-is to maintain binary compatibility (we
97 // can't add new members to it).  Instead we just put all our data
98 // in this class and use BGLVIew::m_gc to point to it.
99 //
100 class MesaDriver
101 {
102 friend class BGLView;
103 public:
104         MesaDriver();
105         ~MesaDriver();
106         
107         void            Init(BGLView * bglview, struct gl_context * c, struct gl_config * v, struct gl_framebuffer * b);
108
109         void            LockGL();
110         void            UnlockGL();
111         void            SwapBuffers() const;
112         status_t        CopyPixelsOut(BPoint source, BBitmap *dest);
113         status_t        CopyPixelsIn(BBitmap *source, BPoint dest);
114
115         void CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const;
116         void Draw(BRect updateRect) const;
117
118 private:
119         MesaDriver(const MesaDriver &rhs);  // copy constructor illegal
120         MesaDriver &operator=(const MesaDriver &rhs);  // assignment oper. illegal
121
122         struct gl_context *     m_glcontext;
123         struct gl_config *              m_glvisual;
124         struct gl_framebuffer * m_glframebuffer;
125
126         BGLView *               m_bglview;
127         BBitmap *               m_bitmap;
128
129         GLchan                  m_clear_color[4];  // buffer clear color
130         GLuint                  m_clear_index;      // buffer clear color index
131         GLint                   m_bottom;           // used for flipping Y coords
132         GLuint                  m_width;
133         GLuint                  m_height;
134         
135    // Mesa Device Driver callback functions
136    static void          UpdateState(struct gl_context *ctx, GLuint new_state);
137    static void          ClearIndex(struct gl_context *ctx, GLuint index);
138    static void          ClearColor(struct gl_context *ctx, const GLfloat color[4]);
139    static void          Clear(struct gl_context *ctx, GLbitfield mask,
140                                 GLboolean all, GLint x, GLint y,
141                                 GLint width, GLint height);
142    static void          ClearFront(struct gl_context *ctx, GLboolean all, GLint x, GLint y,
143                           GLint width, GLint height);
144    static void          ClearBack(struct gl_context *ctx, GLboolean all, GLint x, GLint y,
145                          GLint width, GLint height);
146    static void          Index(struct gl_context *ctx, GLuint index);
147    static void          Color(struct gl_context *ctx, GLubyte r, GLubyte g,
148                      GLubyte b, GLubyte a);
149    static void          SetBuffer(struct gl_context *ctx, struct gl_framebuffer *colorBuffer,
150                              GLenum mode);
151    static void          GetBufferSize(struct gl_framebuffer * framebuffer, GLuint *width,
152                              GLuint *height);
153    static void          Error(struct gl_context *ctx);
154    static const GLubyte *       GetString(struct gl_context *ctx, GLenum name);
155    static void          Viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h);
156
157    // Front-buffer functions
158    static void          WriteRGBASpanFront(const struct gl_context *ctx, GLuint n,
159                                   GLint x, GLint y,
160                                   CONST GLubyte rgba[][4],
161                                   const GLubyte mask[]);
162    static void          WriteRGBSpanFront(const struct gl_context *ctx, GLuint n,
163                                  GLint x, GLint y,
164                                  CONST GLubyte rgba[][3],
165                                  const GLubyte mask[]);
166    static void          WriteMonoRGBASpanFront(const struct gl_context *ctx, GLuint n,
167                                       GLint x, GLint y,
168                                       const GLchan color[4],
169                                       const GLubyte mask[]);
170    static void          WriteRGBAPixelsFront(const struct gl_context *ctx, GLuint n,
171                                     const GLint x[], const GLint y[],
172                                     CONST GLubyte rgba[][4],
173                                     const GLubyte mask[]);
174    static void          WriteMonoRGBAPixelsFront(const struct gl_context *ctx, GLuint n,
175                                         const GLint x[], const GLint y[],
176                                         const GLchan color[4],
177                                         const GLubyte mask[]);
178    static void          WriteCI32SpanFront(const struct gl_context *ctx, GLuint n,
179                                   GLint x, GLint y,
180                                   const GLuint index[], const GLubyte mask[]);
181    static void          WriteCI8SpanFront(const struct gl_context *ctx, GLuint n,
182                                  GLint x, GLint y,
183                                  const GLubyte index[], const GLubyte mask[]);
184    static void          WriteMonoCISpanFront(const struct gl_context *ctx, GLuint n,
185                                     GLint x, GLint y,
186                                     GLuint colorIndex, const GLubyte mask[]);
187    static void          WriteCI32PixelsFront(const struct gl_context *ctx,
188                                     GLuint n, const GLint x[], const GLint y[],
189                                     const GLuint index[], const GLubyte mask[]);
190    static void          WriteMonoCIPixelsFront(const struct gl_context *ctx, GLuint n,
191                                       const GLint x[], const GLint y[],
192                                       GLuint colorIndex, const GLubyte mask[]);
193    static void          ReadCI32SpanFront(const struct gl_context *ctx,
194                                  GLuint n, GLint x, GLint y, GLuint index[]);
195    static void          ReadRGBASpanFront(const struct gl_context *ctx, GLuint n,
196                                  GLint x, GLint y,
197                                  GLubyte rgba[][4]);
198    static void          ReadCI32PixelsFront(const struct gl_context *ctx,
199                                    GLuint n, const GLint x[], const GLint y[],
200                                    GLuint indx[], const GLubyte mask[]);
201    static void          ReadRGBAPixelsFront(const struct gl_context *ctx,
202                                    GLuint n, const GLint x[], const GLint y[],
203                                    GLubyte rgba[][4], const GLubyte mask[]);
204
205    // Back buffer functions
206    static void          WriteRGBASpanBack(const struct gl_context *ctx, GLuint n,
207                                   GLint x, GLint y,
208                                   CONST GLubyte rgba[][4],
209                                   const GLubyte mask[]);
210    static void          WriteRGBSpanBack(const struct gl_context *ctx, GLuint n,
211                                  GLint x, GLint y,
212                                  CONST GLubyte rgba[][3],
213                                  const GLubyte mask[]);
214    static void          WriteMonoRGBASpanBack(const struct gl_context *ctx, GLuint n,
215                                      GLint x, GLint y,
216                                      const GLchan color[4],
217                                      const GLubyte mask[]);
218    static void          WriteRGBAPixelsBack(const struct gl_context *ctx, GLuint n,
219                                    const GLint x[], const GLint y[],
220                                    CONST GLubyte rgba[][4],
221                                    const GLubyte mask[]);
222    static void          WriteMonoRGBAPixelsBack(const struct gl_context *ctx, GLuint n,
223                                        const GLint x[], const GLint y[],
224                                        const GLchan color[4],
225                                        const GLubyte mask[]);
226    static void          WriteCI32SpanBack(const struct gl_context *ctx, GLuint n,
227                                  GLint x, GLint y,
228                                  const GLuint index[], const GLubyte mask[]);
229    static void          WriteCI8SpanBack(const struct gl_context *ctx, GLuint n, GLint x, GLint y,
230                                 const GLubyte index[], const GLubyte mask[]);
231    static void          WriteMonoCISpanBack(const struct gl_context *ctx, GLuint n,
232                                    GLint x, GLint y, GLuint colorIndex,
233                                    const GLubyte mask[]);
234    static void          WriteCI32PixelsBack(const struct gl_context *ctx,
235                                    GLuint n, const GLint x[], const GLint y[],
236                                    const GLuint index[], const GLubyte mask[]);
237    static void          WriteMonoCIPixelsBack(const struct gl_context *ctx,
238                                      GLuint n, const GLint x[], const GLint y[],
239                                      GLuint colorIndex, const GLubyte mask[]);
240    static void          ReadCI32SpanBack(const struct gl_context *ctx,
241                                 GLuint n, GLint x, GLint y, GLuint index[]);
242    static void          ReadRGBASpanBack(const struct gl_context *ctx, GLuint n,
243                                 GLint x, GLint y,
244                                 GLubyte rgba[][4]);
245    static void          ReadCI32PixelsBack(const struct gl_context *ctx,
246                                   GLuint n, const GLint x[], const GLint y[],
247                                   GLuint indx[], const GLubyte mask[]);
248    static void          ReadRGBAPixelsBack(const struct gl_context *ctx,
249                                   GLuint n, const GLint x[], const GLint y[],
250                                   GLubyte rgba[][4], const GLubyte mask[]);
251
252 };
253
254 //------------------------------------------------------------------
255 // Public interface methods
256 //------------------------------------------------------------------
257
258
259 //
260 // Input:  rect - initial rectangle
261 //         name - window name
262 //         resizingMode - example: B_FOLLOW_NONE
263 //         mode - usually 0 ?
264 //         options - Bitwise-OR of BGL_* tokens
265 //
266 BGLView::BGLView(BRect rect, char *name,
267                  ulong resizingMode, ulong mode,
268                  ulong options)
269    : BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS) //  | B_FULL_UPDATE_ON_RESIZE)
270 {
271         // We don't support single buffering (yet): double buffering forced.
272         options |= BGL_DOUBLE;
273
274    const GLboolean rgbFlag = ((options & BGL_INDEX) == 0);
275    const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA);
276    const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE);
277    const GLboolean stereoFlag = false;
278    const GLint depth = (options & BGL_DEPTH) ? 16 : 0;
279    const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
280    const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
281    const GLint index = (options & BGL_INDEX) ? 32 : 0;
282    const GLint red = rgbFlag ? 8 : 0;
283    const GLint green = rgbFlag ? 8 : 0;
284    const GLint blue = rgbFlag ? 8 : 0;
285    const GLint alpha = alphaFlag ? 8 : 0;
286
287         m_options = options | BGL_INDIRECT;
288
289    struct dd_function_table functions;
290  
291    if (!rgbFlag) {
292       fprintf(stderr, "Mesa Warning: color index mode not supported\n");
293    }
294
295    // Allocate auxiliary data object
296    MesaDriver * md = new MesaDriver();
297
298    // examine option flags and create gl_context struct
299    struct gl_config * visual = _mesa_create_visual( dblFlag,
300                                             stereoFlag,
301                                             red, green, blue, alpha,
302                                             depth,
303                                             stencil,
304                                             accum, accum, accum, accum,
305                                             1
306                                             );
307
308         // Initialize device driver function table
309         _mesa_init_driver_functions(&functions);
310
311         functions.GetString     = md->GetString;
312         functions.UpdateState   = md->UpdateState;
313         functions.GetBufferSize = md->GetBufferSize;
314         functions.Clear                 = md->Clear;
315         functions.ClearIndex    = md->ClearIndex;
316         functions.ClearColor    = md->ClearColor;
317         functions.Error                 = md->Error;
318         functions.Viewport      = md->Viewport;
319
320         // create core context
321         struct gl_context *ctx = _mesa_create_context(API_OPENGL, visual,
322                                                       NULL, &functions, md);
323         if (! ctx) {
324          _mesa_destroy_visual(visual);
325          delete md;
326          return;
327       }
328    _mesa_enable_sw_extensions(ctx);
329    _mesa_enable_1_3_extensions(ctx);
330    _mesa_enable_1_4_extensions(ctx);
331    _mesa_enable_1_5_extensions(ctx);
332
333
334    // create core framebuffer
335    struct gl_framebuffer * buffer = _mesa_create_framebuffer(visual,
336                                               depth > 0 ? GL_TRUE : GL_FALSE,
337                                               stencil > 0 ? GL_TRUE: GL_FALSE,
338                                               accum > 0 ? GL_TRUE : GL_FALSE,
339                                               alphaFlag
340                                               );
341
342    /* Initialize the software rasterizer and helper modules.
343     */
344    _swrast_CreateContext(ctx);
345    _vbo_CreateContext(ctx);
346    _tnl_CreateContext(ctx);
347    _swsetup_CreateContext(ctx);
348    _swsetup_Wakeup(ctx);
349
350    md->Init(this, ctx, visual, buffer );
351
352    // Hook aux data into BGLView object
353    m_gc = md;
354
355    // some stupid applications (Quake2) don't even think about calling LockGL()
356    // before using glGetString and friends... so make sure there is at least a
357    // valid context.
358    if (!_mesa_get_current_context()) {
359       LockGL();
360       // not needed, we don't have a looper yet: UnlockLooper();
361    }
362
363 }
364
365
366 BGLView::~BGLView()
367 {
368    // printf("BGLView destructor\n");
369    MesaDriver * md = (MesaDriver *) m_gc;
370    assert(md);
371    delete md;
372 }
373
374 void BGLView::LockGL()
375 {
376    MesaDriver * md = (MesaDriver *) m_gc;
377    assert(md);
378    md->LockGL();
379 }
380
381 void BGLView::UnlockGL()
382 {
383    MesaDriver * md = (MesaDriver *) m_gc;
384    assert(md);
385    md->UnlockGL();
386 }
387
388 void BGLView::SwapBuffers()
389 {
390         SwapBuffers(false);
391 }
392
393 void BGLView::SwapBuffers(bool vSync)
394 {
395         MesaDriver * md = (MesaDriver *) m_gc;
396         assert(md);
397         md->SwapBuffers();
398
399         if (vSync) {
400                 BScreen screen(Window());
401                 screen.WaitForRetrace();
402         }
403 }
404
405
406 #if 0
407 void BGLView::CopySubBufferMESA(GLint x, GLint y, GLuint width, GLuint height)
408 {
409    MesaDriver * md = (MesaDriver *) m_gc;
410    assert(md);
411    md->CopySubBuffer(x, y, width, height);
412 }
413 #endif
414
415 BView * BGLView::EmbeddedView()
416 {
417         return NULL;
418 }
419
420 status_t BGLView::CopyPixelsOut(BPoint source, BBitmap *dest)
421 {
422         if (! dest || ! dest->Bounds().IsValid())
423                 return B_BAD_VALUE;
424
425         MesaDriver * md = (MesaDriver *) m_gc;
426         assert(md);
427         return md->CopyPixelsOut(source, dest);
428 }
429
430 status_t BGLView::CopyPixelsIn(BBitmap *source, BPoint dest)
431 {
432         if (! source || ! source->Bounds().IsValid())
433                 return B_BAD_VALUE;
434
435         MesaDriver * md = (MesaDriver *) m_gc;
436         assert(md);
437         return md->CopyPixelsIn(source, dest);
438 }
439
440
441 void BGLView::ErrorCallback(unsigned long errorCode) // Mesa's GLenum is not ulong but uint!
442 {
443         char msg[32];
444         sprintf(msg, "GL: Error code $%04lx.", errorCode);
445         // debugger(msg);
446         fprintf(stderr, "%s\n", msg);
447         return;
448 }
449
450 void BGLView::Draw(BRect updateRect)
451 {
452    // printf("BGLView::Draw()\n");
453    MesaDriver * md = (MesaDriver *) m_gc;
454    assert(md);
455    md->Draw(updateRect);
456 }
457
458 void BGLView::AttachedToWindow()
459 {
460    BView::AttachedToWindow();
461
462    // don't paint window background white when resized
463    SetViewColor(B_TRANSPARENT_32_BIT);
464 }
465
466 void BGLView::AllAttached()
467 {
468    BView::AllAttached();
469 //   printf("BGLView AllAttached\n");
470 }
471
472 void BGLView::DetachedFromWindow()
473 {
474    BView::DetachedFromWindow();
475 }
476
477 void BGLView::AllDetached()
478 {
479    BView::AllDetached();
480 //   printf("BGLView AllDetached");
481 }
482
483 void BGLView::FrameResized(float width, float height)
484 {
485    return BView::FrameResized(width, height);
486 }
487
488 status_t BGLView::Perform(perform_code d, void *arg)
489 {
490    return BView::Perform(d, arg);
491 }
492
493
494 status_t BGLView::Archive(BMessage *data, bool deep) const
495 {
496    return BView::Archive(data, deep);
497 }
498
499 void BGLView::MessageReceived(BMessage *msg)
500 {
501    BView::MessageReceived(msg);
502 }
503
504 void BGLView::SetResizingMode(uint32 mode)
505 {
506    BView::SetResizingMode(mode);
507 }
508
509 void BGLView::Show()
510 {
511    BView::Show();
512 }
513
514 void BGLView::Hide()
515 {
516    BView::Hide();
517 }
518
519 BHandler *BGLView::ResolveSpecifier(BMessage *msg, int32 index,
520                                     BMessage *specifier, int32 form,
521                                     const char *property)
522 {
523    return BView::ResolveSpecifier(msg, index, specifier, form, property);
524 }
525
526 status_t BGLView::GetSupportedSuites(BMessage *data)
527 {
528    return BView::GetSupportedSuites(data);
529 }
530
531 void BGLView::DirectConnected( direct_buffer_info *info )
532 {
533 #if 0
534         if (! m_direct_connected && m_direct_connection_disabled) 
535                 return; 
536
537         direct_info_locker->Lock(); 
538         switch(info->buffer_state & B_DIRECT_MODE_MASK) { 
539         case B_DIRECT_START: 
540                 m_direct_connected = true;
541         case B_DIRECT_MODIFY: 
542                 // Get clipping information 
543                 if (m_clip_list)
544                         free(m_clip_list); 
545                 m_clip_list_count = info->clip_list_count; 
546                 m_clip_list = (clipping_rect *) malloc(m_clip_list_count*sizeof(clipping_rect)); 
547                 if (m_clip_list) { 
548                         memcpy(m_clip_list, info->clip_list, m_clip_list_count*sizeof(clipping_rect));
549                         fBits = (uint8 *) info->bits; 
550                         fRowBytes = info->bytes_per_row; 
551                         fFormat = info->pixel_format; 
552                         fBounds = info->window_bounds; 
553                         fDirty = true; 
554                 } 
555                 break; 
556         case B_DIRECT_STOP: 
557                 fConnected = false; 
558                 break; 
559         } 
560         direct_info_locker->Unlock(); 
561 #endif
562 }
563
564 void BGLView::EnableDirectMode( bool enabled )
565 {
566    // TODO
567 }
568
569
570 //---- virtual reserved methods ----------
571
572 void BGLView::_ReservedGLView1() {}
573 void BGLView::_ReservedGLView2() {}
574 void BGLView::_ReservedGLView3() {}
575 void BGLView::_ReservedGLView4() {}
576 void BGLView::_ReservedGLView5() {}
577 void BGLView::_ReservedGLView6() {}
578 void BGLView::_ReservedGLView7() {}
579 void BGLView::_ReservedGLView8() {}
580
581 #if 0
582 // Not implemented!!!
583
584 BGLView::BGLView(const BGLView &v)
585         : BView(v)
586 {
587    // XXX not sure how this should work
588    printf("Warning BGLView::copy constructor not implemented\n");
589 }
590
591 BGLView &BGLView::operator=(const BGLView &v)
592 {
593    printf("Warning BGLView::operator= not implemented\n");
594         return *this;
595 }
596 #endif
597
598 void BGLView::dither_front()
599 {
600    // no-op
601 }
602
603 bool BGLView::confirm_dither()
604 {
605    // no-op
606    return false;
607 }
608
609 void BGLView::draw(BRect r)
610 {
611    // XXX no-op ???
612 }
613
614 /* Direct Window stuff */
615 void BGLView::drawScanline( int x1, int x2, int y, void *data )
616 {
617    // no-op
618 }
619
620 void BGLView::scanlineHandler(struct rasStateRec *state,
621                               GLint x1, GLint x2)
622 {
623    // no-op
624 }
625
626 void BGLView::lock_draw()
627 {
628    // no-op
629 }
630
631 void BGLView::unlock_draw()
632 {
633    // no-op
634 }
635
636 bool BGLView::validateView()
637 {
638    // no-op
639    return true;
640 }
641
642 // #pragma mark -
643
644 MesaDriver::MesaDriver()
645 {
646    m_glcontext          = NULL;
647    m_glvisual           = NULL;
648    m_glframebuffer      = NULL;
649    m_bglview            = NULL;
650    m_bitmap             = NULL;
651
652    m_clear_color[BE_RCOMP] = 0;
653    m_clear_color[BE_GCOMP] = 0;
654    m_clear_color[BE_BCOMP] = 0;
655    m_clear_color[BE_ACOMP] = 0;
656
657    m_clear_index = 0;
658 }
659
660
661 MesaDriver::~MesaDriver()
662 {
663    _mesa_destroy_visual(m_glvisual);
664    _mesa_destroy_framebuffer(m_glframebuffer);
665    _mesa_destroy_context(m_glcontext);
666    
667    delete m_bitmap;
668 }
669
670
671 void MesaDriver::Init(BGLView * bglview, struct gl_context * ctx, struct gl_config * visual, struct gl_framebuffer * framebuffer)
672 {
673         m_bglview               = bglview;
674         m_glcontext     = ctx;
675         m_glvisual              = visual;
676         m_glframebuffer = framebuffer;
677
678         MesaDriver * md = (MesaDriver *) ctx->DriverCtx;
679         struct swrast_device_driver * swdd = _swrast_GetDeviceDriverReference( ctx );
680         TNLcontext * tnl = TNL_CONTEXT(ctx);
681
682         assert(md->m_glcontext == ctx );
683         assert(tnl);
684         assert(swdd);
685
686         // Use default TCL pipeline
687         tnl->Driver.RunPipeline = _tnl_run_pipeline;
688  
689         swdd->SetBuffer = this->SetBuffer;
690 }
691
692
693 void MesaDriver::LockGL()
694 {
695         m_bglview->LockLooper();
696
697    UpdateState(m_glcontext, 0);
698    _mesa_make_current(m_glcontext, m_glframebuffer);
699 }
700
701
702 void MesaDriver::UnlockGL()
703 {
704         if (m_bglview->Looper()->IsLocked())
705                 m_bglview->UnlockLooper();
706    // Could call _mesa_make_current(NULL, NULL) but it would just
707    // hinder performance
708 }
709
710
711 void MesaDriver::SwapBuffers() const
712 {
713     _mesa_notifySwapBuffers(m_glcontext);
714
715         if (m_bitmap) {
716                 m_bglview->LockLooper();
717                 m_bglview->DrawBitmap(m_bitmap);
718                 m_bglview->UnlockLooper();
719         };
720 }
721
722
723 void MesaDriver::CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const
724 {
725    if (m_bitmap) {
726       // Source bitmap and view's bitmap are same size.
727       // Source and dest rectangle are the same.
728       // Note (x,y) = (0,0) is the lower-left corner, have to flip Y
729       BRect srcAndDest;
730       srcAndDest.left = x;
731       srcAndDest.right = x + width - 1;
732       srcAndDest.bottom = m_bottom - y;
733       srcAndDest.top = srcAndDest.bottom - height + 1;
734       m_bglview->DrawBitmap(m_bitmap, srcAndDest, srcAndDest);
735    }
736 }
737
738 status_t MesaDriver::CopyPixelsOut(BPoint location, BBitmap *bitmap)
739 {
740         color_space scs = m_bitmap->ColorSpace();
741         color_space dcs = bitmap->ColorSpace();
742
743         if (scs != dcs && (scs != B_RGBA32 || dcs != B_RGB32)) {
744                 printf("CopyPixelsOut(): incompatible color space: %s != %s\n",
745                         color_space_name(scs),
746                         color_space_name(dcs));
747                 return B_BAD_TYPE;
748         }
749         
750         // debugger("CopyPixelsOut()");
751         
752         BRect sr = m_bitmap->Bounds();
753         BRect dr = bitmap->Bounds();
754
755         sr = sr & dr.OffsetBySelf(location);
756         dr = sr.OffsetByCopy(-location.x, -location.y); 
757         
758         uint8 *ps = (uint8 *) m_bitmap->Bits();
759         uint8 *pd = (uint8 *) bitmap->Bits();
760         uint32 *s, *d;
761         uint32 y;
762         for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) {
763                 s = (uint32 *) (ps + y * m_bitmap->BytesPerRow());
764                 s += (uint32) sr.left;
765                 
766                 d = (uint32 *) (pd + (y + (uint32) (dr.top - sr.top)) * bitmap->BytesPerRow());
767                 d += (uint32) dr.left;
768                 
769                 memcpy(d, s, dr.IntegerWidth() * 4);
770         }
771         return B_OK;
772 }
773
774 status_t MesaDriver::CopyPixelsIn(BBitmap *bitmap, BPoint location)
775 {
776         color_space scs = bitmap->ColorSpace();
777         color_space dcs = m_bitmap->ColorSpace();
778
779         if (scs != dcs && (dcs != B_RGBA32 || scs != B_RGB32)) {
780                 printf("CopyPixelsIn(): incompatible color space: %s != %s\n",
781                         color_space_name(scs),
782                         color_space_name(dcs));
783                 return B_BAD_TYPE;
784         }
785         
786         // debugger("CopyPixelsIn()");
787
788         BRect sr = bitmap->Bounds();
789         BRect dr = m_bitmap->Bounds();
790
791         sr = sr & dr.OffsetBySelf(location);
792         dr = sr.OffsetByCopy(-location.x, -location.y); 
793         
794         uint8 *ps = (uint8 *) bitmap->Bits();
795         uint8 *pd = (uint8 *) m_bitmap->Bits();
796         uint32 *s, *d;
797         uint32 y;
798         for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) {
799                 s = (uint32 *) (ps + y * bitmap->BytesPerRow());
800                 s += (uint32) sr.left;
801                 
802                 d = (uint32 *) (pd + (y + (uint32) (dr.top - sr.top)) * m_bitmap->BytesPerRow());
803                 d += (uint32) dr.left;
804                 
805                 memcpy(d, s, dr.IntegerWidth() * 4);
806         }
807         return B_OK;
808 }
809
810
811 void MesaDriver::Draw(BRect updateRect) const
812 {
813    if (m_bitmap)
814       m_bglview->DrawBitmap(m_bitmap, updateRect, updateRect);
815 }
816
817
818 void MesaDriver::Error(struct gl_context *ctx)
819 {
820         MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
821         if (md && md->m_bglview)
822                 md->m_bglview->ErrorCallback((unsigned long) ctx->ErrorValue);
823 }
824
825 void MesaDriver::UpdateState( struct gl_context *ctx, GLuint new_state )
826 {
827         struct swrast_device_driver *   swdd = _swrast_GetDeviceDriverReference( ctx );
828
829         _swrast_InvalidateState( ctx, new_state );
830         _swsetup_InvalidateState( ctx, new_state );
831         _vbo_InvalidateState( ctx, new_state );
832         _tnl_InvalidateState( ctx, new_state );
833
834         if (ctx->Color.DrawBuffer[0] == GL_FRONT) {
835       /* read/write front buffer */
836       swdd->WriteRGBASpan = MesaDriver::WriteRGBASpanFront;
837       swdd->WriteRGBSpan = MesaDriver::WriteRGBSpanFront;
838       swdd->WriteRGBAPixels = MesaDriver::WriteRGBAPixelsFront;
839       swdd->WriteMonoRGBASpan = MesaDriver::WriteMonoRGBASpanFront;
840       swdd->WriteMonoRGBAPixels = MesaDriver::WriteMonoRGBAPixelsFront;
841       swdd->WriteCI32Span = MesaDriver::WriteCI32SpanFront;
842       swdd->WriteCI8Span = MesaDriver::WriteCI8SpanFront;
843       swdd->WriteMonoCISpan = MesaDriver::WriteMonoCISpanFront;
844       swdd->WriteCI32Pixels = MesaDriver::WriteCI32PixelsFront;
845       swdd->WriteMonoCIPixels = MesaDriver::WriteMonoCIPixelsFront;
846       swdd->ReadRGBASpan = MesaDriver::ReadRGBASpanFront;
847       swdd->ReadRGBAPixels = MesaDriver::ReadRGBAPixelsFront;
848       swdd->ReadCI32Span = MesaDriver::ReadCI32SpanFront;
849       swdd->ReadCI32Pixels = MesaDriver::ReadCI32PixelsFront;
850    }
851    else {
852       /* read/write back buffer */
853       swdd->WriteRGBASpan = MesaDriver::WriteRGBASpanBack;
854       swdd->WriteRGBSpan = MesaDriver::WriteRGBSpanBack;
855       swdd->WriteRGBAPixels = MesaDriver::WriteRGBAPixelsBack;
856       swdd->WriteMonoRGBASpan = MesaDriver::WriteMonoRGBASpanBack;
857       swdd->WriteMonoRGBAPixels = MesaDriver::WriteMonoRGBAPixelsBack;
858       swdd->WriteCI32Span = MesaDriver::WriteCI32SpanBack;
859       swdd->WriteCI8Span = MesaDriver::WriteCI8SpanBack;
860       swdd->WriteMonoCISpan = MesaDriver::WriteMonoCISpanBack;
861       swdd->WriteCI32Pixels = MesaDriver::WriteCI32PixelsBack;
862       swdd->WriteMonoCIPixels = MesaDriver::WriteMonoCIPixelsBack;
863       swdd->ReadRGBASpan = MesaDriver::ReadRGBASpanBack;
864       swdd->ReadRGBAPixels = MesaDriver::ReadRGBAPixelsBack;
865       swdd->ReadCI32Span = MesaDriver::ReadCI32SpanBack;
866       swdd->ReadCI32Pixels = MesaDriver::ReadCI32PixelsBack;
867     }
868 }
869
870
871 void MesaDriver::ClearIndex(struct gl_context *ctx, GLuint index)
872 {
873    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
874    md->m_clear_index = index;
875 }
876
877
878 void MesaDriver::ClearColor(struct gl_context *ctx, const GLfloat color[4])
879 {
880    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
881    CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_RCOMP], color[0]);
882    CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_GCOMP], color[1]);
883    CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_BCOMP], color[2]);
884    CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_ACOMP], color[3]); 
885    assert(md->m_bglview);
886 }
887
888
889 void MesaDriver::Clear(struct gl_context *ctx, GLbitfield mask,
890                                GLboolean all, GLint x, GLint y,
891                                GLint width, GLint height)
892 {
893    if (mask & DD_FRONT_LEFT_BIT)
894                 ClearFront(ctx, all, x, y, width, height);
895    if (mask & DD_BACK_LEFT_BIT)
896                 ClearBack(ctx, all, x, y, width, height);
897
898         mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
899         if (mask)
900                 _swrast_Clear( ctx, mask, all, x, y, width, height );
901
902    return;
903 }
904
905
906 void MesaDriver::ClearFront(struct gl_context *ctx,
907                          GLboolean all, GLint x, GLint y,
908                          GLint width, GLint height)
909 {
910    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
911    BGLView *bglview = md->m_bglview;
912    assert(bglview);
913
914    bglview->SetHighColor(md->m_clear_color[BE_RCOMP],
915                          md->m_clear_color[BE_GCOMP],
916                          md->m_clear_color[BE_BCOMP],
917                          md->m_clear_color[BE_ACOMP]);
918    bglview->SetLowColor(md->m_clear_color[BE_RCOMP],
919                         md->m_clear_color[BE_GCOMP],
920                         md->m_clear_color[BE_BCOMP],
921                         md->m_clear_color[BE_ACOMP]);
922    if (all) {
923       BRect b = bglview->Bounds();
924       bglview->FillRect(b);
925    }
926    else {
927       // XXX untested
928       BRect b;
929       b.left = x;
930       b.right = x + width;
931       b.bottom = md->m_height - y - 1;
932       b.top = b.bottom - height;
933       bglview->FillRect(b);
934    }
935
936    // restore drawing color
937 #if 0
938    bglview->SetHighColor(md->mColor[BE_RCOMP],
939                          md->mColor[BE_GCOMP],
940                          md->mColor[BE_BCOMP],
941                          md->mColor[BE_ACOMP]);
942    bglview->SetLowColor(md->mColor[BE_RCOMP],
943                         md->mColor[BE_GCOMP],
944                         md->mColor[BE_BCOMP],
945                         md->mColor[BE_ACOMP]);
946 #endif
947 }
948
949
950 void MesaDriver::ClearBack(struct gl_context *ctx,
951                         GLboolean all, GLint x, GLint y,
952                         GLint width, GLint height)
953 {
954    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
955    BGLView *bglview = md->m_bglview;
956    assert(bglview);
957    BBitmap *bitmap = md->m_bitmap;
958    assert(bitmap);
959    GLuint *start = (GLuint *) bitmap->Bits();
960    const GLuint *clearPixelPtr = (const GLuint *) md->m_clear_color;
961    const GLuint clearPixel = B_LENDIAN_TO_HOST_INT32(*clearPixelPtr);
962
963    if (all) {
964       const int numPixels = md->m_width * md->m_height;
965       if (clearPixel == 0) {
966          memset(start, 0, numPixels * 4);
967       }
968       else {
969          for (int i = 0; i < numPixels; i++) {
970              start[i] = clearPixel;
971          }
972       }
973    }
974    else {
975       // XXX untested
976       start += y * md->m_width + x;
977       for (int i = 0; i < height; i++) {
978          for (int j = 0; j < width; j++) {
979             start[j] = clearPixel;
980          }
981          start += md->m_width;
982       }
983    }
984 }
985
986
987 void MesaDriver::SetBuffer(struct gl_context *ctx, struct gl_framebuffer *buffer,
988                             GLenum mode)
989 {
990    /* TODO */
991         (void) ctx;
992         (void) buffer;
993         (void) mode;
994 }
995
996 void MesaDriver::GetBufferSize(struct gl_framebuffer * framebuffer, GLuint *width,
997                             GLuint *height)
998 {
999    GET_CURRENT_CONTEXT(ctx);
1000    if (!ctx)
1001                 return;
1002
1003    MesaDriver * md = (MesaDriver *) ctx->DriverCtx;
1004    BGLView *bglview = md->m_bglview;
1005    assert(bglview);
1006
1007    BRect b = bglview->Bounds();
1008    *width = (GLuint) b.IntegerWidth() + 1; // (b.right - b.left + 1);
1009    *height = (GLuint) b.IntegerHeight() + 1; // (b.bottom - b.top + 1);
1010    md->m_bottom = (GLint) b.bottom;
1011
1012    if (ctx->Visual.doubleBufferMode) {
1013       if (*width != md->m_width || *height != md->m_height) {
1014          // allocate new size of back buffer bitmap
1015          if (md->m_bitmap)
1016             delete md->m_bitmap;
1017          BRect rect(0.0, 0.0, *width - 1, *height - 1);
1018          md->m_bitmap = new BBitmap(rect, B_RGBA32);
1019       }
1020    }
1021    else
1022    {
1023       md->m_bitmap = NULL;
1024    }
1025
1026    md->m_width = *width;
1027    md->m_height = *height;
1028 }
1029
1030
1031 void MesaDriver::Viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
1032 {
1033    /* poll for window size change and realloc software Z/stencil/etc if needed */
1034    _mesa_ResizeBuffersMESA();
1035 }
1036
1037
1038 const GLubyte *MesaDriver::GetString(struct gl_context *ctx, GLenum name)
1039 {
1040    switch (name) {
1041       case GL_RENDERER:
1042          return (const GLubyte *) "Mesa " MESA_VERSION_STRING " powered BGLView (software)";
1043       default:
1044          // Let core library handle all other cases
1045          return NULL;
1046    }
1047 }
1048
1049
1050 // Plot a pixel.  (0,0) is upper-left corner
1051 // This is only used when drawing to the front buffer.
1052 inline void Plot(BGLView *bglview, int x, int y)
1053 {
1054    // XXX There's got to be a better way!
1055    BPoint p(x, y), q(x+1, y);
1056    bglview->StrokeLine(p, q);
1057 }
1058
1059
1060 void MesaDriver::WriteRGBASpanFront(const struct gl_context *ctx, GLuint n,
1061                                  GLint x, GLint y,
1062                                  CONST GLubyte rgba[][4],
1063                                  const GLubyte mask[])
1064 {
1065    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1066    BGLView *bglview = md->m_bglview;
1067    assert(bglview);
1068    int flippedY = md->m_bottom - y;
1069    if (mask) {
1070       for (GLuint i = 0; i < n; i++) {
1071          if (mask[i]) {
1072             bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]);
1073             Plot(bglview, x++, flippedY);
1074          }
1075       }
1076    }
1077    else {
1078       for (GLuint i = 0; i < n; i++) {
1079          bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]);
1080          Plot(bglview, x++, flippedY);
1081       }
1082    }
1083 }
1084
1085 void MesaDriver::WriteRGBSpanFront(const struct gl_context *ctx, GLuint n,
1086                                 GLint x, GLint y,
1087                                 CONST GLubyte rgba[][3],
1088                                 const GLubyte mask[])
1089 {
1090    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1091    BGLView *bglview = md->m_bglview;
1092    assert(bglview);
1093    int flippedY = md->m_bottom - y;
1094    if (mask) {
1095       for (GLuint i = 0; i < n; i++) {
1096          if (mask[i]) {
1097             bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
1098             Plot(bglview, x++, flippedY);
1099          }
1100       }
1101    }
1102    else {
1103       for (GLuint i = 0; i < n; i++) {
1104          bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
1105          Plot(bglview, x++, flippedY);
1106       }
1107    }
1108 }
1109
1110 void MesaDriver::WriteMonoRGBASpanFront(const struct gl_context *ctx, GLuint n,
1111                                      GLint x, GLint y,
1112                                      const GLchan color[4],
1113                                      const GLubyte mask[])
1114 {
1115    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1116    BGLView *bglview = md->m_bglview;
1117    assert(bglview);
1118    int flippedY = md->m_bottom - y;
1119    bglview->SetHighColor(color[RCOMP], color[GCOMP], color[BCOMP]);
1120    if (mask) {
1121       for (GLuint i = 0; i < n; i++) {
1122          if (mask[i]) {
1123             Plot(bglview, x++, flippedY);
1124          }
1125       }
1126    }
1127    else {
1128       for (GLuint i = 0; i < n; i++) {
1129          Plot(bglview, x++, flippedY);
1130       }
1131    }
1132 }
1133
1134 void MesaDriver::WriteRGBAPixelsFront(const struct gl_context *ctx,
1135                                    GLuint n, const GLint x[], const GLint y[],
1136                                    CONST GLubyte rgba[][4],
1137                                    const GLubyte mask[] )
1138 {
1139    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1140    BGLView *bglview = md->m_bglview;
1141    assert(bglview);
1142    if (mask) {
1143       for (GLuint i = 0; i < n; i++) {
1144          if (mask[i]) {
1145             bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
1146             Plot(bglview, x[i], md->m_bottom - y[i]);
1147          }
1148       }
1149    }
1150    else {
1151       for (GLuint i = 0; i < n; i++) {
1152          bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
1153          Plot(bglview, x[i], md->m_bottom - y[i]);
1154       }
1155    }
1156 }
1157
1158
1159 void MesaDriver::WriteMonoRGBAPixelsFront(const struct gl_context *ctx, GLuint n,
1160                                        const GLint x[], const GLint y[],
1161                                        const GLchan color[4],
1162                                        const GLubyte mask[])
1163 {
1164    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1165    BGLView *bglview = md->m_bglview;
1166    assert(bglview);
1167    // plot points using current color
1168    bglview->SetHighColor(color[RCOMP], color[GCOMP], color[BCOMP]);
1169    if (mask) {
1170       for (GLuint i = 0; i < n; i++) {
1171          if (mask[i]) {
1172             Plot(bglview, x[i], md->m_bottom - y[i]);
1173          }
1174       }
1175    }
1176    else {
1177       for (GLuint i = 0; i < n; i++) {
1178          Plot(bglview, x[i], md->m_bottom - y[i]);
1179       }
1180    }
1181 }
1182
1183
1184 void MesaDriver::WriteCI32SpanFront( const struct gl_context *ctx, GLuint n, GLint x, GLint y,
1185                              const GLuint index[], const GLubyte mask[] )
1186 {
1187         printf("WriteCI32SpanFront() not implemented yet!\n");
1188    // TODO
1189 }
1190
1191 void MesaDriver::WriteCI8SpanFront( const struct gl_context *ctx, GLuint n, GLint x, GLint y,
1192                             const GLubyte index[], const GLubyte mask[] )
1193 {
1194         printf("WriteCI8SpanFront() not implemented yet!\n");
1195    // TODO
1196 }
1197
1198 void MesaDriver::WriteMonoCISpanFront( const struct gl_context *ctx, GLuint n,
1199                                     GLint x, GLint y,
1200                                     GLuint colorIndex, const GLubyte mask[] )
1201 {
1202         printf("WriteMonoCISpanFront() not implemented yet!\n");
1203    // TODO
1204 }
1205
1206
1207 void MesaDriver::WriteCI32PixelsFront( const struct gl_context *ctx, GLuint n,
1208                                     const GLint x[], const GLint y[],
1209                                     const GLuint index[], const GLubyte mask[] )
1210 {
1211         printf("WriteCI32PixelsFront() not implemented yet!\n");
1212    // TODO
1213 }
1214
1215 void MesaDriver::WriteMonoCIPixelsFront( const struct gl_context *ctx, GLuint n,
1216                                       const GLint x[], const GLint y[],
1217                                       GLuint colorIndex, const GLubyte mask[] )
1218 {
1219         printf("WriteMonoCIPixelsFront() not implemented yet!\n");
1220    // TODO
1221 }
1222
1223
1224 void MesaDriver::ReadCI32SpanFront( const struct gl_context *ctx,
1225                                  GLuint n, GLint x, GLint y, GLuint index[] )
1226 {
1227         printf("ReadCI32SpanFront() not implemented yet!\n");
1228   // TODO
1229 }
1230
1231
1232 void MesaDriver::ReadRGBASpanFront( const struct gl_context *ctx, GLuint n,
1233                                  GLint x, GLint y, GLubyte rgba[][4] )
1234 {
1235         printf("ReadRGBASpanFront() not implemented yet!\n");
1236    // TODO
1237 }
1238
1239
1240 void MesaDriver::ReadCI32PixelsFront( const struct gl_context *ctx,
1241                                    GLuint n, const GLint x[], const GLint y[],
1242                                    GLuint indx[], const GLubyte mask[] )
1243 {
1244         printf("ReadCI32PixelsFront() not implemented yet!\n");
1245    // TODO
1246 }
1247
1248
1249 void MesaDriver::ReadRGBAPixelsFront( const struct gl_context *ctx,
1250                                    GLuint n, const GLint x[], const GLint y[],
1251                                    GLubyte rgba[][4], const GLubyte mask[] )
1252 {
1253         printf("ReadRGBAPixelsFront() not implemented yet!\n");
1254    // TODO
1255 }
1256
1257
1258
1259
1260 void MesaDriver::WriteRGBASpanBack(const struct gl_context *ctx, GLuint n,
1261                                  GLint x, GLint y,
1262                                  CONST GLubyte rgba[][4],
1263                                  const GLubyte mask[])
1264 {
1265         MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1266         BBitmap *bitmap = md->m_bitmap;
1267
1268         assert(bitmap);
1269
1270         int row = md->m_bottom - y;
1271         uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4;
1272         uint32 * pixel = (uint32 *) ptr;
1273         
1274         if (mask) {
1275                 while(n--) {
1276                         if (*mask++)
1277                                 *pixel = PACK_B_RGBA32(rgba[0]);
1278                         pixel++;
1279                         rgba++;
1280                 };
1281         } else {
1282                 while(n--) {
1283                         *pixel++ = PACK_B_RGBA32(rgba[0]);
1284                         rgba++;
1285                 };
1286         };
1287  }
1288
1289
1290 void MesaDriver::WriteRGBSpanBack(const struct gl_context *ctx, GLuint n,
1291                                 GLint x, GLint y,
1292                                 CONST GLubyte rgb[][3],
1293                                 const GLubyte mask[])
1294 {
1295         MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1296         BBitmap *bitmap = md->m_bitmap;
1297
1298         assert(bitmap);
1299
1300         int row = md->m_bottom - y;
1301         uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4;
1302         uint32 * pixel = (uint32 *) ptr;
1303         
1304         if (mask) {
1305                 while(n--) {
1306                         if (*mask++)
1307                                 *pixel = PACK_B_RGB32(rgb[0]);
1308                         pixel++;
1309                         rgb++;
1310                 };
1311         } else {
1312                 while(n--) {
1313                         *pixel++ = PACK_B_RGB32(rgb[0]);
1314                         rgb++;
1315                 };
1316         };
1317 }
1318
1319
1320
1321
1322 void MesaDriver::WriteMonoRGBASpanBack(const struct gl_context *ctx, GLuint n,
1323                                     GLint x, GLint y,
1324                                     const GLchan color[4], const GLubyte mask[])
1325 {
1326         MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1327         BBitmap *bitmap = md->m_bitmap;
1328
1329         assert(bitmap);
1330
1331         int row = md->m_bottom - y;
1332         uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4;
1333         uint32 * pixel = (uint32 *) ptr;
1334         uint32 pixel_color = PACK_B_RGBA32(color);
1335         
1336         if (mask) {
1337                 while(n--) {
1338                         if (*mask++)
1339                                 *pixel = pixel_color;
1340                         pixel++;
1341                 };
1342         } else {
1343                 while(n--) {
1344                         *pixel++ = pixel_color;
1345                 };
1346         };
1347 }
1348
1349
1350 void MesaDriver::WriteRGBAPixelsBack(const struct gl_context *ctx,
1351                                    GLuint n, const GLint x[], const GLint y[],
1352                                    CONST GLubyte rgba[][4],
1353                                    const GLubyte mask[] )
1354 {
1355    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1356    BBitmap *bitmap = md->m_bitmap;
1357
1358         assert(bitmap);
1359 #if 0
1360         while(n--) {
1361                 if (*mask++) {
1362                         int row = md->m_bottom - *y;
1363                         uint8 * pixel = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + *x * 4;
1364                         *((uint32 *) pixel) = PACK_B_RGBA32(rgba[0]);
1365                 };
1366                 x++;
1367                 y++;
1368                 rgba++;
1369         };
1370 #else
1371    if (mask) {
1372       for (GLuint i = 0; i < n; i++) {
1373          if (mask[i]) {
1374             GLubyte *pixel = (GLubyte *) bitmap->Bits()
1375             + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4;
1376             pixel[BE_RCOMP] = rgba[i][RCOMP];
1377             pixel[BE_GCOMP] = rgba[i][GCOMP];
1378             pixel[BE_BCOMP] = rgba[i][BCOMP];
1379             pixel[BE_ACOMP] = rgba[i][ACOMP];
1380          }
1381       }
1382    }
1383    else {
1384       for (GLuint i = 0; i < n; i++) {
1385          GLubyte *pixel = (GLubyte *) bitmap->Bits()
1386             + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4;
1387          pixel[BE_RCOMP] = rgba[i][RCOMP];
1388          pixel[BE_GCOMP] = rgba[i][GCOMP];
1389          pixel[BE_BCOMP] = rgba[i][BCOMP];
1390          pixel[BE_ACOMP] = rgba[i][ACOMP];
1391       }
1392    }
1393 #endif
1394 }
1395
1396
1397 void MesaDriver::WriteMonoRGBAPixelsBack(const struct gl_context *ctx, GLuint n,
1398                                       const GLint x[], const GLint y[],
1399                                       const GLchan color[4],
1400                                       const GLubyte mask[])
1401 {
1402         MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1403         BBitmap *bitmap = md->m_bitmap;
1404
1405         assert(bitmap);
1406
1407         uint32 pixel_color = PACK_B_RGBA32(color);
1408 #if 0   
1409         while(n--) {
1410                 if (*mask++) {
1411                         int row = md->m_bottom - *y;
1412                         uint8 * pixel = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + *x * 4;
1413
1414                         *((uint32 *) pixel) = pixel_color;
1415                 };
1416                 x++;
1417                 y++;
1418         };
1419 #else
1420    if (mask) {
1421       for (GLuint i = 0; i < n; i++) {
1422          if (mask[i]) {
1423                 GLubyte * ptr = (GLubyte *) bitmap->Bits()
1424                 + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4;
1425             *((uint32 *) ptr) = pixel_color;
1426          }
1427       }
1428    }
1429    else {
1430           for (GLuint i = 0; i < n; i++) {
1431         GLubyte * ptr = (GLubyte *) bitmap->Bits()
1432                         + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4;
1433        *((uint32 *) ptr) = pixel_color;
1434       }
1435    }
1436 #endif
1437 }
1438
1439
1440 void MesaDriver::WriteCI32SpanBack( const struct gl_context *ctx, GLuint n,
1441                                  GLint x, GLint y,
1442                                  const GLuint index[], const GLubyte mask[] )
1443 {
1444         printf("WriteCI32SpanBack() not implemented yet!\n");
1445    // TODO
1446 }
1447
1448 void MesaDriver::WriteCI8SpanBack( const struct gl_context *ctx, GLuint n,
1449                                 GLint x, GLint y,
1450                                 const GLubyte index[], const GLubyte mask[] )
1451 {
1452         printf("WriteCI8SpanBack() not implemented yet!\n");
1453   // TODO
1454 }
1455
1456 void MesaDriver::WriteMonoCISpanBack( const struct gl_context *ctx, GLuint n,
1457                                    GLint x, GLint y,
1458                                    GLuint colorIndex, const GLubyte mask[] )
1459 {
1460         printf("WriteMonoCISpanBack() not implemented yet!\n");
1461    // TODO
1462 }
1463
1464
1465 void MesaDriver::WriteCI32PixelsBack( const struct gl_context *ctx, GLuint n,
1466                                    const GLint x[], const GLint y[],
1467                                    const GLuint index[], const GLubyte mask[] )
1468 {
1469         printf("WriteCI32PixelsBack() not implemented yet!\n");
1470    // TODO
1471 }
1472
1473 void MesaDriver::WriteMonoCIPixelsBack( const struct gl_context *ctx, GLuint n,
1474                                      const GLint x[], const GLint y[],
1475                                      GLuint colorIndex, const GLubyte mask[] )
1476 {
1477         printf("WriteMonoCIPixelsBack() not implemented yet!\n");
1478    // TODO
1479 }
1480
1481
1482 void MesaDriver::ReadCI32SpanBack( const struct gl_context *ctx,
1483                                 GLuint n, GLint x, GLint y, GLuint index[] )
1484 {
1485         printf("ReadCI32SpanBack() not implemented yet!\n");
1486    // TODO
1487 }
1488
1489
1490 void MesaDriver::ReadRGBASpanBack( const struct gl_context *ctx, GLuint n,
1491                                 GLint x, GLint y, GLubyte rgba[][4] )
1492 {
1493    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1494    const BBitmap *bitmap = md->m_bitmap;
1495    assert(bitmap);
1496    int row = md->m_bottom - y;
1497    const GLubyte *pixel = (GLubyte *) bitmap->Bits()
1498                         + (row * bitmap->BytesPerRow()) + x * 4;
1499
1500    for (GLuint i = 0; i < n; i++) {
1501       rgba[i][RCOMP] = pixel[BE_RCOMP];
1502       rgba[i][GCOMP] = pixel[BE_GCOMP];
1503       rgba[i][BCOMP] = pixel[BE_BCOMP];
1504       rgba[i][ACOMP] = pixel[BE_ACOMP];
1505       pixel += 4;
1506    }
1507 }
1508
1509
1510 void MesaDriver::ReadCI32PixelsBack( const struct gl_context *ctx,
1511                                    GLuint n, const GLint x[], const GLint y[],
1512                                    GLuint indx[], const GLubyte mask[] )
1513 {
1514         printf("ReadCI32PixelsBack() not implemented yet!\n");
1515    // TODO
1516 }
1517
1518
1519 void MesaDriver::ReadRGBAPixelsBack( const struct gl_context *ctx,
1520                                   GLuint n, const GLint x[], const GLint y[],
1521                                   GLubyte rgba[][4], const GLubyte mask[] )
1522 {
1523    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1524    const BBitmap *bitmap = md->m_bitmap;
1525    assert(bitmap);
1526
1527    if (mask) {
1528       for (GLuint i = 0; i < n; i++) {
1529          if (mask[i]) {
1530             GLubyte *pixel = (GLubyte *) bitmap->Bits()
1531             + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4;
1532                  rgba[i][RCOMP] = pixel[BE_RCOMP];
1533              rgba[i][GCOMP] = pixel[BE_GCOMP];
1534                  rgba[i][BCOMP] = pixel[BE_BCOMP];
1535                  rgba[i][ACOMP] = pixel[BE_ACOMP];
1536          };
1537       };
1538    } else {
1539       for (GLuint i = 0; i < n; i++) {
1540          GLubyte *pixel = (GLubyte *) bitmap->Bits()
1541             + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4;
1542          rgba[i][RCOMP] = pixel[BE_RCOMP];
1543          rgba[i][GCOMP] = pixel[BE_GCOMP];
1544          rgba[i][BCOMP] = pixel[BE_BCOMP];
1545          rgba[i][ACOMP] = pixel[BE_ACOMP];
1546       };
1547    };
1548 }
1549
1550 const char * color_space_name(color_space space)
1551 {
1552 #define C2N(a)  case a: return #a
1553
1554         switch (space) {
1555         C2N(B_RGB24);
1556         C2N(B_RGB32);
1557         C2N(B_RGBA32);
1558         C2N(B_RGB32_BIG);
1559         C2N(B_RGBA32_BIG);
1560         C2N(B_GRAY8);
1561         C2N(B_GRAY1);
1562         C2N(B_RGB16);
1563         C2N(B_RGB15);
1564         C2N(B_RGBA15);
1565         C2N(B_CMAP8);
1566         default:
1567                 return "Unknown!";
1568         };
1569
1570 #undef C2N
1571 };
1572
1573