| /* |
| * Mesa 3-D graphics library |
| * Version: 6.1 |
| * |
| * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
| * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| |
| #include <assert.h> |
| #include <stdio.h> |
| |
| extern "C" { |
| |
| #include "glheader.h" |
| #include "version.h" |
| #include "buffers.h" |
| #include "bufferobj.h" |
| #include "context.h" |
| #include "colormac.h" |
| #include "depth.h" |
| #include "extensions.h" |
| #include "macros.h" |
| #include "matrix.h" |
| #include "mtypes.h" |
| #include "texformat.h" |
| #include "texobj.h" |
| #include "teximage.h" |
| #include "texstore.h" |
| #include "vbo/vbo.h" |
| #include "swrast/swrast.h" |
| #include "swrast_setup/swrast_setup.h" |
| #include "swrast/s_context.h" |
| #include "swrast/s_depth.h" |
| #include "swrast/s_lines.h" |
| #include "swrast/s_triangle.h" |
| #include "swrast/s_trispan.h" |
| #include "tnl/tnl.h" |
| #include "tnl/t_context.h" |
| #include "tnl/t_pipeline.h" |
| |
| #include "drivers/common/driverfuncs.h" |
| |
| } // extern "C" |
| |
| #include <interface/Screen.h> |
| #include <GLView.h> |
| |
| // BeOS component ordering for B_RGBA32 bitmap format |
| #if B_HOST_IS_LENDIAN |
| #define BE_RCOMP 2 |
| #define BE_GCOMP 1 |
| #define BE_BCOMP 0 |
| #define BE_ACOMP 3 |
| |
| #define PACK_B_RGBA32(color) (color[BCOMP] | (color[GCOMP] << 8) | \ |
| (color[RCOMP] << 16) | (color[ACOMP] << 24)) |
| |
| #define PACK_B_RGB32(color) (color[BCOMP] | (color[GCOMP] << 8) | \ |
| (color[RCOMP] << 16) | 0xFF000000) |
| #else |
| // Big Endian B_RGBA32 bitmap format |
| #define BE_RCOMP 1 |
| #define BE_GCOMP 2 |
| #define BE_BCOMP 3 |
| #define BE_ACOMP 0 |
| |
| #define PACK_B_RGBA32(color) (color[ACOMP] | (color[RCOMP] << 8) | \ |
| (color[GCOMP] << 16) | (color[BCOMP] << 24)) |
| |
| #define PACK_B_RGB32(color) ((color[RCOMP] << 8) | (color[GCOMP] << 16) | \ |
| (color[BCOMP] << 24) | 0xFF000000) |
| #endif |
| |
| #define FLIP(coord) (LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y-(coord) - 1) |
| |
| const char * color_space_name(color_space space); |
| |
| // |
| // This object hangs off of the BGLView object. We have to use |
| // Be's BGLView class as-is to maintain binary compatibility (we |
| // can't add new members to it). Instead we just put all our data |
| // in this class and use BGLVIew::m_gc to point to it. |
| // |
| class MesaDriver |
| { |
| friend class BGLView; |
| public: |
| MesaDriver(); |
| ~MesaDriver(); |
| |
| void Init(BGLView * bglview, GLcontext * c, struct gl_config * v, GLframebuffer * b); |
| |
| void LockGL(); |
| void UnlockGL(); |
| void SwapBuffers() const; |
| status_t CopyPixelsOut(BPoint source, BBitmap *dest); |
| status_t CopyPixelsIn(BBitmap *source, BPoint dest); |
| |
| void CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const; |
| void Draw(BRect updateRect) const; |
| |
| private: |
| MesaDriver(const MesaDriver &rhs); // copy constructor illegal |
| MesaDriver &operator=(const MesaDriver &rhs); // assignment oper. illegal |
| |
| GLcontext * m_glcontext; |
| struct gl_config * m_glvisual; |
| GLframebuffer * m_glframebuffer; |
| |
| BGLView * m_bglview; |
| BBitmap * m_bitmap; |
| |
| GLchan m_clear_color[4]; // buffer clear color |
| GLuint m_clear_index; // buffer clear color index |
| GLint m_bottom; // used for flipping Y coords |
| GLuint m_width; |
| GLuint m_height; |
| |
| // Mesa Device Driver callback functions |
| static void UpdateState(GLcontext *ctx, GLuint new_state); |
| static void ClearIndex(GLcontext *ctx, GLuint index); |
| static void ClearColor(GLcontext *ctx, const GLfloat color[4]); |
| static void Clear(GLcontext *ctx, GLbitfield mask, |
| GLboolean all, GLint x, GLint y, |
| GLint width, GLint height); |
| static void ClearFront(GLcontext *ctx, GLboolean all, GLint x, GLint y, |
| GLint width, GLint height); |
| static void ClearBack(GLcontext *ctx, GLboolean all, GLint x, GLint y, |
| GLint width, GLint height); |
| static void Index(GLcontext *ctx, GLuint index); |
| static void Color(GLcontext *ctx, GLubyte r, GLubyte g, |
| GLubyte b, GLubyte a); |
| static void SetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer, |
| GLenum mode); |
| static void GetBufferSize(GLframebuffer * framebuffer, GLuint *width, |
| GLuint *height); |
| static void Error(GLcontext *ctx); |
| static const GLubyte * GetString(GLcontext *ctx, GLenum name); |
| static void Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); |
| |
| // Front-buffer functions |
| static void WriteRGBASpanFront(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| CONST GLubyte rgba[][4], |
| const GLubyte mask[]); |
| static void WriteRGBSpanFront(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| CONST GLubyte rgba[][3], |
| const GLubyte mask[]); |
| static void WriteMonoRGBASpanFront(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| const GLchan color[4], |
| const GLubyte mask[]); |
| static void WriteRGBAPixelsFront(const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| CONST GLubyte rgba[][4], |
| const GLubyte mask[]); |
| static void WriteMonoRGBAPixelsFront(const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| const GLchan color[4], |
| const GLubyte mask[]); |
| static void WriteCI32SpanFront(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| const GLuint index[], const GLubyte mask[]); |
| static void WriteCI8SpanFront(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| const GLubyte index[], const GLubyte mask[]); |
| static void WriteMonoCISpanFront(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| GLuint colorIndex, const GLubyte mask[]); |
| static void WriteCI32PixelsFront(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| const GLuint index[], const GLubyte mask[]); |
| static void WriteMonoCIPixelsFront(const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| GLuint colorIndex, const GLubyte mask[]); |
| static void ReadCI32SpanFront(const GLcontext *ctx, |
| GLuint n, GLint x, GLint y, GLuint index[]); |
| static void ReadRGBASpanFront(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| GLubyte rgba[][4]); |
| static void ReadCI32PixelsFront(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLuint indx[], const GLubyte mask[]); |
| static void ReadRGBAPixelsFront(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLubyte rgba[][4], const GLubyte mask[]); |
| |
| // Back buffer functions |
| static void WriteRGBASpanBack(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| CONST GLubyte rgba[][4], |
| const GLubyte mask[]); |
| static void WriteRGBSpanBack(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| CONST GLubyte rgba[][3], |
| const GLubyte mask[]); |
| static void WriteMonoRGBASpanBack(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| const GLchan color[4], |
| const GLubyte mask[]); |
| static void WriteRGBAPixelsBack(const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| CONST GLubyte rgba[][4], |
| const GLubyte mask[]); |
| static void WriteMonoRGBAPixelsBack(const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| const GLchan color[4], |
| const GLubyte mask[]); |
| static void WriteCI32SpanBack(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| const GLuint index[], const GLubyte mask[]); |
| static void WriteCI8SpanBack(const GLcontext *ctx, GLuint n, GLint x, GLint y, |
| const GLubyte index[], const GLubyte mask[]); |
| static void WriteMonoCISpanBack(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, GLuint colorIndex, |
| const GLubyte mask[]); |
| static void WriteCI32PixelsBack(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| const GLuint index[], const GLubyte mask[]); |
| static void WriteMonoCIPixelsBack(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLuint colorIndex, const GLubyte mask[]); |
| static void ReadCI32SpanBack(const GLcontext *ctx, |
| GLuint n, GLint x, GLint y, GLuint index[]); |
| static void ReadRGBASpanBack(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| GLubyte rgba[][4]); |
| static void ReadCI32PixelsBack(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLuint indx[], const GLubyte mask[]); |
| static void ReadRGBAPixelsBack(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLubyte rgba[][4], const GLubyte mask[]); |
| |
| }; |
| |
| //------------------------------------------------------------------ |
| // Public interface methods |
| //------------------------------------------------------------------ |
| |
| |
| // |
| // Input: rect - initial rectangle |
| // name - window name |
| // resizingMode - example: B_FOLLOW_NONE |
| // mode - usually 0 ? |
| // options - Bitwise-OR of BGL_* tokens |
| // |
| BGLView::BGLView(BRect rect, char *name, |
| ulong resizingMode, ulong mode, |
| ulong options) |
| : BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS) // | B_FULL_UPDATE_ON_RESIZE) |
| { |
| // We don't support single buffering (yet): double buffering forced. |
| options |= BGL_DOUBLE; |
| |
| const GLboolean rgbFlag = ((options & BGL_INDEX) == 0); |
| const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA); |
| const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE); |
| const GLboolean stereoFlag = false; |
| const GLint depth = (options & BGL_DEPTH) ? 16 : 0; |
| const GLint stencil = (options & BGL_STENCIL) ? 8 : 0; |
| const GLint accum = (options & BGL_ACCUM) ? 16 : 0; |
| const GLint index = (options & BGL_INDEX) ? 32 : 0; |
| const GLint red = rgbFlag ? 8 : 0; |
| const GLint green = rgbFlag ? 8 : 0; |
| const GLint blue = rgbFlag ? 8 : 0; |
| const GLint alpha = alphaFlag ? 8 : 0; |
| |
| m_options = options | BGL_INDIRECT; |
| |
| struct dd_function_table functions; |
| |
| if (!rgbFlag) { |
| fprintf(stderr, "Mesa Warning: color index mode not supported\n"); |
| } |
| |
| // Allocate auxiliary data object |
| MesaDriver * md = new MesaDriver(); |
| |
| // examine option flags and create gl_context struct |
| struct gl_config * visual = _mesa_create_visual( dblFlag, |
| stereoFlag, |
| red, green, blue, alpha, |
| depth, |
| stencil, |
| accum, accum, accum, accum, |
| 1 |
| ); |
| |
| // Initialize device driver function table |
| _mesa_init_driver_functions(&functions); |
| |
| functions.GetString = md->GetString; |
| functions.UpdateState = md->UpdateState; |
| functions.GetBufferSize = md->GetBufferSize; |
| functions.Clear = md->Clear; |
| functions.ClearIndex = md->ClearIndex; |
| functions.ClearColor = md->ClearColor; |
| functions.Error = md->Error; |
| functions.Viewport = md->Viewport; |
| |
| // create core context |
| GLcontext *ctx = _mesa_create_context(visual, NULL, &functions, md); |
| if (! ctx) { |
| _mesa_destroy_visual(visual); |
| delete md; |
| return; |
| } |
| _mesa_enable_sw_extensions(ctx); |
| _mesa_enable_1_3_extensions(ctx); |
| _mesa_enable_1_4_extensions(ctx); |
| _mesa_enable_1_5_extensions(ctx); |
| |
| |
| // create core framebuffer |
| GLframebuffer * buffer = _mesa_create_framebuffer(visual, |
| depth > 0 ? GL_TRUE : GL_FALSE, |
| stencil > 0 ? GL_TRUE: GL_FALSE, |
| accum > 0 ? GL_TRUE : GL_FALSE, |
| alphaFlag |
| ); |
| |
| /* Initialize the software rasterizer and helper modules. |
| */ |
| _swrast_CreateContext(ctx); |
| _vbo_CreateContext(ctx); |
| _tnl_CreateContext(ctx); |
| _swsetup_CreateContext(ctx); |
| _swsetup_Wakeup(ctx); |
| |
| md->Init(this, ctx, visual, buffer ); |
| |
| // Hook aux data into BGLView object |
| m_gc = md; |
| |
| // some stupid applications (Quake2) don't even think about calling LockGL() |
| // before using glGetString and friends... so make sure there is at least a |
| // valid context. |
| if (!_mesa_get_current_context()) { |
| LockGL(); |
| // not needed, we don't have a looper yet: UnlockLooper(); |
| } |
| |
| } |
| |
| |
| BGLView::~BGLView() |
| { |
| // printf("BGLView destructor\n"); |
| MesaDriver * md = (MesaDriver *) m_gc; |
| assert(md); |
| delete md; |
| } |
| |
| void BGLView::LockGL() |
| { |
| MesaDriver * md = (MesaDriver *) m_gc; |
| assert(md); |
| md->LockGL(); |
| } |
| |
| void BGLView::UnlockGL() |
| { |
| MesaDriver * md = (MesaDriver *) m_gc; |
| assert(md); |
| md->UnlockGL(); |
| } |
| |
| void BGLView::SwapBuffers() |
| { |
| SwapBuffers(false); |
| } |
| |
| void BGLView::SwapBuffers(bool vSync) |
| { |
| MesaDriver * md = (MesaDriver *) m_gc; |
| assert(md); |
| md->SwapBuffers(); |
| |
| if (vSync) { |
| BScreen screen(Window()); |
| screen.WaitForRetrace(); |
| } |
| } |
| |
| |
| #if 0 |
| void BGLView::CopySubBufferMESA(GLint x, GLint y, GLuint width, GLuint height) |
| { |
| MesaDriver * md = (MesaDriver *) m_gc; |
| assert(md); |
| md->CopySubBuffer(x, y, width, height); |
| } |
| #endif |
| |
| BView * BGLView::EmbeddedView() |
| { |
| return NULL; |
| } |
| |
| status_t BGLView::CopyPixelsOut(BPoint source, BBitmap *dest) |
| { |
| if (! dest || ! dest->Bounds().IsValid()) |
| return B_BAD_VALUE; |
| |
| MesaDriver * md = (MesaDriver *) m_gc; |
| assert(md); |
| return md->CopyPixelsOut(source, dest); |
| } |
| |
| status_t BGLView::CopyPixelsIn(BBitmap *source, BPoint dest) |
| { |
| if (! source || ! source->Bounds().IsValid()) |
| return B_BAD_VALUE; |
| |
| MesaDriver * md = (MesaDriver *) m_gc; |
| assert(md); |
| return md->CopyPixelsIn(source, dest); |
| } |
| |
| |
| void BGLView::ErrorCallback(unsigned long errorCode) // Mesa's GLenum is not ulong but uint! |
| { |
| char msg[32]; |
| sprintf(msg, "GL: Error code $%04lx.", errorCode); |
| // debugger(msg); |
| fprintf(stderr, "%s\n", msg); |
| return; |
| } |
| |
| void BGLView::Draw(BRect updateRect) |
| { |
| // printf("BGLView::Draw()\n"); |
| MesaDriver * md = (MesaDriver *) m_gc; |
| assert(md); |
| md->Draw(updateRect); |
| } |
| |
| void BGLView::AttachedToWindow() |
| { |
| BView::AttachedToWindow(); |
| |
| // don't paint window background white when resized |
| SetViewColor(B_TRANSPARENT_32_BIT); |
| } |
| |
| void BGLView::AllAttached() |
| { |
| BView::AllAttached(); |
| // printf("BGLView AllAttached\n"); |
| } |
| |
| void BGLView::DetachedFromWindow() |
| { |
| BView::DetachedFromWindow(); |
| } |
| |
| void BGLView::AllDetached() |
| { |
| BView::AllDetached(); |
| // printf("BGLView AllDetached"); |
| } |
| |
| void BGLView::FrameResized(float width, float height) |
| { |
| return BView::FrameResized(width, height); |
| } |
| |
| status_t BGLView::Perform(perform_code d, void *arg) |
| { |
| return BView::Perform(d, arg); |
| } |
| |
| |
| status_t BGLView::Archive(BMessage *data, bool deep) const |
| { |
| return BView::Archive(data, deep); |
| } |
| |
| void BGLView::MessageReceived(BMessage *msg) |
| { |
| BView::MessageReceived(msg); |
| } |
| |
| void BGLView::SetResizingMode(uint32 mode) |
| { |
| BView::SetResizingMode(mode); |
| } |
| |
| void BGLView::Show() |
| { |
| BView::Show(); |
| } |
| |
| void BGLView::Hide() |
| { |
| BView::Hide(); |
| } |
| |
| BHandler *BGLView::ResolveSpecifier(BMessage *msg, int32 index, |
| BMessage *specifier, int32 form, |
| const char *property) |
| { |
| return BView::ResolveSpecifier(msg, index, specifier, form, property); |
| } |
| |
| status_t BGLView::GetSupportedSuites(BMessage *data) |
| { |
| return BView::GetSupportedSuites(data); |
| } |
| |
| void BGLView::DirectConnected( direct_buffer_info *info ) |
| { |
| #if 0 |
| if (! m_direct_connected && m_direct_connection_disabled) |
| return; |
| |
| direct_info_locker->Lock(); |
| switch(info->buffer_state & B_DIRECT_MODE_MASK) { |
| case B_DIRECT_START: |
| m_direct_connected = true; |
| case B_DIRECT_MODIFY: |
| // Get clipping information |
| if (m_clip_list) |
| free(m_clip_list); |
| m_clip_list_count = info->clip_list_count; |
| m_clip_list = (clipping_rect *) malloc(m_clip_list_count*sizeof(clipping_rect)); |
| if (m_clip_list) { |
| memcpy(m_clip_list, info->clip_list, m_clip_list_count*sizeof(clipping_rect)); |
| fBits = (uint8 *) info->bits; |
| fRowBytes = info->bytes_per_row; |
| fFormat = info->pixel_format; |
| fBounds = info->window_bounds; |
| fDirty = true; |
| } |
| break; |
| case B_DIRECT_STOP: |
| fConnected = false; |
| break; |
| } |
| direct_info_locker->Unlock(); |
| #endif |
| } |
| |
| void BGLView::EnableDirectMode( bool enabled ) |
| { |
| // TODO |
| } |
| |
| |
| //---- virtual reserved methods ---------- |
| |
| void BGLView::_ReservedGLView1() {} |
| void BGLView::_ReservedGLView2() {} |
| void BGLView::_ReservedGLView3() {} |
| void BGLView::_ReservedGLView4() {} |
| void BGLView::_ReservedGLView5() {} |
| void BGLView::_ReservedGLView6() {} |
| void BGLView::_ReservedGLView7() {} |
| void BGLView::_ReservedGLView8() {} |
| |
| #if 0 |
| // Not implemented!!! |
| |
| BGLView::BGLView(const BGLView &v) |
| : BView(v) |
| { |
| // XXX not sure how this should work |
| printf("Warning BGLView::copy constructor not implemented\n"); |
| } |
| |
| BGLView &BGLView::operator=(const BGLView &v) |
| { |
| printf("Warning BGLView::operator= not implemented\n"); |
| return *this; |
| } |
| #endif |
| |
| void BGLView::dither_front() |
| { |
| // no-op |
| } |
| |
| bool BGLView::confirm_dither() |
| { |
| // no-op |
| return false; |
| } |
| |
| void BGLView::draw(BRect r) |
| { |
| // XXX no-op ??? |
| } |
| |
| /* Direct Window stuff */ |
| void BGLView::drawScanline( int x1, int x2, int y, void *data ) |
| { |
| // no-op |
| } |
| |
| void BGLView::scanlineHandler(struct rasStateRec *state, |
| GLint x1, GLint x2) |
| { |
| // no-op |
| } |
| |
| void BGLView::lock_draw() |
| { |
| // no-op |
| } |
| |
| void BGLView::unlock_draw() |
| { |
| // no-op |
| } |
| |
| bool BGLView::validateView() |
| { |
| // no-op |
| return true; |
| } |
| |
| // #pragma mark - |
| |
| MesaDriver::MesaDriver() |
| { |
| m_glcontext = NULL; |
| m_glvisual = NULL; |
| m_glframebuffer = NULL; |
| m_bglview = NULL; |
| m_bitmap = NULL; |
| |
| m_clear_color[BE_RCOMP] = 0; |
| m_clear_color[BE_GCOMP] = 0; |
| m_clear_color[BE_BCOMP] = 0; |
| m_clear_color[BE_ACOMP] = 0; |
| |
| m_clear_index = 0; |
| } |
| |
| |
| MesaDriver::~MesaDriver() |
| { |
| _mesa_destroy_visual(m_glvisual); |
| _mesa_destroy_framebuffer(m_glframebuffer); |
| _mesa_destroy_context(m_glcontext); |
| |
| delete m_bitmap; |
| } |
| |
| |
| void MesaDriver::Init(BGLView * bglview, GLcontext * ctx, struct gl_config * visual, GLframebuffer * framebuffer) |
| { |
| m_bglview = bglview; |
| m_glcontext = ctx; |
| m_glvisual = visual; |
| m_glframebuffer = framebuffer; |
| |
| MesaDriver * md = (MesaDriver *) ctx->DriverCtx; |
| struct swrast_device_driver * swdd = _swrast_GetDeviceDriverReference( ctx ); |
| TNLcontext * tnl = TNL_CONTEXT(ctx); |
| |
| assert(md->m_glcontext == ctx ); |
| assert(tnl); |
| assert(swdd); |
| |
| // Use default TCL pipeline |
| tnl->Driver.RunPipeline = _tnl_run_pipeline; |
| |
| swdd->SetBuffer = this->SetBuffer; |
| } |
| |
| |
| void MesaDriver::LockGL() |
| { |
| m_bglview->LockLooper(); |
| |
| UpdateState(m_glcontext, 0); |
| _mesa_make_current(m_glcontext, m_glframebuffer); |
| } |
| |
| |
| void MesaDriver::UnlockGL() |
| { |
| if (m_bglview->Looper()->IsLocked()) |
| m_bglview->UnlockLooper(); |
| // Could call _mesa_make_current(NULL, NULL) but it would just |
| // hinder performance |
| } |
| |
| |
| void MesaDriver::SwapBuffers() const |
| { |
| _mesa_notifySwapBuffers(m_glcontext); |
| |
| if (m_bitmap) { |
| m_bglview->LockLooper(); |
| m_bglview->DrawBitmap(m_bitmap); |
| m_bglview->UnlockLooper(); |
| }; |
| } |
| |
| |
| void MesaDriver::CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const |
| { |
| if (m_bitmap) { |
| // Source bitmap and view's bitmap are same size. |
| // Source and dest rectangle are the same. |
| // Note (x,y) = (0,0) is the lower-left corner, have to flip Y |
| BRect srcAndDest; |
| srcAndDest.left = x; |
| srcAndDest.right = x + width - 1; |
| srcAndDest.bottom = m_bottom - y; |
| srcAndDest.top = srcAndDest.bottom - height + 1; |
| m_bglview->DrawBitmap(m_bitmap, srcAndDest, srcAndDest); |
| } |
| } |
| |
| status_t MesaDriver::CopyPixelsOut(BPoint location, BBitmap *bitmap) |
| { |
| color_space scs = m_bitmap->ColorSpace(); |
| color_space dcs = bitmap->ColorSpace(); |
| |
| if (scs != dcs && (scs != B_RGBA32 || dcs != B_RGB32)) { |
| printf("CopyPixelsOut(): incompatible color space: %s != %s\n", |
| color_space_name(scs), |
| color_space_name(dcs)); |
| return B_BAD_TYPE; |
| } |
| |
| // debugger("CopyPixelsOut()"); |
| |
| BRect sr = m_bitmap->Bounds(); |
| BRect dr = bitmap->Bounds(); |
| |
| sr = sr & dr.OffsetBySelf(location); |
| dr = sr.OffsetByCopy(-location.x, -location.y); |
| |
| uint8 *ps = (uint8 *) m_bitmap->Bits(); |
| uint8 *pd = (uint8 *) bitmap->Bits(); |
| uint32 *s, *d; |
| uint32 y; |
| for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) { |
| s = (uint32 *) (ps + y * m_bitmap->BytesPerRow()); |
| s += (uint32) sr.left; |
| |
| d = (uint32 *) (pd + (y + (uint32) (dr.top - sr.top)) * bitmap->BytesPerRow()); |
| d += (uint32) dr.left; |
| |
| memcpy(d, s, dr.IntegerWidth() * 4); |
| } |
| return B_OK; |
| } |
| |
| status_t MesaDriver::CopyPixelsIn(BBitmap *bitmap, BPoint location) |
| { |
| color_space scs = bitmap->ColorSpace(); |
| color_space dcs = m_bitmap->ColorSpace(); |
| |
| if (scs != dcs && (dcs != B_RGBA32 || scs != B_RGB32)) { |
| printf("CopyPixelsIn(): incompatible color space: %s != %s\n", |
| color_space_name(scs), |
| color_space_name(dcs)); |
| return B_BAD_TYPE; |
| } |
| |
| // debugger("CopyPixelsIn()"); |
| |
| BRect sr = bitmap->Bounds(); |
| BRect dr = m_bitmap->Bounds(); |
| |
| sr = sr & dr.OffsetBySelf(location); |
| dr = sr.OffsetByCopy(-location.x, -location.y); |
| |
| uint8 *ps = (uint8 *) bitmap->Bits(); |
| uint8 *pd = (uint8 *) m_bitmap->Bits(); |
| uint32 *s, *d; |
| uint32 y; |
| for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) { |
| s = (uint32 *) (ps + y * bitmap->BytesPerRow()); |
| s += (uint32) sr.left; |
| |
| d = (uint32 *) (pd + (y + (uint32) (dr.top - sr.top)) * m_bitmap->BytesPerRow()); |
| d += (uint32) dr.left; |
| |
| memcpy(d, s, dr.IntegerWidth() * 4); |
| } |
| return B_OK; |
| } |
| |
| |
| void MesaDriver::Draw(BRect updateRect) const |
| { |
| if (m_bitmap) |
| m_bglview->DrawBitmap(m_bitmap, updateRect, updateRect); |
| } |
| |
| |
| void MesaDriver::Error(GLcontext *ctx) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| if (md && md->m_bglview) |
| md->m_bglview->ErrorCallback((unsigned long) ctx->ErrorValue); |
| } |
| |
| void MesaDriver::UpdateState( GLcontext *ctx, GLuint new_state ) |
| { |
| struct swrast_device_driver * swdd = _swrast_GetDeviceDriverReference( ctx ); |
| |
| _swrast_InvalidateState( ctx, new_state ); |
| _swsetup_InvalidateState( ctx, new_state ); |
| _vbo_InvalidateState( ctx, new_state ); |
| _tnl_InvalidateState( ctx, new_state ); |
| |
| if (ctx->Color.DrawBuffer[0] == GL_FRONT) { |
| /* read/write front buffer */ |
| swdd->WriteRGBASpan = MesaDriver::WriteRGBASpanFront; |
| swdd->WriteRGBSpan = MesaDriver::WriteRGBSpanFront; |
| swdd->WriteRGBAPixels = MesaDriver::WriteRGBAPixelsFront; |
| swdd->WriteMonoRGBASpan = MesaDriver::WriteMonoRGBASpanFront; |
| swdd->WriteMonoRGBAPixels = MesaDriver::WriteMonoRGBAPixelsFront; |
| swdd->WriteCI32Span = MesaDriver::WriteCI32SpanFront; |
| swdd->WriteCI8Span = MesaDriver::WriteCI8SpanFront; |
| swdd->WriteMonoCISpan = MesaDriver::WriteMonoCISpanFront; |
| swdd->WriteCI32Pixels = MesaDriver::WriteCI32PixelsFront; |
| swdd->WriteMonoCIPixels = MesaDriver::WriteMonoCIPixelsFront; |
| swdd->ReadRGBASpan = MesaDriver::ReadRGBASpanFront; |
| swdd->ReadRGBAPixels = MesaDriver::ReadRGBAPixelsFront; |
| swdd->ReadCI32Span = MesaDriver::ReadCI32SpanFront; |
| swdd->ReadCI32Pixels = MesaDriver::ReadCI32PixelsFront; |
| } |
| else { |
| /* read/write back buffer */ |
| swdd->WriteRGBASpan = MesaDriver::WriteRGBASpanBack; |
| swdd->WriteRGBSpan = MesaDriver::WriteRGBSpanBack; |
| swdd->WriteRGBAPixels = MesaDriver::WriteRGBAPixelsBack; |
| swdd->WriteMonoRGBASpan = MesaDriver::WriteMonoRGBASpanBack; |
| swdd->WriteMonoRGBAPixels = MesaDriver::WriteMonoRGBAPixelsBack; |
| swdd->WriteCI32Span = MesaDriver::WriteCI32SpanBack; |
| swdd->WriteCI8Span = MesaDriver::WriteCI8SpanBack; |
| swdd->WriteMonoCISpan = MesaDriver::WriteMonoCISpanBack; |
| swdd->WriteCI32Pixels = MesaDriver::WriteCI32PixelsBack; |
| swdd->WriteMonoCIPixels = MesaDriver::WriteMonoCIPixelsBack; |
| swdd->ReadRGBASpan = MesaDriver::ReadRGBASpanBack; |
| swdd->ReadRGBAPixels = MesaDriver::ReadRGBAPixelsBack; |
| swdd->ReadCI32Span = MesaDriver::ReadCI32SpanBack; |
| swdd->ReadCI32Pixels = MesaDriver::ReadCI32PixelsBack; |
| } |
| } |
| |
| |
| void MesaDriver::ClearIndex(GLcontext *ctx, GLuint index) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| md->m_clear_index = index; |
| } |
| |
| |
| void MesaDriver::ClearColor(GLcontext *ctx, const GLfloat color[4]) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_RCOMP], color[0]); |
| CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_GCOMP], color[1]); |
| CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_BCOMP], color[2]); |
| CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_ACOMP], color[3]); |
| assert(md->m_bglview); |
| } |
| |
| |
| void MesaDriver::Clear(GLcontext *ctx, GLbitfield mask, |
| GLboolean all, GLint x, GLint y, |
| GLint width, GLint height) |
| { |
| if (mask & DD_FRONT_LEFT_BIT) |
| ClearFront(ctx, all, x, y, width, height); |
| if (mask & DD_BACK_LEFT_BIT) |
| ClearBack(ctx, all, x, y, width, height); |
| |
| mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT); |
| if (mask) |
| _swrast_Clear( ctx, mask, all, x, y, width, height ); |
| |
| return; |
| } |
| |
| |
| void MesaDriver::ClearFront(GLcontext *ctx, |
| GLboolean all, GLint x, GLint y, |
| GLint width, GLint height) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BGLView *bglview = md->m_bglview; |
| assert(bglview); |
| |
| bglview->SetHighColor(md->m_clear_color[BE_RCOMP], |
| md->m_clear_color[BE_GCOMP], |
| md->m_clear_color[BE_BCOMP], |
| md->m_clear_color[BE_ACOMP]); |
| bglview->SetLowColor(md->m_clear_color[BE_RCOMP], |
| md->m_clear_color[BE_GCOMP], |
| md->m_clear_color[BE_BCOMP], |
| md->m_clear_color[BE_ACOMP]); |
| if (all) { |
| BRect b = bglview->Bounds(); |
| bglview->FillRect(b); |
| } |
| else { |
| // XXX untested |
| BRect b; |
| b.left = x; |
| b.right = x + width; |
| b.bottom = md->m_height - y - 1; |
| b.top = b.bottom - height; |
| bglview->FillRect(b); |
| } |
| |
| // restore drawing color |
| #if 0 |
| bglview->SetHighColor(md->mColor[BE_RCOMP], |
| md->mColor[BE_GCOMP], |
| md->mColor[BE_BCOMP], |
| md->mColor[BE_ACOMP]); |
| bglview->SetLowColor(md->mColor[BE_RCOMP], |
| md->mColor[BE_GCOMP], |
| md->mColor[BE_BCOMP], |
| md->mColor[BE_ACOMP]); |
| #endif |
| } |
| |
| |
| void MesaDriver::ClearBack(GLcontext *ctx, |
| GLboolean all, GLint x, GLint y, |
| GLint width, GLint height) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BGLView *bglview = md->m_bglview; |
| assert(bglview); |
| BBitmap *bitmap = md->m_bitmap; |
| assert(bitmap); |
| GLuint *start = (GLuint *) bitmap->Bits(); |
| const GLuint *clearPixelPtr = (const GLuint *) md->m_clear_color; |
| const GLuint clearPixel = B_LENDIAN_TO_HOST_INT32(*clearPixelPtr); |
| |
| if (all) { |
| const int numPixels = md->m_width * md->m_height; |
| if (clearPixel == 0) { |
| memset(start, 0, numPixels * 4); |
| } |
| else { |
| for (int i = 0; i < numPixels; i++) { |
| start[i] = clearPixel; |
| } |
| } |
| } |
| else { |
| // XXX untested |
| start += y * md->m_width + x; |
| for (int i = 0; i < height; i++) { |
| for (int j = 0; j < width; j++) { |
| start[j] = clearPixel; |
| } |
| start += md->m_width; |
| } |
| } |
| } |
| |
| |
| void MesaDriver::SetBuffer(GLcontext *ctx, GLframebuffer *buffer, |
| GLenum mode) |
| { |
| /* TODO */ |
| (void) ctx; |
| (void) buffer; |
| (void) mode; |
| } |
| |
| void MesaDriver::GetBufferSize(GLframebuffer * framebuffer, GLuint *width, |
| GLuint *height) |
| { |
| GET_CURRENT_CONTEXT(ctx); |
| if (!ctx) |
| return; |
| |
| MesaDriver * md = (MesaDriver *) ctx->DriverCtx; |
| BGLView *bglview = md->m_bglview; |
| assert(bglview); |
| |
| BRect b = bglview->Bounds(); |
| *width = (GLuint) b.IntegerWidth() + 1; // (b.right - b.left + 1); |
| *height = (GLuint) b.IntegerHeight() + 1; // (b.bottom - b.top + 1); |
| md->m_bottom = (GLint) b.bottom; |
| |
| if (ctx->Visual.doubleBufferMode) { |
| if (*width != md->m_width || *height != md->m_height) { |
| // allocate new size of back buffer bitmap |
| if (md->m_bitmap) |
| delete md->m_bitmap; |
| BRect rect(0.0, 0.0, *width - 1, *height - 1); |
| md->m_bitmap = new BBitmap(rect, B_RGBA32); |
| } |
| } |
| else |
| { |
| md->m_bitmap = NULL; |
| } |
| |
| md->m_width = *width; |
| md->m_height = *height; |
| } |
| |
| |
| void MesaDriver::Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) |
| { |
| /* poll for window size change and realloc software Z/stencil/etc if needed */ |
| _mesa_ResizeBuffersMESA(); |
| } |
| |
| |
| const GLubyte *MesaDriver::GetString(GLcontext *ctx, GLenum name) |
| { |
| switch (name) { |
| case GL_RENDERER: |
| return (const GLubyte *) "Mesa " MESA_VERSION_STRING " powered BGLView (software)"; |
| default: |
| // Let core library handle all other cases |
| return NULL; |
| } |
| } |
| |
| |
| // Plot a pixel. (0,0) is upper-left corner |
| // This is only used when drawing to the front buffer. |
| inline void Plot(BGLView *bglview, int x, int y) |
| { |
| // XXX There's got to be a better way! |
| BPoint p(x, y), q(x+1, y); |
| bglview->StrokeLine(p, q); |
| } |
| |
| |
| void MesaDriver::WriteRGBASpanFront(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| CONST GLubyte rgba[][4], |
| const GLubyte mask[]) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BGLView *bglview = md->m_bglview; |
| assert(bglview); |
| int flippedY = md->m_bottom - y; |
| if (mask) { |
| for (GLuint i = 0; i < n; i++) { |
| if (mask[i]) { |
| bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]); |
| Plot(bglview, x++, flippedY); |
| } |
| } |
| } |
| else { |
| for (GLuint i = 0; i < n; i++) { |
| bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]); |
| Plot(bglview, x++, flippedY); |
| } |
| } |
| } |
| |
| void MesaDriver::WriteRGBSpanFront(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| CONST GLubyte rgba[][3], |
| const GLubyte mask[]) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BGLView *bglview = md->m_bglview; |
| assert(bglview); |
| int flippedY = md->m_bottom - y; |
| if (mask) { |
| for (GLuint i = 0; i < n; i++) { |
| if (mask[i]) { |
| bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]); |
| Plot(bglview, x++, flippedY); |
| } |
| } |
| } |
| else { |
| for (GLuint i = 0; i < n; i++) { |
| bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]); |
| Plot(bglview, x++, flippedY); |
| } |
| } |
| } |
| |
| void MesaDriver::WriteMonoRGBASpanFront(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| const GLchan color[4], |
| const GLubyte mask[]) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BGLView *bglview = md->m_bglview; |
| assert(bglview); |
| int flippedY = md->m_bottom - y; |
| bglview->SetHighColor(color[RCOMP], color[GCOMP], color[BCOMP]); |
| if (mask) { |
| for (GLuint i = 0; i < n; i++) { |
| if (mask[i]) { |
| Plot(bglview, x++, flippedY); |
| } |
| } |
| } |
| else { |
| for (GLuint i = 0; i < n; i++) { |
| Plot(bglview, x++, flippedY); |
| } |
| } |
| } |
| |
| void MesaDriver::WriteRGBAPixelsFront(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| CONST GLubyte rgba[][4], |
| const GLubyte mask[] ) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BGLView *bglview = md->m_bglview; |
| assert(bglview); |
| if (mask) { |
| for (GLuint i = 0; i < n; i++) { |
| if (mask[i]) { |
| bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]); |
| Plot(bglview, x[i], md->m_bottom - y[i]); |
| } |
| } |
| } |
| else { |
| for (GLuint i = 0; i < n; i++) { |
| bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]); |
| Plot(bglview, x[i], md->m_bottom - y[i]); |
| } |
| } |
| } |
| |
| |
| void MesaDriver::WriteMonoRGBAPixelsFront(const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| const GLchan color[4], |
| const GLubyte mask[]) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BGLView *bglview = md->m_bglview; |
| assert(bglview); |
| // plot points using current color |
| bglview->SetHighColor(color[RCOMP], color[GCOMP], color[BCOMP]); |
| if (mask) { |
| for (GLuint i = 0; i < n; i++) { |
| if (mask[i]) { |
| Plot(bglview, x[i], md->m_bottom - y[i]); |
| } |
| } |
| } |
| else { |
| for (GLuint i = 0; i < n; i++) { |
| Plot(bglview, x[i], md->m_bottom - y[i]); |
| } |
| } |
| } |
| |
| |
| void MesaDriver::WriteCI32SpanFront( const GLcontext *ctx, GLuint n, GLint x, GLint y, |
| const GLuint index[], const GLubyte mask[] ) |
| { |
| printf("WriteCI32SpanFront() not implemented yet!\n"); |
| // TODO |
| } |
| |
| void MesaDriver::WriteCI8SpanFront( const GLcontext *ctx, GLuint n, GLint x, GLint y, |
| const GLubyte index[], const GLubyte mask[] ) |
| { |
| printf("WriteCI8SpanFront() not implemented yet!\n"); |
| // TODO |
| } |
| |
| void MesaDriver::WriteMonoCISpanFront( const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| GLuint colorIndex, const GLubyte mask[] ) |
| { |
| printf("WriteMonoCISpanFront() not implemented yet!\n"); |
| // TODO |
| } |
| |
| |
| void MesaDriver::WriteCI32PixelsFront( const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| const GLuint index[], const GLubyte mask[] ) |
| { |
| printf("WriteCI32PixelsFront() not implemented yet!\n"); |
| // TODO |
| } |
| |
| void MesaDriver::WriteMonoCIPixelsFront( const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| GLuint colorIndex, const GLubyte mask[] ) |
| { |
| printf("WriteMonoCIPixelsFront() not implemented yet!\n"); |
| // TODO |
| } |
| |
| |
| void MesaDriver::ReadCI32SpanFront( const GLcontext *ctx, |
| GLuint n, GLint x, GLint y, GLuint index[] ) |
| { |
| printf("ReadCI32SpanFront() not implemented yet!\n"); |
| // TODO |
| } |
| |
| |
| void MesaDriver::ReadRGBASpanFront( const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, GLubyte rgba[][4] ) |
| { |
| printf("ReadRGBASpanFront() not implemented yet!\n"); |
| // TODO |
| } |
| |
| |
| void MesaDriver::ReadCI32PixelsFront( const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLuint indx[], const GLubyte mask[] ) |
| { |
| printf("ReadCI32PixelsFront() not implemented yet!\n"); |
| // TODO |
| } |
| |
| |
| void MesaDriver::ReadRGBAPixelsFront( const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLubyte rgba[][4], const GLubyte mask[] ) |
| { |
| printf("ReadRGBAPixelsFront() not implemented yet!\n"); |
| // TODO |
| } |
| |
| |
| |
| |
| void MesaDriver::WriteRGBASpanBack(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| CONST GLubyte rgba[][4], |
| const GLubyte mask[]) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BBitmap *bitmap = md->m_bitmap; |
| |
| assert(bitmap); |
| |
| int row = md->m_bottom - y; |
| uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4; |
| uint32 * pixel = (uint32 *) ptr; |
| |
| if (mask) { |
| while(n--) { |
| if (*mask++) |
| *pixel = PACK_B_RGBA32(rgba[0]); |
| pixel++; |
| rgba++; |
| }; |
| } else { |
| while(n--) { |
| *pixel++ = PACK_B_RGBA32(rgba[0]); |
| rgba++; |
| }; |
| }; |
| } |
| |
| |
| void MesaDriver::WriteRGBSpanBack(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| CONST GLubyte rgb[][3], |
| const GLubyte mask[]) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BBitmap *bitmap = md->m_bitmap; |
| |
| assert(bitmap); |
| |
| int row = md->m_bottom - y; |
| uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4; |
| uint32 * pixel = (uint32 *) ptr; |
| |
| if (mask) { |
| while(n--) { |
| if (*mask++) |
| *pixel = PACK_B_RGB32(rgb[0]); |
| pixel++; |
| rgb++; |
| }; |
| } else { |
| while(n--) { |
| *pixel++ = PACK_B_RGB32(rgb[0]); |
| rgb++; |
| }; |
| }; |
| } |
| |
| |
| |
| |
| void MesaDriver::WriteMonoRGBASpanBack(const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| const GLchan color[4], const GLubyte mask[]) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BBitmap *bitmap = md->m_bitmap; |
| |
| assert(bitmap); |
| |
| int row = md->m_bottom - y; |
| uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4; |
| uint32 * pixel = (uint32 *) ptr; |
| uint32 pixel_color = PACK_B_RGBA32(color); |
| |
| if (mask) { |
| while(n--) { |
| if (*mask++) |
| *pixel = pixel_color; |
| pixel++; |
| }; |
| } else { |
| while(n--) { |
| *pixel++ = pixel_color; |
| }; |
| }; |
| } |
| |
| |
| void MesaDriver::WriteRGBAPixelsBack(const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| CONST GLubyte rgba[][4], |
| const GLubyte mask[] ) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BBitmap *bitmap = md->m_bitmap; |
| |
| assert(bitmap); |
| #if 0 |
| while(n--) { |
| if (*mask++) { |
| int row = md->m_bottom - *y; |
| uint8 * pixel = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + *x * 4; |
| *((uint32 *) pixel) = PACK_B_RGBA32(rgba[0]); |
| }; |
| x++; |
| y++; |
| rgba++; |
| }; |
| #else |
| if (mask) { |
| for (GLuint i = 0; i < n; i++) { |
| if (mask[i]) { |
| GLubyte *pixel = (GLubyte *) bitmap->Bits() |
| + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; |
| pixel[BE_RCOMP] = rgba[i][RCOMP]; |
| pixel[BE_GCOMP] = rgba[i][GCOMP]; |
| pixel[BE_BCOMP] = rgba[i][BCOMP]; |
| pixel[BE_ACOMP] = rgba[i][ACOMP]; |
| } |
| } |
| } |
| else { |
| for (GLuint i = 0; i < n; i++) { |
| GLubyte *pixel = (GLubyte *) bitmap->Bits() |
| + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; |
| pixel[BE_RCOMP] = rgba[i][RCOMP]; |
| pixel[BE_GCOMP] = rgba[i][GCOMP]; |
| pixel[BE_BCOMP] = rgba[i][BCOMP]; |
| pixel[BE_ACOMP] = rgba[i][ACOMP]; |
| } |
| } |
| #endif |
| } |
| |
| |
| void MesaDriver::WriteMonoRGBAPixelsBack(const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| const GLchan color[4], |
| const GLubyte mask[]) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| BBitmap *bitmap = md->m_bitmap; |
| |
| assert(bitmap); |
| |
| uint32 pixel_color = PACK_B_RGBA32(color); |
| #if 0 |
| while(n--) { |
| if (*mask++) { |
| int row = md->m_bottom - *y; |
| uint8 * pixel = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + *x * 4; |
| |
| *((uint32 *) pixel) = pixel_color; |
| }; |
| x++; |
| y++; |
| }; |
| #else |
| if (mask) { |
| for (GLuint i = 0; i < n; i++) { |
| if (mask[i]) { |
| GLubyte * ptr = (GLubyte *) bitmap->Bits() |
| + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; |
| *((uint32 *) ptr) = pixel_color; |
| } |
| } |
| } |
| else { |
| for (GLuint i = 0; i < n; i++) { |
| GLubyte * ptr = (GLubyte *) bitmap->Bits() |
| + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; |
| *((uint32 *) ptr) = pixel_color; |
| } |
| } |
| #endif |
| } |
| |
| |
| void MesaDriver::WriteCI32SpanBack( const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| const GLuint index[], const GLubyte mask[] ) |
| { |
| printf("WriteCI32SpanBack() not implemented yet!\n"); |
| // TODO |
| } |
| |
| void MesaDriver::WriteCI8SpanBack( const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| const GLubyte index[], const GLubyte mask[] ) |
| { |
| printf("WriteCI8SpanBack() not implemented yet!\n"); |
| // TODO |
| } |
| |
| void MesaDriver::WriteMonoCISpanBack( const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, |
| GLuint colorIndex, const GLubyte mask[] ) |
| { |
| printf("WriteMonoCISpanBack() not implemented yet!\n"); |
| // TODO |
| } |
| |
| |
| void MesaDriver::WriteCI32PixelsBack( const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| const GLuint index[], const GLubyte mask[] ) |
| { |
| printf("WriteCI32PixelsBack() not implemented yet!\n"); |
| // TODO |
| } |
| |
| void MesaDriver::WriteMonoCIPixelsBack( const GLcontext *ctx, GLuint n, |
| const GLint x[], const GLint y[], |
| GLuint colorIndex, const GLubyte mask[] ) |
| { |
| printf("WriteMonoCIPixelsBack() not implemented yet!\n"); |
| // TODO |
| } |
| |
| |
| void MesaDriver::ReadCI32SpanBack( const GLcontext *ctx, |
| GLuint n, GLint x, GLint y, GLuint index[] ) |
| { |
| printf("ReadCI32SpanBack() not implemented yet!\n"); |
| // TODO |
| } |
| |
| |
| void MesaDriver::ReadRGBASpanBack( const GLcontext *ctx, GLuint n, |
| GLint x, GLint y, GLubyte rgba[][4] ) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| const BBitmap *bitmap = md->m_bitmap; |
| assert(bitmap); |
| int row = md->m_bottom - y; |
| const GLubyte *pixel = (GLubyte *) bitmap->Bits() |
| + (row * bitmap->BytesPerRow()) + x * 4; |
| |
| for (GLuint i = 0; i < n; i++) { |
| rgba[i][RCOMP] = pixel[BE_RCOMP]; |
| rgba[i][GCOMP] = pixel[BE_GCOMP]; |
| rgba[i][BCOMP] = pixel[BE_BCOMP]; |
| rgba[i][ACOMP] = pixel[BE_ACOMP]; |
| pixel += 4; |
| } |
| } |
| |
| |
| void MesaDriver::ReadCI32PixelsBack( const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLuint indx[], const GLubyte mask[] ) |
| { |
| printf("ReadCI32PixelsBack() not implemented yet!\n"); |
| // TODO |
| } |
| |
| |
| void MesaDriver::ReadRGBAPixelsBack( const GLcontext *ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLubyte rgba[][4], const GLubyte mask[] ) |
| { |
| MesaDriver *md = (MesaDriver *) ctx->DriverCtx; |
| const BBitmap *bitmap = md->m_bitmap; |
| assert(bitmap); |
| |
| if (mask) { |
| for (GLuint i = 0; i < n; i++) { |
| if (mask[i]) { |
| GLubyte *pixel = (GLubyte *) bitmap->Bits() |
| + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; |
| rgba[i][RCOMP] = pixel[BE_RCOMP]; |
| rgba[i][GCOMP] = pixel[BE_GCOMP]; |
| rgba[i][BCOMP] = pixel[BE_BCOMP]; |
| rgba[i][ACOMP] = pixel[BE_ACOMP]; |
| }; |
| }; |
| } else { |
| for (GLuint i = 0; i < n; i++) { |
| GLubyte *pixel = (GLubyte *) bitmap->Bits() |
| + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; |
| rgba[i][RCOMP] = pixel[BE_RCOMP]; |
| rgba[i][GCOMP] = pixel[BE_GCOMP]; |
| rgba[i][BCOMP] = pixel[BE_BCOMP]; |
| rgba[i][ACOMP] = pixel[BE_ACOMP]; |
| }; |
| }; |
| } |
| |
| const char * color_space_name(color_space space) |
| { |
| #define C2N(a) case a: return #a |
| |
| switch (space) { |
| C2N(B_RGB24); |
| C2N(B_RGB32); |
| C2N(B_RGBA32); |
| C2N(B_RGB32_BIG); |
| C2N(B_RGBA32_BIG); |
| C2N(B_GRAY8); |
| C2N(B_GRAY1); |
| C2N(B_RGB16); |
| C2N(B_RGB15); |
| C2N(B_RGBA15); |
| C2N(B_CMAP8); |
| default: |
| return "Unknown!"; |
| }; |
| |
| #undef C2N |
| }; |
| |
| |