Merge branch 'llvm-cliptest-viewport'
[mesa.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 "swrast/s_trispan.h"
54 #include "tnl/tnl.h"
55 #include "tnl/t_context.h"
56 #include "tnl/t_pipeline.h"
57
58 #include "drivers/common/driverfuncs.h"
59
60 } // extern "C"
61
62 #include <interface/Screen.h>
63 #include <GLView.h>
64
65 // BeOS component ordering for B_RGBA32 bitmap format
66 #if B_HOST_IS_LENDIAN
67 #define BE_RCOMP 2
68 #define BE_GCOMP 1
69 #define BE_BCOMP 0
70 #define BE_ACOMP 3
71
72 #define PACK_B_RGBA32(color) (color[BCOMP] | (color[GCOMP] << 8) | \
73 (color[RCOMP] << 16) | (color[ACOMP] << 24))
74
75 #define PACK_B_RGB32(color) (color[BCOMP] | (color[GCOMP] << 8) | \
76 (color[RCOMP] << 16) | 0xFF000000)
77 #else
78 // Big Endian B_RGBA32 bitmap format
79 #define BE_RCOMP 1
80 #define BE_GCOMP 2
81 #define BE_BCOMP 3
82 #define BE_ACOMP 0
83
84 #define PACK_B_RGBA32(color) (color[ACOMP] | (color[RCOMP] << 8) | \
85 (color[GCOMP] << 16) | (color[BCOMP] << 24))
86
87 #define PACK_B_RGB32(color) ((color[RCOMP] << 8) | (color[GCOMP] << 16) | \
88 (color[BCOMP] << 24) | 0xFF000000)
89 #endif
90
91 #define FLIP(coord) (LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y-(coord) - 1)
92
93 const char * color_space_name(color_space space);
94
95 //
96 // This object hangs off of the BGLView object. We have to use
97 // Be's BGLView class as-is to maintain binary compatibility (we
98 // can't add new members to it). Instead we just put all our data
99 // in this class and use BGLVIew::m_gc to point to it.
100 //
101 class MesaDriver
102 {
103 friend class BGLView;
104 public:
105 MesaDriver();
106 ~MesaDriver();
107
108 void Init(BGLView * bglview, struct gl_context * c, struct gl_config * v, struct gl_framebuffer * b);
109
110 void LockGL();
111 void UnlockGL();
112 void SwapBuffers() const;
113 status_t CopyPixelsOut(BPoint source, BBitmap *dest);
114 status_t CopyPixelsIn(BBitmap *source, BPoint dest);
115
116 void CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const;
117 void Draw(BRect updateRect) const;
118
119 private:
120 MesaDriver(const MesaDriver &rhs); // copy constructor illegal
121 MesaDriver &operator=(const MesaDriver &rhs); // assignment oper. illegal
122
123 struct gl_context * m_glcontext;
124 struct gl_config * m_glvisual;
125 struct gl_framebuffer * m_glframebuffer;
126
127 BGLView * m_bglview;
128 BBitmap * m_bitmap;
129
130 GLchan m_clear_color[4]; // buffer clear color
131 GLuint m_clear_index; // buffer clear color index
132 GLint m_bottom; // used for flipping Y coords
133 GLuint m_width;
134 GLuint m_height;
135
136 // Mesa Device Driver callback functions
137 static void UpdateState(struct gl_context *ctx, GLuint new_state);
138 static void ClearIndex(struct gl_context *ctx, GLuint index);
139 static void ClearColor(struct gl_context *ctx, const GLfloat color[4]);
140 static void Clear(struct gl_context *ctx, GLbitfield mask,
141 GLboolean all, GLint x, GLint y,
142 GLint width, GLint height);
143 static void ClearFront(struct gl_context *ctx, GLboolean all, GLint x, GLint y,
144 GLint width, GLint height);
145 static void ClearBack(struct gl_context *ctx, GLboolean all, GLint x, GLint y,
146 GLint width, GLint height);
147 static void Index(struct gl_context *ctx, GLuint index);
148 static void Color(struct gl_context *ctx, GLubyte r, GLubyte g,
149 GLubyte b, GLubyte a);
150 static void SetBuffer(struct gl_context *ctx, struct gl_framebuffer *colorBuffer,
151 GLenum mode);
152 static void GetBufferSize(struct gl_framebuffer * framebuffer, GLuint *width,
153 GLuint *height);
154 static void Error(struct gl_context *ctx);
155 static const GLubyte * GetString(struct gl_context *ctx, GLenum name);
156 static void Viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h);
157
158 // Front-buffer functions
159 static void WriteRGBASpanFront(const struct gl_context *ctx, GLuint n,
160 GLint x, GLint y,
161 CONST GLubyte rgba[][4],
162 const GLubyte mask[]);
163 static void WriteRGBSpanFront(const struct gl_context *ctx, GLuint n,
164 GLint x, GLint y,
165 CONST GLubyte rgba[][3],
166 const GLubyte mask[]);
167 static void WriteMonoRGBASpanFront(const struct gl_context *ctx, GLuint n,
168 GLint x, GLint y,
169 const GLchan color[4],
170 const GLubyte mask[]);
171 static void WriteRGBAPixelsFront(const struct gl_context *ctx, GLuint n,
172 const GLint x[], const GLint y[],
173 CONST GLubyte rgba[][4],
174 const GLubyte mask[]);
175 static void WriteMonoRGBAPixelsFront(const struct gl_context *ctx, GLuint n,
176 const GLint x[], const GLint y[],
177 const GLchan color[4],
178 const GLubyte mask[]);
179 static void WriteCI32SpanFront(const struct gl_context *ctx, GLuint n,
180 GLint x, GLint y,
181 const GLuint index[], const GLubyte mask[]);
182 static void WriteCI8SpanFront(const struct gl_context *ctx, GLuint n,
183 GLint x, GLint y,
184 const GLubyte index[], const GLubyte mask[]);
185 static void WriteMonoCISpanFront(const struct gl_context *ctx, GLuint n,
186 GLint x, GLint y,
187 GLuint colorIndex, const GLubyte mask[]);
188 static void WriteCI32PixelsFront(const struct gl_context *ctx,
189 GLuint n, const GLint x[], const GLint y[],
190 const GLuint index[], const GLubyte mask[]);
191 static void WriteMonoCIPixelsFront(const struct gl_context *ctx, GLuint n,
192 const GLint x[], const GLint y[],
193 GLuint colorIndex, const GLubyte mask[]);
194 static void ReadCI32SpanFront(const struct gl_context *ctx,
195 GLuint n, GLint x, GLint y, GLuint index[]);
196 static void ReadRGBASpanFront(const struct gl_context *ctx, GLuint n,
197 GLint x, GLint y,
198 GLubyte rgba[][4]);
199 static void ReadCI32PixelsFront(const struct gl_context *ctx,
200 GLuint n, const GLint x[], const GLint y[],
201 GLuint indx[], const GLubyte mask[]);
202 static void ReadRGBAPixelsFront(const struct gl_context *ctx,
203 GLuint n, const GLint x[], const GLint y[],
204 GLubyte rgba[][4], const GLubyte mask[]);
205
206 // Back buffer functions
207 static void WriteRGBASpanBack(const struct gl_context *ctx, GLuint n,
208 GLint x, GLint y,
209 CONST GLubyte rgba[][4],
210 const GLubyte mask[]);
211 static void WriteRGBSpanBack(const struct gl_context *ctx, GLuint n,
212 GLint x, GLint y,
213 CONST GLubyte rgba[][3],
214 const GLubyte mask[]);
215 static void WriteMonoRGBASpanBack(const struct gl_context *ctx, GLuint n,
216 GLint x, GLint y,
217 const GLchan color[4],
218 const GLubyte mask[]);
219 static void WriteRGBAPixelsBack(const struct gl_context *ctx, GLuint n,
220 const GLint x[], const GLint y[],
221 CONST GLubyte rgba[][4],
222 const GLubyte mask[]);
223 static void WriteMonoRGBAPixelsBack(const struct gl_context *ctx, GLuint n,
224 const GLint x[], const GLint y[],
225 const GLchan color[4],
226 const GLubyte mask[]);
227 static void WriteCI32SpanBack(const struct gl_context *ctx, GLuint n,
228 GLint x, GLint y,
229 const GLuint index[], const GLubyte mask[]);
230 static void WriteCI8SpanBack(const struct gl_context *ctx, GLuint n, GLint x, GLint y,
231 const GLubyte index[], const GLubyte mask[]);
232 static void WriteMonoCISpanBack(const struct gl_context *ctx, GLuint n,
233 GLint x, GLint y, GLuint colorIndex,
234 const GLubyte mask[]);
235 static void WriteCI32PixelsBack(const struct gl_context *ctx,
236 GLuint n, const GLint x[], const GLint y[],
237 const GLuint index[], const GLubyte mask[]);
238 static void WriteMonoCIPixelsBack(const struct gl_context *ctx,
239 GLuint n, const GLint x[], const GLint y[],
240 GLuint colorIndex, const GLubyte mask[]);
241 static void ReadCI32SpanBack(const struct gl_context *ctx,
242 GLuint n, GLint x, GLint y, GLuint index[]);
243 static void ReadRGBASpanBack(const struct gl_context *ctx, GLuint n,
244 GLint x, GLint y,
245 GLubyte rgba[][4]);
246 static void ReadCI32PixelsBack(const struct gl_context *ctx,
247 GLuint n, const GLint x[], const GLint y[],
248 GLuint indx[], const GLubyte mask[]);
249 static void ReadRGBAPixelsBack(const struct gl_context *ctx,
250 GLuint n, const GLint x[], const GLint y[],
251 GLubyte rgba[][4], const GLubyte mask[]);
252
253 };
254
255 //------------------------------------------------------------------
256 // Public interface methods
257 //------------------------------------------------------------------
258
259
260 //
261 // Input: rect - initial rectangle
262 // name - window name
263 // resizingMode - example: B_FOLLOW_NONE
264 // mode - usually 0 ?
265 // options - Bitwise-OR of BGL_* tokens
266 //
267 BGLView::BGLView(BRect rect, char *name,
268 ulong resizingMode, ulong mode,
269 ulong options)
270 : BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS) // | B_FULL_UPDATE_ON_RESIZE)
271 {
272 // We don't support single buffering (yet): double buffering forced.
273 options |= BGL_DOUBLE;
274
275 const GLboolean rgbFlag = ((options & BGL_INDEX) == 0);
276 const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA);
277 const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE);
278 const GLboolean stereoFlag = false;
279 const GLint depth = (options & BGL_DEPTH) ? 16 : 0;
280 const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
281 const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
282 const GLint index = (options & BGL_INDEX) ? 32 : 0;
283 const GLint red = rgbFlag ? 8 : 0;
284 const GLint green = rgbFlag ? 8 : 0;
285 const GLint blue = rgbFlag ? 8 : 0;
286 const GLint alpha = alphaFlag ? 8 : 0;
287
288 m_options = options | BGL_INDIRECT;
289
290 struct dd_function_table functions;
291
292 if (!rgbFlag) {
293 fprintf(stderr, "Mesa Warning: color index mode not supported\n");
294 }
295
296 // Allocate auxiliary data object
297 MesaDriver * md = new MesaDriver();
298
299 // examine option flags and create gl_context struct
300 struct gl_config * visual = _mesa_create_visual( dblFlag,
301 stereoFlag,
302 red, green, blue, alpha,
303 depth,
304 stencil,
305 accum, accum, accum, accum,
306 1
307 );
308
309 // Initialize device driver function table
310 _mesa_init_driver_functions(&functions);
311
312 functions.GetString = md->GetString;
313 functions.UpdateState = md->UpdateState;
314 functions.GetBufferSize = md->GetBufferSize;
315 functions.Clear = md->Clear;
316 functions.ClearIndex = md->ClearIndex;
317 functions.ClearColor = md->ClearColor;
318 functions.Error = md->Error;
319 functions.Viewport = md->Viewport;
320
321 // create core context
322 struct gl_context *ctx = _mesa_create_context(visual, 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