Developer Delphi / C ++ Windows 10 1709 raster operations extremely slow

Has anyone experienced this problem?

It appeared after updating Windows 10 for assembly 1709. After some time of the system operation - several hours - bitmap download, adding elements in the "imaginary" style becomes extremely slow. 256x256 BMP boots in more than 10 seconds ... while it occupies one central core 100%. Thus, compiled applications, which usually start in a matter of seconds, start in a matter of minutes!

I regularly use hibernation / resume. Drivers are older than a year, so this may not be a problem.

Comment on this?

Update: I found that this happens with code using Canvas.Pixels, so it can be changed, but it slows down a lot.

Update 2: Replacing with Scanline operations sped up. A recent Windows patch was to make Canvas.Pixels very slow when using more.

-1
source share
1 answer
  • GDI Pixels[x][y] canvas is slow.

    It performs many checks and color conversions that you don’t know about (literally dozens of jokes, if not hundreds). That's why it is so slow, it is not a Win10 question. this behavior always comes from windows, at least as far as I know, this is not a GDI VCL question (it has nothing to do with Borland / Embarcadero VCL ). Therefore, do not use Pixels[x][y] heavily. Even clearing a 1024x1024 image this way can be a matter of a second on some machines ...

  • VCL / GDI ScanLine[y]

    This is Borland / Embarcadero (for pure GDI you need to use bit lock). Each bitmap has this property / function that returns a pointer to the raw bitmap data for any y . It is as slow as Pixels[y][x] , but if your bitmap does not change its pixel format and does not change, then the pointer is still the same.

    This can be used for direct access to pixels without any performance issues. You just remember all the lines in each raster size / reload into your own array. And then use just that. This is usually up to ~10000x times faster than Pixels[x][y] when used properly.

    I usually copy ScanLine pointers to my own array in C ++ as follows:

     // 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 move it to Delphi. Just beware that in some pixel formats, the colors are RGB instead of BGR (or vice versa), so in some cases you need to cancel the R, G, B colors (especially the predefined ones).

    Since there are no checks, therefore PIXELS ARE NOT AVAILABLE FOR EXTERNAL BITS , most likely, this will lead to access violation.

    And finally, don't forget to free the pyx array if it is no longer needed (or before the new distribution)

+3
source

Source: https://habr.com/ru/post/1262300/


All Articles