2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 #include "bufferobj.h"
38 #include "extensions.h"
42 #include "texformat.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"
54 #include "tnl/t_context.h"
55 #include "tnl/t_pipeline.h"
57 #include "drivers/common/driverfuncs.h"
61 #include <interface/Screen.h>
64 // BeOS component ordering for B_RGBA32 bitmap format
71 #define PACK_B_RGBA32(color) (color[BCOMP] | (color[GCOMP] << 8) | \
72 (color[RCOMP] << 16) | (color[ACOMP] << 24))
74 #define PACK_B_RGB32(color) (color[BCOMP] | (color[GCOMP] << 8) | \
75 (color[RCOMP] << 16) | 0xFF000000)
77 // Big Endian B_RGBA32 bitmap format
83 #define PACK_B_RGBA32(color) (color[ACOMP] | (color[RCOMP] << 8) | \
84 (color[GCOMP] << 16) | (color[BCOMP] << 24))
86 #define PACK_B_RGB32(color) ((color[RCOMP] << 8) | (color[GCOMP] << 16) | \
87 (color[BCOMP] << 24) | 0xFF000000)
90 #define FLIP(coord) (LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y-(coord) - 1)
92 const char * color_space_name(color_space space);
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.
102 friend class BGLView;
107 void Init(BGLView * bglview, struct gl_context * c, struct gl_config * v, struct gl_framebuffer * b);
111 void SwapBuffers() const;
112 status_t CopyPixelsOut(BPoint source, BBitmap *dest);
113 status_t CopyPixelsIn(BBitmap *source, BPoint dest);
115 void CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const;
116 void Draw(BRect updateRect) const;
119 MesaDriver(const MesaDriver &rhs); // copy constructor illegal
120 MesaDriver &operator=(const MesaDriver &rhs); // assignment oper. illegal
122 struct gl_context * m_glcontext;
123 struct gl_config * m_glvisual;
124 struct gl_framebuffer * m_glframebuffer;
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
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,
151 static void GetBufferSize(struct gl_framebuffer * framebuffer, GLuint *width,
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);
157 // Front-buffer functions
158 static void WriteRGBASpanFront(const struct gl_context *ctx, GLuint n,
160 CONST GLubyte rgba[][4],
161 const GLubyte mask[]);
162 static void WriteRGBSpanFront(const struct gl_context *ctx, GLuint n,
164 CONST GLubyte rgba[][3],
165 const GLubyte mask[]);
166 static void WriteMonoRGBASpanFront(const struct gl_context *ctx, GLuint n,
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,
180 const GLuint index[], const GLubyte mask[]);
181 static void WriteCI8SpanFront(const struct gl_context *ctx, GLuint n,
183 const GLubyte index[], const GLubyte mask[]);
184 static void WriteMonoCISpanFront(const struct gl_context *ctx, GLuint n,
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,
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[]);
205 // Back buffer functions
206 static void WriteRGBASpanBack(const struct gl_context *ctx, GLuint n,
208 CONST GLubyte rgba[][4],
209 const GLubyte mask[]);
210 static void WriteRGBSpanBack(const struct gl_context *ctx, GLuint n,
212 CONST GLubyte rgba[][3],
213 const GLubyte mask[]);
214 static void WriteMonoRGBASpanBack(const struct gl_context *ctx, GLuint n,
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,
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,
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[]);
254 //------------------------------------------------------------------
255 // Public interface methods
256 //------------------------------------------------------------------
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
266 BGLView::BGLView(BRect rect, char *name,
267 ulong resizingMode, ulong mode,
269 : BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS) // | B_FULL_UPDATE_ON_RESIZE)
271 // We don't support single buffering (yet): double buffering forced.
272 options |= BGL_DOUBLE;
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;
287 m_options = options | BGL_INDIRECT;
289 struct dd_function_table functions;
292 fprintf(stderr, "Mesa Warning: color index mode not supported\n");
295 // Allocate auxiliary data object
296 MesaDriver * md = new MesaDriver();
298 // examine option flags and create gl_context struct
299 struct gl_config * visual = _mesa_create_visual( dblFlag,
301 red, green, blue, alpha,
304 accum, accum, accum, accum,
308 // Initialize device driver function table
309 _mesa_init_driver_functions(&functions);
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;
320 // create core context
321 struct gl_context *ctx = _mesa_create_context(API_OPENGL, visual,
322 NULL, &functions, md);
324 _mesa_destroy_visual(visual);
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);
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,
342 /* Initialize the software rasterizer and helper modules.
344 _swrast_CreateContext(ctx);
345 _vbo_CreateContext(ctx);
346 _tnl_CreateContext(ctx);
347 _swsetup_CreateContext(ctx);
348 _swsetup_Wakeup(ctx);
350 md->Init(this, ctx, visual, buffer );
352 // Hook aux data into BGLView object
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
358 if (!_mesa_get_current_context()) {
360 // not needed, we don't have a looper yet: UnlockLooper();
368 // printf("BGLView destructor\n");
369 MesaDriver * md = (MesaDriver *) m_gc;
374 void BGLView::LockGL()
376 MesaDriver * md = (MesaDriver *) m_gc;
381 void BGLView::UnlockGL()
383 MesaDriver * md = (MesaDriver *) m_gc;
388 void BGLView::SwapBuffers()
393 void BGLView::SwapBuffers(bool vSync)
395 MesaDriver * md = (MesaDriver *) m_gc;
400 BScreen screen(Window());
401 screen.WaitForRetrace();
407 void BGLView::CopySubBufferMESA(GLint x, GLint y, GLuint width, GLuint height)
409 MesaDriver * md = (MesaDriver *) m_gc;
411 md->CopySubBuffer(x, y, width, height);
415 BView * BGLView::EmbeddedView()
420 status_t BGLView::CopyPixelsOut(BPoint source, BBitmap *dest)
422 if (! dest || ! dest->Bounds().IsValid())
425 MesaDriver * md = (MesaDriver *) m_gc;
427 return md->CopyPixelsOut(source, dest);
430 status_t BGLView::CopyPixelsIn(BBitmap *source, BPoint dest)
432 if (! source || ! source->Bounds().IsValid())
435 MesaDriver * md = (MesaDriver *) m_gc;
437 return md->CopyPixelsIn(source, dest);
441 void BGLView::ErrorCallback(unsigned long errorCode) // Mesa's GLenum is not ulong but uint!
444 sprintf(msg, "GL: Error code $%04lx.", errorCode);
446 fprintf(stderr, "%s\n", msg);
450 void BGLView::Draw(BRect updateRect)
452 // printf("BGLView::Draw()\n");
453 MesaDriver * md = (MesaDriver *) m_gc;
455 md->Draw(updateRect);
458 void BGLView::AttachedToWindow()
460 BView::AttachedToWindow();
462 // don't paint window background white when resized
463 SetViewColor(B_TRANSPARENT_32_BIT);
466 void BGLView::AllAttached()
468 BView::AllAttached();
469 // printf("BGLView AllAttached\n");
472 void BGLView::DetachedFromWindow()
474 BView::DetachedFromWindow();
477 void BGLView::AllDetached()
479 BView::AllDetached();
480 // printf("BGLView AllDetached");
483 void BGLView::FrameResized(float width, float height)
485 return BView::FrameResized(width, height);
488 status_t BGLView::Perform(perform_code d, void *arg)
490 return BView::Perform(d, arg);
494 status_t BGLView::Archive(BMessage *data, bool deep) const
496 return BView::Archive(data, deep);
499 void BGLView::MessageReceived(BMessage *msg)
501 BView::MessageReceived(msg);
504 void BGLView::SetResizingMode(uint32 mode)
506 BView::SetResizingMode(mode);
519 BHandler *BGLView::ResolveSpecifier(BMessage *msg, int32 index,
520 BMessage *specifier, int32 form,
521 const char *property)
523 return BView::ResolveSpecifier(msg, index, specifier, form, property);
526 status_t BGLView::GetSupportedSuites(BMessage *data)
528 return BView::GetSupportedSuites(data);
531 void BGLView::DirectConnected( direct_buffer_info *info )
534 if (! m_direct_connected && m_direct_connection_disabled)
537 direct_info_locker->Lock();
538 switch(info->buffer_state & B_DIRECT_MODE_MASK) {
540 m_direct_connected = true;
541 case B_DIRECT_MODIFY:
542 // Get clipping information
545 m_clip_list_count = info->clip_list_count;
546 m_clip_list = (clipping_rect *) malloc(m_clip_list_count*sizeof(clipping_rect));
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;
560 direct_info_locker->Unlock();
564 void BGLView::EnableDirectMode( bool enabled )
570 //---- virtual reserved methods ----------
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() {}
582 // Not implemented!!!
584 BGLView::BGLView(const BGLView &v)
587 // XXX not sure how this should work
588 printf("Warning BGLView::copy constructor not implemented\n");
591 BGLView &BGLView::operator=(const BGLView &v)
593 printf("Warning BGLView::operator= not implemented\n");
598 void BGLView::dither_front()
603 bool BGLView::confirm_dither()
609 void BGLView::draw(BRect r)
614 /* Direct Window stuff */
615 void BGLView::drawScanline( int x1, int x2, int y, void *data )
620 void BGLView::scanlineHandler(struct rasStateRec *state,
626 void BGLView::lock_draw()
631 void BGLView::unlock_draw()
636 bool BGLView::validateView()
644 MesaDriver::MesaDriver()
648 m_glframebuffer = NULL;
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;
661 MesaDriver::~MesaDriver()
663 _mesa_destroy_visual(m_glvisual);
664 _mesa_destroy_framebuffer(m_glframebuffer);
665 _mesa_destroy_context(m_glcontext);
671 void MesaDriver::Init(BGLView * bglview, struct gl_context * ctx, struct gl_config * visual, struct gl_framebuffer * framebuffer)
676 m_glframebuffer = framebuffer;
678 MesaDriver * md = (MesaDriver *) ctx->DriverCtx;
679 struct swrast_device_driver * swdd = _swrast_GetDeviceDriverReference( ctx );
680 TNLcontext * tnl = TNL_CONTEXT(ctx);
682 assert(md->m_glcontext == ctx );
686 // Use default TCL pipeline
687 tnl->Driver.RunPipeline = _tnl_run_pipeline;
689 swdd->SetBuffer = this->SetBuffer;
693 void MesaDriver::LockGL()
695 m_bglview->LockLooper();
697 UpdateState(m_glcontext, 0);
698 _mesa_make_current(m_glcontext, m_glframebuffer);
702 void MesaDriver::UnlockGL()
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
711 void MesaDriver::SwapBuffers() const
713 _mesa_notifySwapBuffers(m_glcontext);
716 m_bglview->LockLooper();
717 m_bglview->DrawBitmap(m_bitmap);
718 m_bglview->UnlockLooper();
723 void MesaDriver::CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const
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
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);
738 status_t MesaDriver::CopyPixelsOut(BPoint location, BBitmap *bitmap)
740 color_space scs = m_bitmap->ColorSpace();
741 color_space dcs = bitmap->ColorSpace();
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));
750 // debugger("CopyPixelsOut()");
752 BRect sr = m_bitmap->Bounds();
753 BRect dr = bitmap->Bounds();
755 sr = sr & dr.OffsetBySelf(location);
756 dr = sr.OffsetByCopy(-location.x, -location.y);
758 uint8 *ps = (uint8 *) m_bitmap->Bits();
759 uint8 *pd = (uint8 *) bitmap->Bits();
762 for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) {
763 s = (uint32 *) (ps + y * m_bitmap->BytesPerRow());
764 s += (uint32) sr.left;
766 d = (uint32 *) (pd + (y + (uint32) (dr.top - sr.top)) * bitmap->BytesPerRow());
767 d += (uint32) dr.left;
769 memcpy(d, s, dr.IntegerWidth() * 4);
774 status_t MesaDriver::CopyPixelsIn(BBitmap *bitmap, BPoint location)
776 color_space scs = bitmap->ColorSpace();
777 color_space dcs = m_bitmap->ColorSpace();
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));
786 // debugger("CopyPixelsIn()");
788 BRect sr = bitmap->Bounds();
789 BRect dr = m_bitmap->Bounds();
791 sr = sr & dr.OffsetBySelf(location);
792 dr = sr.OffsetByCopy(-location.x, -location.y);
794 uint8 *ps = (uint8 *) bitmap->Bits();
795 uint8 *pd = (uint8 *) m_bitmap->Bits();
798 for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) {
799 s = (uint32 *) (ps + y * bitmap->BytesPerRow());
800 s += (uint32) sr.left;
802 d = (uint32 *) (pd + (y + (uint32) (dr.top - sr.top)) * m_bitmap->BytesPerRow());
803 d += (uint32) dr.left;
805 memcpy(d, s, dr.IntegerWidth() * 4);
811 void MesaDriver::Draw(BRect updateRect) const
814 m_bglview->DrawBitmap(m_bitmap, updateRect, updateRect);
818 void MesaDriver::Error(struct gl_context *ctx)
820 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
821 if (md && md->m_bglview)
822 md->m_bglview->ErrorCallback((unsigned long) ctx->ErrorValue);
825 void MesaDriver::UpdateState( struct gl_context *ctx, GLuint new_state )
827 struct swrast_device_driver * swdd = _swrast_GetDeviceDriverReference( ctx );
829 _swrast_InvalidateState( ctx, new_state );
830 _swsetup_InvalidateState( ctx, new_state );
831 _vbo_InvalidateState( ctx, new_state );
832 _tnl_InvalidateState( ctx, new_state );
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;
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;
871 void MesaDriver::ClearIndex(struct gl_context *ctx, GLuint index)
873 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
874 md->m_clear_index = index;
878 void MesaDriver::ClearColor(struct gl_context *ctx, const GLfloat color[4])
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);
889 void MesaDriver::Clear(struct gl_context *ctx, GLbitfield mask,
890 GLboolean all, GLint x, GLint y,
891 GLint width, GLint height)
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);
898 mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
900 _swrast_Clear( ctx, mask, all, x, y, width, height );
906 void MesaDriver::ClearFront(struct gl_context *ctx,
907 GLboolean all, GLint x, GLint y,
908 GLint width, GLint height)
910 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
911 BGLView *bglview = md->m_bglview;
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]);
923 BRect b = bglview->Bounds();
924 bglview->FillRect(b);
931 b.bottom = md->m_height - y - 1;
932 b.top = b.bottom - height;
933 bglview->FillRect(b);
936 // restore drawing color
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]);
950 void MesaDriver::ClearBack(struct gl_context *ctx,
951 GLboolean all, GLint x, GLint y,
952 GLint width, GLint height)
954 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
955 BGLView *bglview = md->m_bglview;
957 BBitmap *bitmap = md->m_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);
964 const int numPixels = md->m_width * md->m_height;
965 if (clearPixel == 0) {
966 memset(start, 0, numPixels * 4);
969 for (int i = 0; i < numPixels; i++) {
970 start[i] = clearPixel;
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;
981 start += md->m_width;
987 void MesaDriver::SetBuffer(struct gl_context *ctx, struct gl_framebuffer *buffer,
996 void MesaDriver::GetBufferSize(struct gl_framebuffer * framebuffer, GLuint *width,
999 GET_CURRENT_CONTEXT(ctx);
1003 MesaDriver * md = (MesaDriver *) ctx->DriverCtx;
1004 BGLView *bglview = md->m_bglview;
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;
1012 if (ctx->Visual.doubleBufferMode) {
1013 if (*width != md->m_width || *height != md->m_height) {
1014 // allocate new size of back buffer 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);
1023 md->m_bitmap = NULL;
1026 md->m_width = *width;
1027 md->m_height = *height;
1031 void MesaDriver::Viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
1033 /* poll for window size change and realloc software Z/stencil/etc if needed */
1034 _mesa_ResizeBuffersMESA();
1038 const GLubyte *MesaDriver::GetString(struct gl_context *ctx, GLenum name)
1042 return (const GLubyte *) "Mesa " MESA_VERSION_STRING " powered BGLView (software)";
1044 // Let core library handle all other cases
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)
1054 // XXX There's got to be a better way!
1055 BPoint p(x, y), q(x+1, y);
1056 bglview->StrokeLine(p, q);
1060 void MesaDriver::WriteRGBASpanFront(const struct gl_context *ctx, GLuint n,
1062 CONST GLubyte rgba[][4],
1063 const GLubyte mask[])
1065 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1066 BGLView *bglview = md->m_bglview;
1068 int flippedY = md->m_bottom - y;
1070 for (GLuint i = 0; i < n; i++) {
1072 bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]);
1073 Plot(bglview, x++, flippedY);
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);
1085 void MesaDriver::WriteRGBSpanFront(const struct gl_context *ctx, GLuint n,
1087 CONST GLubyte rgba[][3],
1088 const GLubyte mask[])
1090 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1091 BGLView *bglview = md->m_bglview;
1093 int flippedY = md->m_bottom - y;
1095 for (GLuint i = 0; i < n; i++) {
1097 bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
1098 Plot(bglview, x++, flippedY);
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);
1110 void MesaDriver::WriteMonoRGBASpanFront(const struct gl_context *ctx, GLuint n,
1112 const GLchan color[4],
1113 const GLubyte mask[])
1115 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1116 BGLView *bglview = md->m_bglview;
1118 int flippedY = md->m_bottom - y;
1119 bglview->SetHighColor(color[RCOMP], color[GCOMP], color[BCOMP]);
1121 for (GLuint i = 0; i < n; i++) {
1123 Plot(bglview, x++, flippedY);
1128 for (GLuint i = 0; i < n; i++) {
1129 Plot(bglview, x++, flippedY);
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[] )
1139 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1140 BGLView *bglview = md->m_bglview;
1143 for (GLuint i = 0; i < n; i++) {
1145 bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
1146 Plot(bglview, x[i], md->m_bottom - y[i]);
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]);
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[])
1164 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1165 BGLView *bglview = md->m_bglview;
1167 // plot points using current color
1168 bglview->SetHighColor(color[RCOMP], color[GCOMP], color[BCOMP]);
1170 for (GLuint i = 0; i < n; i++) {
1172 Plot(bglview, x[i], md->m_bottom - y[i]);
1177 for (GLuint i = 0; i < n; i++) {
1178 Plot(bglview, x[i], md->m_bottom - y[i]);
1184 void MesaDriver::WriteCI32SpanFront( const struct gl_context *ctx, GLuint n, GLint x, GLint y,
1185 const GLuint index[], const GLubyte mask[] )
1187 printf("WriteCI32SpanFront() not implemented yet!\n");
1191 void MesaDriver::WriteCI8SpanFront( const struct gl_context *ctx, GLuint n, GLint x, GLint y,
1192 const GLubyte index[], const GLubyte mask[] )
1194 printf("WriteCI8SpanFront() not implemented yet!\n");
1198 void MesaDriver::WriteMonoCISpanFront( const struct gl_context *ctx, GLuint n,
1200 GLuint colorIndex, const GLubyte mask[] )
1202 printf("WriteMonoCISpanFront() not implemented yet!\n");
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[] )
1211 printf("WriteCI32PixelsFront() not implemented yet!\n");
1215 void MesaDriver::WriteMonoCIPixelsFront( const struct gl_context *ctx, GLuint n,
1216 const GLint x[], const GLint y[],
1217 GLuint colorIndex, const GLubyte mask[] )
1219 printf("WriteMonoCIPixelsFront() not implemented yet!\n");
1224 void MesaDriver::ReadCI32SpanFront( const struct gl_context *ctx,
1225 GLuint n, GLint x, GLint y, GLuint index[] )
1227 printf("ReadCI32SpanFront() not implemented yet!\n");
1232 void MesaDriver::ReadRGBASpanFront( const struct gl_context *ctx, GLuint n,
1233 GLint x, GLint y, GLubyte rgba[][4] )
1235 printf("ReadRGBASpanFront() not implemented yet!\n");
1240 void MesaDriver::ReadCI32PixelsFront( const struct gl_context *ctx,
1241 GLuint n, const GLint x[], const GLint y[],
1242 GLuint indx[], const GLubyte mask[] )
1244 printf("ReadCI32PixelsFront() not implemented yet!\n");
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[] )
1253 printf("ReadRGBAPixelsFront() not implemented yet!\n");
1260 void MesaDriver::WriteRGBASpanBack(const struct gl_context *ctx, GLuint n,
1262 CONST GLubyte rgba[][4],
1263 const GLubyte mask[])
1265 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1266 BBitmap *bitmap = md->m_bitmap;
1270 int row = md->m_bottom - y;
1271 uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4;
1272 uint32 * pixel = (uint32 *) ptr;
1277 *pixel = PACK_B_RGBA32(rgba[0]);
1283 *pixel++ = PACK_B_RGBA32(rgba[0]);
1290 void MesaDriver::WriteRGBSpanBack(const struct gl_context *ctx, GLuint n,
1292 CONST GLubyte rgb[][3],
1293 const GLubyte mask[])
1295 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1296 BBitmap *bitmap = md->m_bitmap;
1300 int row = md->m_bottom - y;
1301 uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4;
1302 uint32 * pixel = (uint32 *) ptr;
1307 *pixel = PACK_B_RGB32(rgb[0]);
1313 *pixel++ = PACK_B_RGB32(rgb[0]);
1322 void MesaDriver::WriteMonoRGBASpanBack(const struct gl_context *ctx, GLuint n,
1324 const GLchan color[4], const GLubyte mask[])
1326 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1327 BBitmap *bitmap = md->m_bitmap;
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);
1339 *pixel = pixel_color;
1344 *pixel++ = pixel_color;
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[] )
1355 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1356 BBitmap *bitmap = md->m_bitmap;
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]);
1372 for (GLuint i = 0; i < n; 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];
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];
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[])
1402 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1403 BBitmap *bitmap = md->m_bitmap;
1407 uint32 pixel_color = PACK_B_RGBA32(color);
1411 int row = md->m_bottom - *y;
1412 uint8 * pixel = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + *x * 4;
1414 *((uint32 *) pixel) = pixel_color;
1421 for (GLuint i = 0; i < n; i++) {
1423 GLubyte * ptr = (GLubyte *) bitmap->Bits()
1424 + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4;
1425 *((uint32 *) ptr) = pixel_color;
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;
1440 void MesaDriver::WriteCI32SpanBack( const struct gl_context *ctx, GLuint n,
1442 const GLuint index[], const GLubyte mask[] )
1444 printf("WriteCI32SpanBack() not implemented yet!\n");
1448 void MesaDriver::WriteCI8SpanBack( const struct gl_context *ctx, GLuint n,
1450 const GLubyte index[], const GLubyte mask[] )
1452 printf("WriteCI8SpanBack() not implemented yet!\n");
1456 void MesaDriver::WriteMonoCISpanBack( const struct gl_context *ctx, GLuint n,
1458 GLuint colorIndex, const GLubyte mask[] )
1460 printf("WriteMonoCISpanBack() not implemented yet!\n");
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[] )
1469 printf("WriteCI32PixelsBack() not implemented yet!\n");
1473 void MesaDriver::WriteMonoCIPixelsBack( const struct gl_context *ctx, GLuint n,
1474 const GLint x[], const GLint y[],
1475 GLuint colorIndex, const GLubyte mask[] )
1477 printf("WriteMonoCIPixelsBack() not implemented yet!\n");
1482 void MesaDriver::ReadCI32SpanBack( const struct gl_context *ctx,
1483 GLuint n, GLint x, GLint y, GLuint index[] )
1485 printf("ReadCI32SpanBack() not implemented yet!\n");
1490 void MesaDriver::ReadRGBASpanBack( const struct gl_context *ctx, GLuint n,
1491 GLint x, GLint y, GLubyte rgba[][4] )
1493 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1494 const BBitmap *bitmap = md->m_bitmap;
1496 int row = md->m_bottom - y;
1497 const GLubyte *pixel = (GLubyte *) bitmap->Bits()
1498 + (row * bitmap->BytesPerRow()) + x * 4;
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];
1510 void MesaDriver::ReadCI32PixelsBack( const struct gl_context *ctx,
1511 GLuint n, const GLint x[], const GLint y[],
1512 GLuint indx[], const GLubyte mask[] )
1514 printf("ReadCI32PixelsBack() not implemented yet!\n");
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[] )
1523 MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
1524 const BBitmap *bitmap = md->m_bitmap;
1528 for (GLuint i = 0; i < n; 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];
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];
1550 const char * color_space_name(color_space space)
1552 #define C2N(a) case a: return #a