My Application Currently Crashes as soon the GDI object count reaches to 8800,IS there any way or setting I need to do so that the consumption of GDI by TeeChart Can be less.
You can increment the limit of your GDI objects in your Ms Windows configuration
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724291(v=vs.85).aspx
But, as you indicated in your question, you should reduce their use. I had some problems with GDI objects when changing the format of a huge number of cells on a grid. You could try not changing many colors or fonts in your chart.
Try using GDI+ TeeChart canvas instead of GDI.
Related
Anyone experienced this problem? :
It appeared after Windows 10 update to build 1709.
After some system up time - a few hours -, bitmap loadings, imagelist item adding gets extremely slow. A 256x256 BMP loads in more than 10 seconds...while doing this, it occupies one CPU core 100%.
So compiled applications that start up normally in seconds now start up in minutes!
I use hibernation/resume regularly.
Display drivers are more than a year old, so that can't be the problem.
Any comment on this?
Update:
I found that this happens with code that use Canvas.Pixels, so that can be changed, still it slowed down very much.
Update 2:
Replacing with Scanline operations speeded up things. Recent Windows patch must have made Canvas.Pixels really slow on larger amount use.
GDI Canvas Pixels[x][y] is slow.
It performs many checks and color conversions you have no idea (it is literally tens of subcalls if not hundreds). That is why it is so slow it is not matter of Win10. this behavior is there all the time from windows start at least to my knowledge it is matter of GDI not VCL (it has nothing to do with Borland/Embarcadero VCL). So do not use Pixels[x][y] heavily. Even clearing 1024x1024 image this way can be a matter of around second on some machines...
VCL/GDI Bitmap ScanLine[y]
This is Borland/Embarcadero specific (on pure GDI you need to use bits locking instead). Each bitmap has this property/function which return pointer to raw data of the bitmap for any y. It is as slow as Pixels[y][x] but if your bitmap does not change its pixel format nor it is resized then the pointer is still the same.
This can be used for direct pixel access without any performance hits. You just remember all lines at each bitmap resize/reload into own array like. And afterwards use just that. That is usually up to ~10000x times faster then Pixels[x][y] if used properly.
I usually copy ScanLine pointers to my own array in C++ like this:
// ok lests have some bitmap
Graphics::TBitmap *bmp=new Graphics::TBitmap;
bmp->Width=100;
bmp->Height=100;
// this is needed for direct pixel access after any LoadFromFile, Assign or resize
bmp->HandleType=bmDIB; // allows use of ScanLine
bmp->PixelFormat=pf32bit; // 32bit the same as int so we can use int* for pixels pointer
DWORD **pyx=new DWORD*[bmp->Height];
for (int y=0;y<bmp->Height;y++) pyx[y]=(DWORD*)bmp->ScanLine[y];
// now we can render pixels fast like this:
pyx[10][20]=0x0000FF00; // green dot at x=20, y=10
// and also read it back fast:
DWORD col=pyx[10][20];
So port it to Delphi. Just beware that on some pixel formats the colors are RGB instead of BGR (or vice versa) so in some cases you need to reverse R,G,B order of colors (especially the predefined ones).
As there are no checks so DO NOT ACCESS PIXELS OUTSIDE BITMAP it would most likely throw an access violation.
And lastly do not forget to release the pyx array when not needed anymore (or before new allocation)
I have recently updated my delphi from XE4 to XE6, but it is extremely slow to plot points using the TPointSeries series. I noticed the points to be anti-aliased, so I disabled that using chart_radar.Canvas := TTeeCanvas3D.Create. The anti-aliasing effect is gone, but the drawing of points remains slow.
Any idea what causes this change in efficiency and how to speed up drawing the points?
I have an application that creates 3D motion on a TPaintBox Canvas using native Delphi code. In the old code I rendered the 3D image to a temporary TBitmap on a Timer event. In the TPaintBox OnPaint() event I would BitBlt() the temporary TBitmap the TPaintBox's Canvas. This approach worked fine but the motion was jerky.
Because I was not happy with the smoothness of the motion I decided to try "rendering" instead to a very large workspace bitmap and then down-sample it to the TPaintBox Canvas. To do the re-sampling I used the Graphics32 library which I read about here:
Scale an image nicely in Delphi?
I changed my code to render to a large TBitmap32 (1100w x 1100h) and then when I down-sample it I use a Graphics TKernelResampler object with a TLanczosKernel kernel to do the down-sampling to another TBitmap32 that is the exact same size as the TPaintBox Canvas and call the TPaintBox's Refresh method. In the TPaintBox OnPaint event I BitBlt() the down-sampled TBitmap32 to the TPaintBox Canvas.
This works but the problem is I only see repaints when the Form that owns the TPaintBox requires a repaint, a problem I did not have with the old code despite the face that I call the Refresh method on the TPaintBox right after I'm done rendering to it, as I said. As a validity test I called SaveToFile() on both the large hi-res TBitmap32 object and the smaller TBitmap32 object I use for pre-rendering. The bitmaps showed that indeed the frame had not changed in content at all between Timer events so it's not a weird Repaint related issue, at least not with the TPaintBox component.
If I invalidate the Form's Canvas by moving the Form or overlaying any part of it's client area with another form, then the content of the TBitmap32 objects do update and so do the bitmap images I save to disk as a check.
It's as if the Graphics32 TBitmap object's themselves need to be invalidated so that the new content I rendered to the large hi-res workspace is updated. However, TBitmap32 has no such invalidate/refresh call.
If anyone out there is experienced with the Graphics32 library and can tell me why I'm only seeing the images change when the Form requires a repaint or has it's client area invalidated then I would appreciate that.
This ended up being a prime example of how somehow the symptoms can look like a problem that is completely different than the one you are actually having. Despite the fact that the CPU utilization on my quad core and on only one processor never exceeded 25%, it turned out that the lack of updating was due to a processing (not processor) overload somewhere in the graphics handling chain. I still don't know exactly where, perhaps something in the dark recesses of the Windows graphics libraries. But once I eased up the processing load everything started updating perfectly. It turned out that trying to run the Graphics32 library TLanczos kernel resampler 20 times a second on a large bitmap was too much for the windows graphics system to handle. If I slowed the frame rate (renders per second) down to 4 times a second than suddenly updates started happening normally. By swapping out the TLanczos kernel resampler for the much faster draft resampler, I was able to go back to updating 20 times a second with excellent visual aesthetic quality. I guess when I moved or resized the host window, that gave the graphics sub-system enough time to catch up and update properly so that's why I saw the updates after doing that.
My whole experience with direct use of graphics consists of drawing shapes using Turbo Pascal’s gdi unit on a 386 machine ages ago, finding it unbearably slow and never giving it a second thought. In other words, I have next to no idea where to begin.
For a simple Internet radio player application, I would like to design a graphic display somewhat similar to Winamp (but a bit larger and easier on the eyes, since the illegibility of such displays is one reason I’m trying to do my own).
Simple graphic components like those imitating LED displays are nowhere near sufficient, of course. I don’t expect to be drawing clickable UI controls, and certainly not skins – just the readout, with text, digits and a few symbols. I understand Delphi 2010 supports Direct2D, but I only have D2009.
What are my options? Are there any 3rd party components that would help?
On edit two small points. I need the drawing to be flicker-free (i.e,, unlike what I experienced all those years ago in Turbo Pascal :-). Is TCanvas going to be fast enough for that? Also, I would probably want to use alphablending, which I don't think I can get with the basic TextOut, LineTo etc. graphics API. (I just don't know what's possible). What about GDI+?
A library for fast 2D graphics for Delphi is available as open source on Sourceforge:
Graphics32 (home page: http://www.graphics32.org/)
Graphics32 is a graphics library for
Delphi and Kylix/CLX. Optimized for
32-bit pixel formats, it provides fast
operations with pixels and graphic
primitives. In most cases Graphics32
considerably outperforms the standard
TBitmap/TCanvas methods.
Features Some of Graphics32 features include:
Fast per-pixel access up to 100 times faster compared to standard TBitmap;
High-performance Bitmap alpha blending (including per-pixel alpha blending);
Pixel, line and polygon antialiasing with sub-pixel accuracy (combined with alpha blending);
Arbitrary polygon transformations and custom fillings;
Bitmap resampling with high quality reconstruction filters (e.g. Lanczos, Cubic, Mitchell);
A unique state-of-the-art rasterization system;
Affine transformations of bitmaps: rotations, scaling, etc with sub-pixel accuracy;
Arbitrary projective transformations of bitmaps;
Arbitrary remapping transformations of bitmaps (e.g. for Warping, Morphing);
Flexible supersampling implementation for maximum sampling quality;
Flicker-free image displaying components with optimized double buffering via advanced MicroTiles based repaint optimizer;
Multiple customizible easy-to-use overlay layers;
Locking of bitmaps for safe multithreading;
A property editor for RGB and alpha channel loading;
Design-time loading of image formats supported by standard TPicture;
Works on Borland Delphi, C++ Builder and Kylix (The last version that supported Kylix was 1.8.3).
As of version 1.5.1b Graphics32 is licensed under the terms of the Mozilla Public License.
Take a look at TCanvas. It's built into most visual controls and contains easy methods for the sort of simple drawing you're looking at, without the need for mucking around with DirectX or OpenGL. If you want a really simple surface you can draw on, place a blank TImage TPaintBox on the form and use its Canvas as your drawing surface.
Mostly I agree with Mason and the comments. TPaintBox is a very simple component really. You implement the OnPaint event and are in complete control. It is fast enough on a fast-enough machine.
Put it on a TScrollBox and you don't even need to worry about where the user has scrolled to :)
Make sure you check out the DoubleBufferred property of the parent control(panel/ScrollBox).
If it is a complex drawing/graphic also check out InvalidateRect - this controls which area of a canvas is redrawn.
Of course like all graphics/drawing it gets pretty complicated pretty quickly :(
Just saw your edit. If you need alpha blending and flicker-free drawing, TCanvas is probably not going to be good enough for you. You should look at components that wrap OpenGL or Direct3D and provide you a high-power graphics canvas.
One such package is Asphyre, though I'm not sure if they have a version that works on Delphi 2009+ yet. I've also got a custom-built library that wraps SDL 1.3 and gives you a drawing frame component you can place on a Delphi form. It does work on Delphi 2009 and later, but I haven't released it as its own package yet. You could find it if you dig around in the SVN archive of my game engine, but if you can wait a day or two I could try to get it made into an easily-usable BPL component package and available for download.
I am looking for a graphical component in Delphi winch have such features:
allows to paint text in different font types, sizes and colors
allows to select previously drawn text and copy it
paints images on a given coords, gif support would be nice
its very fast in terms of CPU usage
I need this component as a main chat window. I don't want to use it as a text editor.
I've tried two solutions so far:
TVirtualStringTree
THtml
Currently I am using THtml. It performs quite nice but it is a bit to slow due to two facts:
It supports many features which are not necessary in my case
Each time I want to add some content to it, I must reload the whole content
I really don't want to go into its sources and modify them until I have no other choice. So maybe someone of you knows some nice lightweight component which I can use instead?
Take a look at TRichView. It's derived from TCustomControl so no external dependencies. It's third party commercial component, but a very good one. Skype Win client uses it.
What about a TRichEdit? Most of the things you mention should be easiliby possible with this component.
Concering the insertion of a bitmap, see this article on Delphi 3000.
Did you consider using TWebBrowser?
At least it ticks all your boxes...