Ah, no attachments, here is the code:
void CVNCClient::SetupBitmapInfo()
{
m_bmi = new BYTE[sizeof(BITMAPINFOHEADER) + (4 * sizeof(DWORD))];
BITMAPINFO* m_bi = (BITMAPINFO *) m_bmi;
m_bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_bi->bmiHeader.biWidth = 0; // set later
m_bi->bmiHeader.biHeight = 0; // set later
m_bi->bmiHeader.biPlanes = 1;
m_bi->bmiHeader.biBitCount = m_pixelFormat.bitsPerPixel;
m_bi->bmiHeader.biCompression = BI_BITFIELDS;
m_bi->bmiHeader.biSizeImage = 0; // set later
m_bi->bmiHeader.biXPelsPerMeter = 0; // ??
m_bi->bmiHeader.biYPelsPerMeter = 0; // ??
m_bi->bmiHeader.biClrUsed = 0;
m_bi->bmiHeader.biClrImportant = 0;
DWORD* m = (DWORD *)(m_bmi + sizeof(BITMAPINFOHEADER));
*m = ((DWORD)m_pixelFormat.redMax) << m_pixelFormat.redShift;
TRACE(_T(" -- red mask: %X\n"), *m);
m++;
*m = ((DWORD)m_pixelFormat.greenMax) << m_pixelFormat.greenShift;
TRACE(_T(" -- green mask: %X\n"), *m);
m++;
*m = ((DWORD)m_pixelFormat.blueMax) << m_pixelFormat.blueShift;
TRACE(_T(" -- blue mask: %X\n"), *m);
m++;
*m = 0;
// BUF_LINES about 100 or so
if (8 == m_pixelFormat.bitsPerPixel || 16 == m_pixelFormat.bitsPerPixel)
{
// we are going to have to DWORD align some rects, this
// is a scratch buffer for this
m_pixbuf = new BYTE[
GetFrameBufferWidth() * GetMinPixelBytes() * BUF_LINES];
TRACE(_T(" pixbuf len: %d\n"),
GetFrameBufferWidth() * GetMinPixelBytes() * BUF_LINES);
}
}
void CVNCClient::FastSetPixels(
CDC& dc,
BYTE* buffer, int x, int y, int w, int h)
{
/* setup the bitmap header */
BITMAPINFO* bi = GetBitmapInfo();
bi->bmiHeader.biWidth = w;
bi->bmiHeader.biHeight = -h; /* top down */
bi->bmiHeader.biSizeImage = GetMinPixelBytes() * w * h;
int lineSize = GetMinPixelBytes() * w;
if (lineSize % sizeof(DWORD) == 0)
{
// already aligned
::SetDIBitsToDevice(dc.m_hDC,
x, y, /* destination */
w, h, /* source width/height */
0, 0, /* source x,y */
0, /* fist scanline */
h, /* number of scanlines */
buffer, /* bits */
bi,
DIB_RGB_COLORS);
}
else
{
int nLeft = h;
int extraBytesNeeded = sizeof(DWORD) - GetMinPixelBytes();
ASSERT((lineSize + extraBytesNeeded) % sizeof(DWORD) == 0);
int nDrawn = 0;
while (nLeft > 0)
{
int nlines = min(nLeft, BUF_LINES);
BYTE* buf = m_pixbuf;
// DWORD align in scratch buffer
for (int l = 0; l < nlines; l++)
{
memcpy(buf, buffer, lineSize);
buffer += lineSize;
buf += lineSize + extraBytesNeeded;
}
bi->bmiHeader.biHeight = -nlines; /* top down */
bi->bmiHeader.biSizeImage = (lineSize + extraBytesNeeded) * nlines;
int s = ::SetDIBitsToDevice(dc.m_hDC,
x, y, /* destination */
w, nlines, /* source width/height */
0, 0, /* source x,y */
0, /* fist scanline */
nlines, /* number of scanlines */
m_pixbuf, /* bits */
bi,
DIB_RGB_COLORS);
nLeft -= nlines;
y += nlines;
nDrawn += nlines;
}
ASSERT(nDrawn == h);
}
}
----- Original Message -----
From: "Tony Rozga" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, March 06, 2003 8:45 PM
Subject: A windows optimization
> Hi,
> I wish I had time to submit this as a patch but I'm in the middle of a
> monster project...
> you know how that goes. Anyway, we noticed that processing updates in the
> windows
> viewer was taking, well, a long time. A little profiling led us to the
> SETPIXELs
> macros. SetPixel is slow. For example, just profiling SetPixel, it took
> 5-6 seconds
> to process a 1280x1024 full update (zlib) on a fast machine with ok video.
>
> The optimization is simple. Treat the buffer as the bits of a DIB and use
> SetDIBitsToDevice
> to write to the DC.
>
> I've attached two methods, one to setup a BITMAPINFO once the clients
pixel
> format is set and
> one called FastSetPixels. The only trickiness is that scanlines must be
> DWORD aligned, no
> prob for 32 bits, can be a problem in 8 and 16 bits. Our solution was to
> pre-create a
> temp buffer to hold 100 scan lines and use that to draw those updates that
> did not come in
> aligned in chunks.
>
> The result is a significant improvement, 5-6 seconds dropped to <1 second.
>
> This code has only been tested in 16/32 bit modes so be warned. Also,
this
> code will not drop
> straight into the standard viewer code but it is pretty obvious.
>
> Anyway, that is all. Hope you like it. Gotta get back to it.
>
> Tony Rozga
> NeoValent
>
> [demime 0.99d.1 removed an attachment of type application/octet-stream
which had a name of vncopt.cpp]
> _______________________________________________
> VNC-List mailing list
> [EMAIL PROTECTED]
> http://www.realvnc.com/mailman/listinfo/vnc-list
_______________________________________________
VNC-List mailing list
[EMAIL PROTECTED]
http://www.realvnc.com/mailman/listinfo/vnc-list