1566 lines
46 KiB
C++
1566 lines
46 KiB
C++
/*
|
|
* 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 "array_cache/acache.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, GLvisual * 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;
|
|
GLvisual * 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);
|
|
|
|
// 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
|
|
GLvisual * visual = _mesa_create_visual( rgbFlag,
|
|
dblFlag,
|
|
stereoFlag,
|
|
red, green, blue, alpha,
|
|
index,
|
|
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;
|
|
|
|
// 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);
|
|
_ac_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);
|
|
|
|
}
|
|
|
|
|
|
void MesaDriver::Init(BGLView * bglview, GLcontext * ctx, GLvisual * 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 );
|
|
_ac_InvalidateState( ctx, new_state );
|
|
_tnl_InvalidateState( ctx, new_state );
|
|
|
|
if (ctx->Color.DrawBuffer == 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;
|
|
}
|
|
|
|
|
|
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
|
|
};
|
|
|
|
|