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?
Author: Robert G. Hoover
Date: Wed, 13 Jun 2007 16:34
Date: Wed, 13 Jun 2007 16:34
102 lines
4338 bytes
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?
Author: JD
Date: Wed, 13 Jun 2007 17:02
Date: Wed, 13 Jun 2007 17:02
16 lines
1391 bytes
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?
Author: Robert G. Hoover
Date: Wed, 13 Jun 2007 17:22
Date: Wed, 13 Jun 2007 17:22
33 lines
2172 bytes
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?
Author: Jonathan Benedicto
Date: Wed, 13 Jun 2007 17:38
Date: Wed, 13 Jun 2007 17:38
22 lines
1951 bytes
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?
Author: Jonathan Benedicto
Date: Wed, 13 Jun 2007 18:26
Date: Wed, 13 Jun 2007 18:26
28 lines
2206 bytes
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?
Author: Jonathan Benedicto
Date: Wed, 13 Jun 2007 18:54
Date: Wed, 13 Jun 2007 18:54
9 lines
1350 bytes
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?
Author: JD
Date: Wed, 13 Jun 2007 19:37
Date: Wed, 13 Jun 2007 19:37
37 lines
2197 bytes
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?
Author: Robert G. Hoover
Date: Thu, 14 Jun 2007 14:57
Date: Thu, 14 Jun 2007 14:57
122 lines
4504 bytes
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?
Author: Bob Gonder
Date: Thu, 14 Jun 2007 21:06
Date: Thu, 14 Jun 2007 21:06
17 lines
1550 bytes
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?
Author: Jonathan Benedicto
Date: Thu, 14 Jun 2007 22:17
Date: Thu, 14 Jun 2007 22:17
11 lines
1505 bytes
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?
Author: Robert G. Hoover
Date: Fri, 15 Jun 2007 12:41
Date: Fri, 15 Jun 2007 12:41
14 lines
1658 bytes
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?
Author: Jonathan Benedicto
Date: Fri, 15 Jun 2007 14:52
Date: Fri, 15 Jun 2007 14:52
15 lines
1699 bytes
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?
Author: Bob Gonder
Date: Fri, 15 Jun 2007 16:53
Date: Fri, 15 Jun 2007 16:53
22 lines
1691 bytes
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?
Author: Robert G. Hoover
Date: Mon, 18 Jun 2007 17:30
Date: Mon, 18 Jun 2007 17:30
16 lines
1485 bytes
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?
Author: Bob Gonder
Date: Mon, 18 Jun 2007 22:40
Date: Mon, 18 Jun 2007 22:40
29 lines
1863 bytes
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?
Author: Robert G. Hoover
Date: Tue, 19 Jun 2007 12:47
Date: Tue, 19 Jun 2007 12:47
112 lines
3551 bytes
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?
Author: Bob Gonder
Date: Tue, 19 Jun 2007 20:36
Date: Tue, 19 Jun 2007 20:36
21 lines
1874 bytes
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