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