Add functions to the Win32 GDISP driver to enable full testing of the streaming driver interface.

ugfx_release_2.6
inmarket 2013-10-24 11:30:17 +10:00
parent 825bbf26a1
commit 8c1a37b59e
2 changed files with 250 additions and 32 deletions

View File

@ -17,38 +17,15 @@
#include "../drivers/multiple/Win32/gdisp_lld_config.h"
#include "gdisp/lld/gdisp_lld.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <wingdi.h>
#include <assert.h>
#ifndef GDISP_SCREEN_WIDTH
#define GDISP_SCREEN_WIDTH 640
#endif
#ifndef GDISP_SCREEN_HEIGHT
#define GDISP_SCREEN_HEIGHT 480
#endif
#define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0)
#define GDISP_FLG_HASTOGGLE (GDISP_FLG_DRIVER<<1)
#define GDISP_FLG_HASMOUSE (GDISP_FLG_DRIVER<<2)
#if GINPUT_NEED_TOGGLE
/* Include toggle support code */
#include "ginput/lld/toggle.h"
#endif
#if GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888
#error "GDISP Win32: This driver currently only supports the RGB888 pixel format."
#endif
#if GINPUT_NEED_MOUSE
/* Include mouse support code */
#include "ginput/lld/mouse.h"
#endif
// Setting this to TRUE delays updating the screen
// to the windows paint routine. Due to the
// drawing lock this does not add as much speed
@ -57,18 +34,46 @@
// even draw_pixel().
// This is probably due to drawing operations being
// combined as the update regions are merged.
// The only time you might want to turn this off is
// if you are debugging drawing and want to see each
// pixel as it is set.
#define GDISP_WIN32_USE_INDIRECT_UPDATE TRUE
//#define GDISP_WIN32_USE_INDIRECT_UPDATE FALSE
// How far extra windows should be offset from the first.
// How far extra windows (multiple displays) should be offset from the first.
#define DISPLAY_X_OFFSET 50
#define DISPLAY_Y_OFFSET 50
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <wingdi.h>
#include <assert.h>
#define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0)
#define GDISP_FLG_HASTOGGLE (GDISP_FLG_DRIVER<<1)
#define GDISP_FLG_HASMOUSE (GDISP_FLG_DRIVER<<2)
#if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
#define GDISP_FLG_WSTREAM (GDISP_FLG_DRIVER<<3)
#define GDISP_FLG_WRAPPED (GDISP_FLG_DRIVER<<4)
#endif
#if GINPUT_NEED_TOGGLE
/* Include toggle support code */
#include "ginput/lld/toggle.h"
#endif
#if GINPUT_NEED_MOUSE
/* Include mouse support code */
#include "ginput/lld/mouse.h"
#endif
static DWORD winThreadId;
static ATOM winClass;
static volatile bool_t QReady;
static HANDLE drawMutex;
/*===========================================================================*/
/* Driver local routines . */
/*===========================================================================*/
@ -96,6 +101,10 @@ typedef struct winPriv {
#if GINPUT_NEED_TOGGLE
uint8_t toggles;
#endif
#if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
coord_t x0, y0, x1, y1;
coord_t x, y;
#endif
} winPriv;
@ -441,6 +450,10 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
assert(priv != NULL);
memset(priv, 0, sizeof(winPriv));
g->priv = priv;
#if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
// Initialise with an invalid window
g->flags &= ~GDISP_FLG_WSTREAM;
#endif
g->board = 0; // no board interface for this controller
// Create the window in the message thread
@ -467,6 +480,199 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
}
#endif
#if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
void BAD_PARAMETER(const char *msg) {
volatile int a;
// This is really just a point for us to set the debugger
a = 0;
}
#endif
#if GDISP_HARDWARE_STREAM_WRITE
LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
winPriv * priv;
if (g->flags & GDISP_FLG_WSTREAM)
BAD_PARAMETER("write_start: already in streaming mode");
if (g->p.cx <= 0 || g->p.cy <= 0 || g->p.x < 0 || g->p.y < 0 || g->p.x+g->p.cx > g->g.Width || g->p.y+g->p.cy > g->g.Height)
BAD_PARAMETER("write_start: bad window parameter");
priv = g->priv;
priv->x0 = g->p.x; priv->x1 = g->p.x + g->p.cx - 1;
priv->y0 = g->p.y; priv->y1 = g->p.y + g->p.cy - 1;
#if GDISP_HARDWARE_STREAM_POS
priv->x = g->p.x-1; // Make sure these values are invalid (for testing)
priv->y = g->p.y-1;
#else
priv->x = g->p.x;
priv->y = g->p.y;
#endif
g->flags |= GDISP_FLG_WSTREAM;
g->flags &= ~GDISP_FLG_WRAPPED;
}
LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
winPriv * priv;
int x, y;
COLORREF color;
priv = g->priv;
color = COLOR2BGR(g->p.color);
if (!(g->flags & GDISP_FLG_WSTREAM))
BAD_PARAMETER("write_color: not in streaming mode");
if (priv->x < priv->x0 || priv->x > priv->x1 || priv->y < priv->y0 || priv->y > priv->y1)
BAD_PARAMETER("write_color: cursor outside streaming area");
if (g->flags & GDISP_FLG_WRAPPED) {
BAD_PARAMETER("write_color: Warning - Area wrapped.");
g->flags &= ~GDISP_FLG_WRAPPED;
}
#if GDISP_NEED_CONTROL
switch(g->g.Orientation) {
case GDISP_ROTATE_0:
x = priv->x;
y = priv->y;
break;
case GDISP_ROTATE_90:
x = priv->y;
y = g->g.Width - 1 - priv->x;
break;
case GDISP_ROTATE_180:
x = g->g.Width - 1 - priv->x;
y = g->g.Height - 1 - priv->y;
break;
case GDISP_ROTATE_270:
x = g->g.Height - 1 - priv->y;
y = priv->x;
break;
}
#else
x = priv->x;
y = priv->y;
#endif
// Draw the pixel on the screen and in the buffer.
WaitForSingleObject(drawMutex, INFINITE);
SetPixel(priv->dcBuffer, x, y, color);
#if GDISP_WIN32_USE_INDIRECT_UPDATE
ReleaseMutex(drawMutex);
{
RECT r;
r.left = x; r.right = x+1;
r.top = y; r.bottom = y+1;
InvalidateRect(priv->hwnd, &r, FALSE);
}
#else
{
HDC dc;
dc = GetDC(priv->hwnd);
SetPixel(dc, x, y, color);
ReleaseDC(priv->hwnd, dc);
ReleaseMutex(drawMutex);
}
#endif
// Update the cursor
if (++priv->x > priv->x1) {
priv->x = priv->x0;
if (++priv->y > priv->y1) {
g->flags |= GDISP_FLG_WRAPPED;
priv->y = priv->y0;
}
}
}
LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
if (!(g->flags & GDISP_FLG_WSTREAM))
BAD_PARAMETER("write_stop: not in streaming mode");
g->flags &= ~GDISP_FLG_WSTREAM;
}
#if GDISP_HARDWARE_STREAM_POS
LLDSPEC void gdisp_lld_write_pos(GDisplay *g) {
winPriv * priv;
priv = g->priv;
if (!(g->flags & GDISP_FLG_WSTREAM))
BAD_PARAMETER("write_pos: not in streaming mode");
if (g->p.x < priv->x0 || g->p.x > priv->x1 || g->p.y < priv->y0 || g->p.y > priv->y1)
BAD_PARAMETER("write_color: new cursor outside streaming area");
priv->x = g->p.x;
priv->y = g->p.y;
}
#endif
#endif
#if GDISP_HARDWARE_STREAM_READ
LLDSPEC void gdisp_lld_read_start(GDisplay *g) {
winPriv * priv;
if (g->flags & GDISP_FLG_WSTREAM)
BAD_PARAMETER("read_start: already in streaming mode");
if (g->p.cx <= 0 || g->p.cy <= 0 || g->p.x < 0 || g->p.y < 0 || g->p.x+g->p.cx > g->g.Width || g->p.y+g->p.cy > g->g.Height)
BAD_PARAMETER("read_start: bad window parameter");
priv = g->priv;
priv->x0 = g->p.x; priv->x1 = g->p.x + g->p.cx - 1;
priv->y0 = g->p.y; priv->y1 = g->p.y + g->p.cy - 1;
priv->x = g->p.x;
priv->y = g->p.y;
g->flags |= GDISP_FLG_WSTREAM;
g->flags &= ~GDISP_FLG_WRAPPED;
}
LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) {
winPriv * priv;
COLORREF color;
priv = g->priv;
if (!(g->flags & GDISP_FLG_WSTREAM))
BAD_PARAMETER("read_color: not in streaming mode");
if (priv->x < priv->x0 || priv->x > priv->x1 || priv->y < priv->y0 || priv->y > priv->y1)
BAD_PARAMETER("read_color: cursor outside streaming area");
if (g->flags & GDISP_FLG_WRAPPED) {
BAD_PARAMETER("read_color: Warning - Area wrapped.");
g->flags &= ~GDISP_FLG_WRAPPED;
}
WaitForSingleObject(drawMutex, INFINITE);
#if GDISP_NEED_CONTROL
switch(g->g.Orientation) {
case GDISP_ROTATE_0:
color = GetPixel(priv->dcBuffer, g->p.x, g->p.y);
break;
case GDISP_ROTATE_90:
color = GetPixel(priv->dcBuffer, g->p.y, g->g.Width - 1 - g->p.x);
break;
case GDISP_ROTATE_180:
color = GetPixel(priv->dcBuffer, g->g.Width - 1 - g->p.x, g->g.Height - 1 - g->p.y);
break;
case GDISP_ROTATE_270:
color = GetPixel(priv->dcBuffer, g->g.Height - 1 - g->p.y, g->p.x);
break;
}
#else
color = GetPixel(priv->dcBuffer, g->p.x, g->p.y);
#endif
ReleaseMutex(drawMutex);
// Update the cursor
if (++priv->x > priv->x1) {
priv->x = priv->x0;
if (++priv->y > priv->y1) {
g->flags |= GDISP_FLG_WRAPPED;
priv->y = priv->y0;
}
}
return BGR2COLOR(color);
}
LLDSPEC void gdisp_lld_read_stop(GDisplay *g) {
if (!(g->flags & GDISP_FLG_WSTREAM))
BAD_PARAMETER("write_stop: not in streaming mode");
g->flags &= ~GDISP_FLG_WSTREAM;
}
#endif
#if GDISP_HARDWARE_DRAWPIXEL
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
winPriv * priv;
@ -507,8 +713,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
ReleaseMutex(drawMutex);
{
RECT r;
r.left = g->p.x; r.right = g->p.x+1;
r.top = g->p.y; r.bottom = g->p.y+1;
r.left = x; r.right = x+1;
r.top = y; r.bottom = y+1;
InvalidateRect(priv->hwnd, &r, FALSE);
}
#else

View File

@ -26,12 +26,24 @@
// application to force a display update. eg after streaming.
#define GDISP_HARDWARE_FLUSH TRUE
#define GDISP_HARDWARE_DRAWPIXEL TRUE
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_HARDWARE_BITFILLS TRUE
#define GDISP_HARDWARE_SCROLL TRUE
//#define GDISP_WIN32_STREAMING_TEST
#ifdef GDISP_WIN32_STREAMING_TEST
// These streaming routines are here only to debug the high level gdisp
// code for streaming controllers. They are slow, inefficient and have
// lots of debugging turned on.
#define GDISP_HARDWARE_STREAM_WRITE TRUE
#define GDISP_HARDWARE_STREAM_READ TRUE
#define GDISP_HARDWARE_STREAM_POS TRUE
#else
// The proper way on the Win32. These routines are nice and fast.
#define GDISP_HARDWARE_DRAWPIXEL TRUE
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_BITFILLS TRUE
#define GDISP_HARDWARE_SCROLL TRUE
#endif
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888