🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
17 messages
17 total messages Started by Robert G. Hoover Wed, 13 Jun 2007 16:34
Multi-thread OR Event-based?
#1841
Author: Robert G. Hoover
Date: Wed, 13 Jun 2007 16:34
102 lines
4338 bytes
Hi again,

I've written a test app (in BDS C++ Builder 2006) that creates a BITMAP
structure and then paints it onto the screen every 50 milliseconds via
TTimer and WM_TIMER. Sounds simple enough, right?

Here's the timer function:

// draw video frame
void __fastcall TShellForm::VideoStreamTimerTimer(TObject *Sender)
{
	// increasing image color (black to white, then wrap)
	static unsigned char ThisShade = 0;

	// update image color
	memset(VideoImage->bmBitmap.bmBits,
               ThisShade++,
               VideoImage->WidthBytes * VideoImage->Height);

	// display current image on screen
	VideoImage->DibDraw(hDD, hDC, 0, 0);
}
//---------------------------------------------------------------------------

VideoImage is just a wrapper for a BITMAP structure. Here's my DibDraw
stuff...

// draw bitmap preserving size and aspect ratio
void BitmapImageClass::DibDraw(HDRAWDIB hDD, HDC hDC, int left, int top)
{
	DrawDibDraw(hDD,     						
		    hDC,     						
		    left,							
		    top,    						
		    -1,
		    -1,
		    &(bmInfo.bmiHeader),			
		    bmBitmap.bmBits,   	   			
		    0,     							
		    0,     							
		    bmInfo.bmiHeader.biWidth,    	
		    bmInfo.bmiHeader.biHeight,    	
		    DDF_SAME_DRAW | DDF_SAME_HDC);	
}
//---------------------------------------------------------------------------

I'm also setting it up like so...

// initialize GUI
void __fastcall TShellForm::FormCreate(TObject *Sender)
{
	// create object
	VideoImage = new BitmapImageClass(ClientWidth, ClientHeight, 8);

	// get handle to window canvas
	hDC = GetDC(Handle);

	// open DrawDib library for use
	// and create a DrawDib device context for drawing
	hDD = DrawDibOpen();

	// define DrawDib transformation
	DrawDibBegin(hDD,
		     hDC,
		     -1,
		     -1,
		     &(VideoImage->bmInfo.bmiHeader),
		     VideoImage->Width,
		     VideoImage->Height,
		     DDF_SAME_DRAW | DDF_SAME_HDC);

	// realize palette of DrawDib DC for use with specified DC
//	DrawDibRealize(hDD, hDC, 0);
}
//---------------------------------------------------------------------------

The DrawDibRealize fails and seems not to affect the operation as my
stream does paint as expected.

So, here's the problem.... I've got 2 Pentium machines and 1 DualCore
machine exhibiting the same behavior. This code causes crashes on them
(blue screen of death) with Windows errors BAD_POOL_HEADER,
IRQL_NOT_LESS_OR_EQUAL, PAGE_FAULT_IN_NONPAGED_AREA. This is way outside
my understanding of operating systems and hardware.

I switched from SetDIBitsToDevice() to DrawDibDraw() because of an
earlier discussion about "thread-safe" video routines. There seems to be
no improvement in execution.

And to make matters worse, all my programs run flawlessly on slower
machines. Is it possible that "we" have crossed a yield threshold where
the processors are running faster than WinXP can manage? "Windows XP was
not originally designed to support performance states on multiprocessor
configurations" (http://support.microsoft.com/kb/896256/en-us)

Also, the DualCore runs 10x slower on the frame rate, possibly
indicating that the 2 processors are fighting over the same memory space?

I'm really pulling out my hair on this one... any and all advice
welcome... many thanks!

Rob
Re: Multi-thread OR Event-based?
#1843
Author: JD
Date: Wed, 13 Jun 2007 17:02
16 lines
1391 bytes
"Robert G. Hoover" <not.a.real.address@anywhere.sorry> wrote:
>

>void __fastcall TShellForm::FormCreate(TObject *Sender)

Never ever use OnCreate or OnDestroy. There are delphi
remnants that can execute out of order (OnCreate before
the constructor and OnDestroy after the destructor). Use the constructor and destructor instead.

> I've got 2 Pentium machines and 1 DualCore machine

Why not use the win32 API BitBlt? Works on both my P4 and
Core2Duo.

~ JD
Re: Multi-thread OR Event-based?
#1845
Author: Robert G. Hoover
Date: Wed, 13 Jun 2007 17:22
33 lines
2172 bytes
Hi JD,

There's a function I haven't tried. I'm afraid I have very little
understanding of DeviceContexts. I see that BitBlt needs a source DC. I
don't have one. Rather I have an unsigned char block of memory that I
manipulate myself, held in a BITMAP structure and referenced with a
BITMAPINFO structure. Do I need to define a DC for my BITMAP? I see
functions like CreateCompatibleDC. Do I need to SelectObject an HBITMAP
for a new DC? If I change the bytes in my BITMAP.bmBits array, will
those changes appear immediately? Or do I have to SelectObject again or
CreateCompatibleDC again?

Thanks,

Rob


JD wrote:
> "Robert G. Hoover" <not.a.real.address@anywhere.sorry> wrote:
> 
>> void __fastcall TShellForm::FormCreate(TObject *Sender)
> 
> Never ever use OnCreate or OnDestroy. There are delphi
> remnants that can execute out of order (OnCreate before
> the constructor and OnDestroy after the destructor). Use the constructor and destructor instead.
> 
>> I've got 2 Pentium machines and 1 DualCore machine
> 
> Why not use the win32 API BitBlt? Works on both my P4 and
> Core2Duo.
> 
> ~ JD
> 
Re: Multi-thread OR Event-based?
#1846
Author: Jonathan Benedicto
Date: Wed, 13 Jun 2007 17:38
22 lines
1951 bytes
Robert G. Hoover wrote:
> Hi JD,
>
> There's a function I haven't tried. I'm afraid I have very little
> understanding of DeviceContexts. I see that BitBlt needs a source DC. I
> don't have one. Rather I have an unsigned char block of memory that I
> manipulate myself, held in a BITMAP structure and referenced with a
> BITMAPINFO structure. Do I need to define a DC for my BITMAP? I see
> functions like CreateCompatibleDC. Do I need to SelectObject an HBITMAP
> for a new DC? If I change the bytes in my BITMAP.bmBits array, will
> those changes appear immediately? Or do I have to SelectObject again or
> CreateCompatibleDC again?

I'm in the middle to a reply to your original post, but thought I'd make a 
quick comment here.

AFAIK, StretchDIBits is the BitBlt equivalent that takes a block of memory 
instead of a DC.

HTH

Jon 
Re: Multi-thread OR Event-based?
#1748
Author: Jonathan Benedicto
Date: Wed, 13 Jun 2007 18:26
28 lines
2206 bytes
Robert G. Hoover wrote:
> I switched from SetDIBitsToDevice() to DrawDibDraw() because of an
> earlier discussion about "thread-safe" video routines. There seems to be
> no improvement in execution.

I've been doing a little research on this, and it seems that I may be wrong. 
In tests, StretchDIBits and DrawDibDraw both worked in a multi-threaded 
situation.

So, I'd suggest using StretchDIBits.

> And to make matters worse, all my programs run flawlessly on slower
> machines. Is it possible that "we" have crossed a yield threshold where
> the processors are running faster than WinXP can manage? "Windows XP was
> not originally designed to support performance states on multiprocessor
> configurations" (http://support.microsoft.com/kb/896256/en-us)

No - I have a dual-core, and everything works perfectly. It is most likely 
that you're running into multi-threading issues, causing your programs to 
behave erratically.

> Also, the DualCore runs 10x slower on the frame rate, possibly
> indicating that the 2 processors are fighting over the same memory space?

You could be having memory problems, but without seeing the code, it is hard 
to say.

Jon 
Re: Multi-thread OR Event-based?
#1749
Author: Jonathan Benedicto
Date: Wed, 13 Jun 2007 18:54
9 lines
1350 bytes
> I've been doing a little research on this, and it seems that I may be 
> wrong. In tests, StretchDIBits and DrawDibDraw both worked in a 
> multi-threaded situation.
>
> So, I'd suggest using StretchDIBits.

PS. I really mean "StretchDIBits". "SetDIBitsToDevice" is *not* thread-safe.

Jon 
Re: Multi-thread OR Event-based?
#1750
Author: JD
Date: Wed, 13 Jun 2007 19:37
37 lines
2197 bytes
"Robert G. Hoover" <not.a.real.address@anywhere.sorry> wrote:
>

Please trim your posts.

> [...] I see that BitBlt needs a source DC. I don't have one.

I would suggest that you use a TBitmap instead. It's 
Canvas::Handle is a DC and you can get a DC for the
screen this way:

    HWND hWnd = ::GetDesktopWindow();
    HDC hDC = ::GetWindowDC( hWnd );

If you need to manipulate the TBitmap, you can use it's Pixels[][] 
property (very slow) or you can use it's ScanLine[] property
(very fast). The following sample converts the TBitmap to gray
scale but note that the offsets differ for variouse PixelFormat
styles. The sample assumes pf24bit.

    for( int y = 0; y < Bmp->Height; ++y )
      {
          BYTE* ScanLine = static_cast<BYTE*>( Bmp->ScanLine[y] );
          for( int x = 0; x < Bmp->Width; ++x )
            {
                BYTE R = ScanLine[ x * 3 + 0 ];
                BYTE G = ScanLine[ x * 3 + 1 ];
                BYTE B = ScanLine[ x * 3 + 2 ];
                BYTE L = (BYTE)((R * 0.299) + (G * 0.587) + (B * 0.114));
                ScanLine[ x * 3 + 0 ] = L;
                ScanLine[ x * 3 + 1 ] = L;
                ScanLine[ x * 3 + 2 ] = L;
            }
      }

~ JD
Re: Multi-thread OR Event-based?
#1753
Author: Robert G. Hoover
Date: Thu, 14 Jun 2007 14:57
122 lines
4504 bytes
Hi Everyone,

Thanks SO much for your help. I'm still struggling with this whole
thing. Can you have a look at this code? I've stripped out everything I
can think of and reduced it to a single application thread by using the
WM_TIMER event. I must be missing something obvious...

Many thanks,

Rob

_________________________________________________________________________


#include <vcl.h> 							#include "PixelSaverShell.h"   				
#pragma hdrstop                     		
#pragma package(smart_init)            	
#pragma resource "*.dfm"

typedef struct
{
   BITMAPINFOHEADER bmiHeader;    	
   RGBQUAD          bmiColors[256];
}
BITMAPINFOSTRUCT;

// global variables
TShellForm       *ShellForm;  				
HDC		 hDC;						
BITMAPINFOSTRUCT  bmInfo;					
BITMAP 		  bmBitmap;

__fastcall TShellForm::TShellForm(TComponent* Owner) : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TShellForm::FormCreate(TObject *Sender)
{
	Left = 0;
	Top  = 0;
	ClientWidth  = Screen->Width;
	ClientHeight = Screen->Height;

	bmBitmap.bmType       = 0;
	bmBitmap.bmPlanes     = 1;
	bmBitmap.bmWidth      = ClientWidth;
	bmBitmap.bmHeight     = ClientHeight;
	bmBitmap.bmBitsPixel  = 8;
	bmBitmap.bmWidthBytes = ClientWidth;

	// pad rows
	short RowPad = bmBitmap.bmWidthBytes % 4;
	if (RowPad != 0)
		bmBitmap.bmWidthBytes += 4 - RowPad;

	bmBitmap.bmBits = (unsigned char *)malloc(bmBitmap.bmWidthBytes *
bmBitmap.bmHeight);

	bmInfo.bmiHeader.biSize	         = sizeof(BITMAPINFOHEADER);
	bmInfo.bmiHeader.biWidth	 = bmBitmap.bmWidth;
	bmInfo.bmiHeader.biHeight	 = bmBitmap.bmHeight;
	bmInfo.bmiHeader.biPlanes	 = bmBitmap.bmPlanes;
	bmInfo.bmiHeader.biBitCount	 = bmBitmap.bmBitsPixel;
	bmInfo.bmiHeader.biCompression	 = BI_RGB;
	bmInfo.bmiHeader.biSizeImage	 = bmBitmap.bmWidthBytes * bmBitmap.bmHeight;
	bmInfo.bmiHeader.biXPelsPerMeter = 0;
	bmInfo.bmiHeader.biYPelsPerMeter = 0;
	bmInfo.bmiHeader.biClrUsed	 = (bmBitmap.bmBitsPixel == 8) ? 256 : 0;
	bmInfo.bmiHeader.biClrImportant  = 0;

	// initialize color table - monochrome greyscale image
	for (DWORD i = 0; i < 256; i++)
	{
		bmInfo.bmiColors[i].rgbRed      = i;
		bmInfo.bmiColors[i].rgbGreen    = i;
		bmInfo.bmiColors[i].rgbBlue     = i;
		bmInfo.bmiColors[i].rgbReserved = 0;
	}

	hDC = GetDC(Handle);
}
//---------------------------------------------------------------------------

void __fastcall TShellForm::FormShow(TObject *Sender)
{
	DisplayTimer->Enabled = true;
}
//---------------------------------------------------------------------------

// draw video frame
void __fastcall TShellForm::DisplayTimerTimer(TObject *Sender)
{
    static unsigned char ThisShade = 127;

    memset(bmBitmap.bmBits,
           ThisShade++,
           bmBitmap.bmWidthBytes * bmBitmap.bmHeight);

    StretchDIBits(hDC,
		  0,
		  0,
		  ClientWidth,
		  ClientHeight,
		  0,
		  0,
		  bmInfo.bmiHeader.biWidth,
		  bmInfo.bmiHeader.biHeight,
		  bmBitmap.bmBits,
		  (BITMAPINFO *)&bmInfo,
		  DIB_RGB_COLORS,
		  SRCCOPY);
}
//---------------------------------------------------------------------------

void __fastcall TShellForm::FormDestroy(TObject *Sender)
{
	ReleaseDC(Handle, hDC);

	free(bmBitmap.bmBits);
}
//---------------------------------------------------------------------------
Re: Multi-thread OR Event-based?
#1761
Author: Bob Gonder
Date: Thu, 14 Jun 2007 21:06
17 lines
1550 bytes
Robert G. Hoover wrote:

> I must be missing something obvious...

I only see the obvious:
Never use the VCL OnCreate or OnDestroy events.
Always use the C++ Contructor and Destuctors instead.

Guessing Handle is not valid.
Maybe also Screen->Width; hasn't been set yet.

Also, not sure if
>	ClientWidth  = Screen->Width;
>	ClientHeight = Screen->Height;
include borders and titlebar.
That might affect the Blt as the destination size would be illegal.
You might look at   GetClientRect()
Re: Multi-thread OR Event-based?
#1764
Author: Jonathan Benedicto
Date: Thu, 14 Jun 2007 22:17
11 lines
1505 bytes
Robert G. Hoover wrote:
> Thanks SO much for your help. I'm still struggling with this whole
> thing. Can you have a look at this code? I've stripped out everything I
> can think of and reduced it to a single application thread by using the
> WM_TIMER event. I must be missing something obvious...

Just tried your code - worked fine in BDS2006 with Vista 64bit

However, like Mr Gonder recommended, never use OnCreate or OnDestroy.

Jon
Re: Multi-thread OR Event-based?
#1766
Author: Robert G. Hoover
Date: Fri, 15 Jun 2007 12:41
14 lines
1658 bytes
Well, the trouble is that it runs for a while.... sometimes 10 minutes
and sometimes 10 hours before I get one these weird Windows error
messages that suggest (to me) that out of bounds memory is being
referenced. Could this be a timing problem? I've got 4 brand new AOpen
XC Cube PCs running this test, 2 are Pentiums and 2 are DualCores.

CPP43.2G/7 Intel P4 640 3.2GHz S775 2MB (i915)

CPP43.0935 Intel Pentium D 935 3.2GHz 800FSB


Thanks again,

Rob
Re: Multi-thread OR Event-based?
#1768
Author: Jonathan Benedicto
Date: Fri, 15 Jun 2007 14:52
15 lines
1699 bytes
Robert G. Hoover wrote:
> Well, the trouble is that it runs for a while.... sometimes 10 minutes
> and sometimes 10 hours before I get one these weird Windows error
> messages that suggest (to me) that out of bounds memory is being
> referenced.

Perhaps the window handle is being re-created by the VCL, and causing this 
problem.

Can you add a button to the form, and on-click, call the RecreateWnd(); 
function.

Then, run the app, and click the button.

Jon 
Re: Multi-thread OR Event-based?
#1769
Author: Bob Gonder
Date: Fri, 15 Jun 2007 16:53
22 lines
1691 bytes

BAD_POOL_HEADER
Depends on the exact codes
http://msdn2.microsoft.com/en-us/library/ms793223.aspx
If Parameter 1 is 0x2 then maybe you wrote where you weren't supposed
to. You might not be error checking everything, especially when
aquiring new pointers.


IRQL_NOT_LESS_OR_EQUAL
Depends on the exact Stop code.
incompatible hardware or an incompatible device driver
http://support.microsoft.com/kb/311564
Bad driver:
http://support.microsoft.com/kb/293077


PAGE_FAULT_IN_NONPAGED_AREA
Hardware problem?
http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/w2000Msgs/6093.mspx?mfr=true
http://tinyurl.com/27rbs7
Re: Multi-thread OR Event-based?
#1778
Author: Robert G. Hoover
Date: Mon, 18 Jun 2007 17:30
16 lines
1485 bytes
Hi Bob,

Yep, I've got a growing list of these babies.... have a look.... :)

http://tritekcorp.com/errors.xls


Here's the list...

BAD_POOL_HEADER
DRIVER_CORRUPTED_EXPOOL
KERNEL_MODE_EXCEPTION_NOT_HANDLED
IRQL_NOT_LESS_OR_EQUAL
SYSTEM_THREAD_EXCEPTION_NOT_HANDLED
PAGE_FAULT_IN_NONPAGED_AREA
NTFS_FILE_SYSTEM
Re: Multi-thread OR Event-based?
#1781
Author: Bob Gonder
Date: Mon, 18 Jun 2007 22:40
29 lines
1863 bytes
Robert G. Hoover wrote:

>Here's the list...

Would be better if you posted the data in your message

BAD_POOL_HEADER	0x00000019		0x00000020
The pool entry that should have been found:	0x8533C450
The next pool entry:			0x8533C490
Reserved				0x0A080005
The pool block header size is corrupt..

DRIVER_CORRUPTED_EXPOOL*	0x000000C5
Memory referenced		0x00000002
IRQL at time of reference		0x0000002
1: Write				0x00000001
Address that referenced memory	0x8054A48F

>KERNEL_MODE_EXCEPTION_NOT_HANDLED
KERNEL_MODE_EXCEPTION_NOT_HANDLED*	0x0000008E
The exception code that was not handled		0xC0000005
The address at which the exception occurred		0xA96C82C5
The trap frame					0xA9687A34
reserved						0x00000000
		aswrdr.sys	A96C82C5	A96C8000

Are you using Avast Antivirus ?
If not, you are infected.
If you are, try turning it off.
Re: Multi-thread OR Event-based?
#1782
Author: Robert G. Hoover
Date: Tue, 19 Jun 2007 12:47
112 lines
3551 bytes
Hi Bob,

Yes, I have AVAST running on one of the machines...

Here's the list of errors.... I didn't post them before because I
thought maybe it was too much garbage that would just confuse things...
sorry....

I looked up the ones with the * beside them as the blue screen
originally didn't display a message, just the hex code. I may have made
an assumption about the hex codes.

Each message is followed by the Stop: hex code and then the 4
parameters. Some of them even specified the module which failed and gave
a few extra codes.

My apologies, but this seems to have turned into a hardware diagnosis
problem. Our PC manufacturer is blaming Micro$oft, Mozilla, Apple,
anyone who writes software. Personally, I think it's a driver problem.
I'm at the point where I'm going to upgrade every possible driver/bios
in hopes of resolving this. Thanks to you knowledgeable folks, we have
ruled out my software as the cause. BTW, Apple Quicktime and Firefox
streaming internet radio and/or video produces the same symptom. All our
suppliers are finger-pointing at each other...

Many thanks,

Rob



BAD_POOL_HEADER	
0x00000019		
0x00000020		
0x8533C450		
0x8533C490		
0x0A080005					

DRIVER_CORRUPTED_EXPOOL*	
0x000000C5		
0x00000002		
0x0000002		
0x00000001		
0x8054A48F					

KERNEL_MODE_EXCEPTION_NOT_HANDLED*	
0x0000008E		
0xC0000005		
0xA96C82C5		
0xA9687A34		
0x00000000		
aswrdr.sys	
A96C82C5	
A96C8000	
46360DB9

KERNEL_MODE_EXCEPTION_NOT_HANDLED*	
0x0000008E		
0xC0000005		
0xBF801DF6		
0xA9C09C48		
0x00000000		
win32k.sks	
BF801DF6	
BF800000	
45F013F6

KERNEL_MODE_EXCEPTION_NOT_HANDLED*	
0x0000008E		
0xC0000005		
0x8051C4F0		
0xA9C4CA80		
0x00000000		
			
IRQL_NOT_LESS_OR_EQUAL	
0x0000000A		
0xD955BFDD		
0x0000001C		
0x00000001		
0x80502926			
		
SYSTEM_THREAD_EXCEPTION_NOT_HANDLED*	
0x0000007E		
0xC0000005		
0x804FAC41		
0xF7AA3C1C		
0xF7AA3918					

PAGE_FAULT_IN_NONPAGED_AREA	
0x00000050		
0xDC92C344		
0x00000000		
0xBF806108		
0x00000000		
win32k.sys	
BF806108	
BF800000	
45F013F6

NTFS_FILE_SYSTEM*	
0x00000024		
0x001902FE		
0xA94DA3A8		
0xA94DA0A4		
0x805257FF					

KERNEL_MODE_EXCEPTION_NOT_HANDLED*	
0x0000008E		
0xC000001D		
0x805107A6		
0xA9E7FB84		
0x00000000					
Re: Multi-thread OR Event-based?
#1791
Author: Bob Gonder
Date: Tue, 19 Jun 2007 20:36
21 lines
1874 bytes
Robert G. Hoover wrote:

>Yes, I have AVAST running on one of the machines...

And...
Did you disable it to see if that was your problem?

>Here's the list of errors.... I didn't post them before because I
>thought maybe it was too much garbage that would just confuse things...
>sorry....

Error codes are almost always more descriptive than the error message.
(And the message can be seen when the error code is looked up)
But showing both is nice too.

>. BTW, Apple Quicktime and Firefox
>streaming internet radio and/or video produces the same symptom. All our
>suppliers are finger-pointing at each other...

Uninstall until the problem goes away.
Start with Avast.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads