⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgmesa.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * MiniGUI device driver for Mesa * * Copyright (C) 2006 Feynman Software (http://www.fmsoft.cn) * */#include <GL/mgmesa.h>#include "mgmesadef.h"#include "colors.h"#include "context.h"#include "extensions.h"#include "framebuffer.h"#include "renderbuffer.h"#include "drivers/common/driverfuncs.h"#include "array_cache/acache.h"#include "swrast/swrast.h"#include "swrast_setup/swrast_setup.h"#include "tnl/tnl.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"/* linked list of our Framebuffers (windows) */static mgMesaFramebuffer FirstFramebuffer = NULL;/** * Create a new mgMesaFramebuffer object which will correspond to the * given HDC (Window handle). */mgMesaFramebuffermgmesa_new_framebuffer (HDC hdc, GLvisual *visual){    mgMesaFramebuffer pwfb        = (mgMesaFramebuffer) malloc(sizeof(struct mgmesa_framebuffer));    if (pwfb) {        _mesa_initialize_framebuffer(&pwfb->Base, visual);        pwfb->dc = hdc;        /* insert at head of list */        pwfb->next = FirstFramebuffer;        FirstFramebuffer = pwfb;    }    return pwfb;}/** * Given an hdc, free the corresponding mgMesaFramebuffer */voidmgmesa_free_framebuffer (HDC hdc){    mgMesaFramebuffer pwfb, prev;    for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {        if (pwfb->dc == hdc)            break;        prev = pwfb;    }    if (pwfb) {        if (pwfb == FirstFramebuffer)            FirstFramebuffer = pwfb->next;        else            prev->next = pwfb->next;        free(pwfb);    }}/** * Given an hdc, return the corresponding mgMesaFramebuffer */mgMesaFramebuffermgmesa_lookup_framebuffer (HDC hdc){    mgMesaFramebuffer pwfb;    for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {        if (pwfb->dc == hdc)            return pwfb;    }    return NULL;}/** * Given a GLframebuffer, return the corresponding mgMesaFramebuffer. */static mgMesaFramebuffer mgmesa_framebuffer (GLframebuffer *fb){    return (mgMesaFramebuffer) fb;}/** * Given a GLcontext, return the corresponding mgMesaContext. */static mgMesaContext mgmesa_context (const GLcontext *ctx){    return (mgMesaContext) ctx;}/* * Every driver should implement a GetString function in order to * return a meaningful GL_RENDERER string. */static const GLubyte *mgmesa_get_string (GLcontext *ctx, GLenum name){    return (name == GL_RENDERER) ?         (GLubyte *) "Mesa MiniGUI Driver" : NULL;}/* * Determine the pixel format based on the pixel size. */static void mgSetPixelFormat (mgMesaFramebuffer pwfb, HDC dc){    pwfb->color_bits = GetGDCapability (dc, GDCAP_BITSPP);    /* Only 16 and 32 bit targets are supported now */    assert (pwfb->color_bits == 0 ||       pwfb->color_bits == 16 ||        pwfb->color_bits == 32);    switch(pwfb->color_bits){    case 8:        pwfb->pixelformat = PF_INDEX8;    break;    case 16:        pwfb->pixelformat = PF_5R6G5B;    break;    case 32:        pwfb->pixelformat = PF_8R8G8B;    break;    default:        pwfb->pixelformat = PF_BADFORMAT;    }}/** * Create DIB for back buffer. * We write into this memory with the span routines and then blit it * to the window on a buffer swap. */BOOL mgCreateBackingStore (mgMesaFramebuffer pwfb, long lxSize, long lySize){    RECT rc = {0, 0, 1, 1};    pwfb->memdc = CreateCompatibleDCEx (pwfb->dc, lxSize, lySize);    pwfb->color_bits = GetGDCapability (pwfb->dc, GDCAP_BITSPP);    pwfb->pixels = LockDC (pwfb->memdc, &rc, NULL, NULL, &pwfb->pitch);    UnlockDC (pwfb->memdc);    mgSetPixelFormat (pwfb, pwfb->dc);    return TRUE;}static mgDeleteBackingStore (mgMesaFramebuffer pwfb){    if (pwfb->memdc) {        DeleteMemDC (pwfb->memdc);    }}/** * Find the width and height of the window named by hdc. */static voidget_window_size (HDC hdc, GLuint *width, GLuint *height){    if (WindowFromDC (hdc)) {        RECT rect;        GetClientRect (WindowFromDC(hdc), &rect);        *width = rect.right - rect.left;        *height = rect.bottom - rect.top;    }    else { /* Memory context */        /* From contributed code - use the size of the desktop         * for the size of a memory context (?) */        *width = GetGDCapability (hdc, GDCAP_HPIXEL);        *height = GetGDCapability (hdc, GDCAP_VPIXEL);    }}static voidmgmesa_get_buffer_size (GLframebuffer *buffer, GLuint *width, GLuint *height){    mgMesaFramebuffer pwfb = mgmesa_framebuffer (buffer);    get_window_size (pwfb->dc, width, height);}static void mgmesa_flush (GLcontext *ctx){    mgMesaContext pwc = mgmesa_context (ctx);    mgMesaFramebuffer pwfb = mgmesa_framebuffer(ctx->WinSysDrawBuffer);    if (ctx->Visual.doubleBufferMode == 1 && pwfb->memdc) {        BitBlt (pwfb->memdc, 0, 0, pwfb->Base.Width, pwfb->Base.Height,            pwfb->dc, 0, 0, 0);    }    else {        /* Do nothing for single buffer */    }}/**********************************************************************//*****                   CLEAR Functions                          *****//**********************************************************************//* If we do not implement these, Mesa clears the buffers via the pixel * span writing interface, which is very slow for a clear operation. *//* * Set the color index used to clear the color buffer. */static void clear_index (GLcontext *ctx, GLuint index){    mgMesaContext pwc = mgmesa_context (ctx);    /* Note that indexed mode is not supported yet */    pwc->clear_color.r = 0;    pwc->clear_color.g = 0;    pwc->clear_color.b = 0;}/* * Set the color used to clear the color buffer. */static void clear_color (GLcontext *ctx, const GLfloat color[4]){    mgMesaContext pwc = mgmesa_context(ctx);    mgMesaFramebuffer pwfb = mgmesa_framebuffer(ctx->DrawBuffer);    GLubyte col[3];    UINT    bytesPerPixel = pwfb->color_bits / 8;     CLAMPED_FLOAT_TO_UBYTE (col[0], color[0]);    CLAMPED_FLOAT_TO_UBYTE (col[1], color[1]);    CLAMPED_FLOAT_TO_UBYTE (col[2], color[2]);    pwc->clear_color.r = col[0];    pwc->clear_color.g = col[1];    pwc->clear_color.b = col[2];}/*  * Clear the specified region of the color buffer using the clear color  * or index as specified by one of the two functions above.  *  * This procedure clears either the front and/or the back COLOR buffers.  * Only the "left" buffer is cleared since we are not stereo.  * Clearing of the other non-color buffers is left to the swrast.  */ static void clear(GLcontext *ctx,           GLbitfield mask,           GLboolean all,           GLint x, GLint y,           GLint width, GLint height) {#define FLIP(Y)  (ctx->DrawBuffer->Height - (Y) - 1)    mgMesaContext pwc = mgmesa_context(ctx);    mgMesaFramebuffer pwfb = mgmesa_framebuffer(ctx->DrawBuffer);    gal_pixel pixel;    RECT rc = {x, FLIP(y) + 1, x + width + 1, FLIP(y) - height + 1};    /* Let swrast do all the work if the masks are not set to     * clear all channels. */    if (ctx->Color.ColorMask[0] != 0xff ||        ctx->Color.ColorMask[1] != 0xff ||        ctx->Color.ColorMask[2] != 0xff ||        ctx->Color.ColorMask[3] != 0xff) {        _swrast_Clear(ctx, mask, all, x, y, width, height);         return;    }    NormalizeRect (&rc);    /* Back buffer */    if (mask & BUFFER_BIT_BACK_LEFT) {     #if 0    int done = 0;        int     i, rowSize;         UINT    bytesPerPixel = pwfb->color_bits / 8;         BYTE*  lpb, clearRow;        WORD*  lpw;        BYTE    bColor;         WORD    wColor;         BYTE    r, g, b;         DWORD   dwColor;         DWORD* lpdw;                 /* Try for a fast clear - clearing entire buffer with a single         * byte value. */        if (all) { /* entire buffer */            /* Now check for an easy clear value */            switch (bytesPerPixel) {            case 1:                bColor = BGR8(pwc->clear_color.r,                                 pwc->clear_color.g,                                 pwc->clear_color.b);                memset (pwfb->pixels, bColor, pwfb->pitch * height);                done = 1;                break;            case 2:                wColor = BGR16(pwc->clear_color.r,                                 pwc->clear_color.g,                                pwc->clear_color.b);                 if (((wColor >> 8) & 0xff) == (wColor & 0xff)) {                    memset (pwfb->pixels, wColor & 0xff,                                     pwfb->pitch * height);                    done = 1;                }            break;            case 3:            /* fall through */            case 4:                if (pwc->clear_color.r == pwc->clear_color.g                                 && pwc->clear_color.r == pwc->clear_color.b) {                    memset (pwfb->pixels,                         pwc->clear_color.r, pwfb->pitch * height);                    done = 1;                }            break;            default:            break;            }        } /* all */        if (!done) {            /* Need to clear a row at a time.  Begin by setting the first             * row in the area to be cleared to the clear color. */                        clearRow = pwfb->pixels + pwfb->pitch * FLIP(y) + bytesPerPixel * x;             switch (bytesPerPixel) {            case 1:                lpb = clearRow;                bColor = BGR8(pwc->clear_color.r,                                 pwc->clear_color.g,                                 pwc->clear_color.b);                memset (lpb, bColor, width);                break;            case 2:                lpw = (WORD*)clearRow;                wColor = BGR16(pwc->clear_color.r,                                 pwc->clear_color.g,                                 pwc->clear_color.b);                 for (i=0; i<width; i++)                    *lpw++ = wColor;                break;            case 3:                 lpb = clearRow;                r = pwc->clear_color.r;                 g = pwc->clear_color.g;                 b = pwc->clear_color.b;                 for (i=0; i<width; i++) {                    *lpb++ = b;                    *lpb++ = g;                     *lpb++ = r;                }            break;            case 4:                 lpdw = (DWORD*)clearRow;                 dwColor = BGR32(pwc->clear_color.r,                         pwc->clear_color.g,                         pwc->clear_color.b);                 for (i=0; i<width; i++)                    *lpdw++ = dwColor;                break;            default:                break;            } /* switch */                        /* copy cleared row to other rows in buffer */            lpb = clearRow - pwfb->pitch;            rowSize = width * bytesPerPixel;            for (i=1; i<height; i++) {                 memcpy (lpb, clearRow, rowSize);                 lpb -= pwfb->pitch;             }         } /* not done */#else        SetBrushType (pwfb->memdc, BT_SOLID);        SetBrushColor (pwfb->memdc,                         RGB2Pixel (pwfb->memdc,                                 pwc->clear_color.r,                                 pwc->clear_color.g,                                 pwc->clear_color.b));        FillBox (pwfb->memdc, rc.left, rc.top, RECTW (rc), RECTH (rc));#endif        mask &= ~BUFFER_BIT_BACK_LEFT;    } /* back buffer */     /* front buffer */    if (mask & BUFFER_BIT_FRONT_LEFT) {         SetBrushType (pwc->dc, BT_SOLID);        SetBrushColor (pwc->dc,                         RGB2Pixel (pwc->dc,                                 pwc->clear_color.r,                                 pwc->clear_color.g,                                 pwc->clear_color.b));        FillBox (pwfb->dc, rc.left, rc.top, RECTW (rc), RECTH (rc));        mask &= ~BUFFER_BIT_FRONT_LEFT;    } /* front buffer */         /* Call swrast if there is anything left to clear (like DEPTH) */     if (mask)         _swrast_Clear (ctx, mask, all, x, y, width, height);   #undef FLIP} /**********************************************************************//*****                   PIXEL Functions                          *****//**********************************************************************/#define FLIP(Y)  (rb->Height - (Y) - 1)/** ** Front Buffer reading/writing ** These are slow, but work with all non-indexed visual types. **//* Write a horizontal span of RGBA color pixels with a boolean mask. */static void write_rgba_span_front(const GLcontext *ctx,                    struct gl_renderbuffer *rb,                    GLuint n, GLint x, GLint y,                   const GLubyte rgba[][4],                    const GLubyte mask[] ){    mgMesaContext pwc = mgmesa_context(ctx);    GLuint i;        (void) ctx;    y = FLIP (y);    if (mask) {        for (i=0; i<n; i++)            if (mask[i])                SetPixelRGB (pwc->dc, x+i, y,                                 rgba[i][RCOMP],                                 rgba[i][GCOMP],                                 rgba[i][BCOMP]);    }    else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -