Drawing of Controls too slow

  • My application consits of one form with several PictureBoxes in it. When opening the application the PictureBoxes are drawn realy slow, one after the other....
    This is only a test application for futher developments where we want to use a lot of controls using images. I tested it with several types of pictures (*.png, *.gif) and all variants were too slow.


    In the normal .net Framework there is the possibility to double buffer the form, but in the compact framework 2.0 which we are using this function is not supported...


    Some ideas, or someone who had the same problem???


    thx a lot...

  • Windows CE is a demand paged OS. This means an application is not loaded into memory and then executed after that. But instead the executable file is only mapped to a virtual memory region with all memory pages marked as invalid. This means each page of the mapped memory region in RAM is marked to refer to a region in the file, but nothing is actually loaded yet. Then the code is already started. The CPU now tries to load data (program code) from the referenced memory, but the page is marked invalid. This is called a "page fault" and triggers an exception. The exception handler routine is part of the virtual memory system of the OS and now actually loads the page from the file to physical memory. Then the CPU can continue executing the code until it again hits a page that is not yet in memory. This again triggers a page fault and the corresponding page is loaded from the file to memory. You see, the pages are loaded when they are "demanded" by the program, hence the name "demand paged OS". After a while the whole program code has found its way into the physical RAM.


    There are two reasons for doing this:


    • The program starts faster as not all of the code must be loaded before the first screen shows up, just the code required to do this. However the program itself runs a little bit slower until the code is completely loaded and available in RAM. In fact if you select some function in your program for the first time, it may have a longer delay as usual until you see the result, because of course the code pages for this function must be loaded first. On the other hand if you don't need all functions of your program during this run, the code for these function never needs to be loaded and does not waste physical RAM.



    • Pages can be phased out to backing store (swap space) if memory is low. Then you can use more virtual memory than you actually have as physical memory in your device. (However this is usually not done on an embedded system because there is no hard disc and only little flash memory that could be used as swap media.)


    The same mechanism happens when you load a bitmap image with the built-in functions. The image is not actually loaded, but it is only mapped to virtual memory. Then when the image is finally drawn to the display and the image data must be copied from the assigned memory region of the image to the frame buffer, this triggers again a lot of page faults and page by page the image data is loaded from the referenced file to the memory. This is the slow appearance that you realize, as the image is loaded from the file to memory in exactly that moment.


    To avoid this, you simply have to request the images once before you need them. For example by copying them to an auxiliary image buffer before you actually draw them on the display. You can throw away that auxiliary buffer after having copied the images to it. But by doing this, the images have already been loaded into physical RAM and are readily available. And if you show your screen now, the images should be visible immediately as no loading from file is involved now anymore. However -- you may have guessed it -- you pay this "appearance speed" with a longer delay before you see any screen at all because the loading delay now happens when you copy the images to the auxiliary buffers before you show your screen. That is always the trade-off between demand paged access and pre-loaded access. The overall time from start of the program until the screen is completely drawn should be more or less the same, but in one case, you see it a little bit earlier but the appearance of the images is slow, and in the other case you see the image a little bit later, but the images appear fast. You have to decide what version looks better.


    Your F&S support team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • thx for the detailed answer!
    In my application all pictures are loaded in the constructor of the form, so no loading should be performed when Painting. I don't care about how long my application needs to start, my problem is that i can see each picture box being drawn. I don't want the picture boxes to drop in one after the other. I want all controls to appear at once! How can i achieve this? I think some sort of double buffering of off-screen picture would help, do you have any ideas how to do that?

  • Quote from "Klaus_Sch"

    In my application all pictures are loaded in the constructor of the form, so no loading should be performed when Painting.


    But that's exactly my point. Even if the function is called "LoadPicture" or similar, the file is only mapped and the data is *not* loaded to memory yet. Only finally when the form is displayed, the pixel data of the image is actually accessed. Previously only some meta data like image size and bit depth is loaded. But the actual pixel data was not loaded earlier as it was never needed right up to the point where the image is actually drawn to the display by Form1.


    Try this: in the constructor, create some bitmap object, capable of holding the largest of your images. Then loop over all the images and actually copy the pixel data of the image to this dummy bitmap, for example using some bitblt function. Then throw away the bitmap before leaving the constructor. I guess you will be surprised.


    Your F&S support team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • I created two bitmaps in the constructor, one i want to use the other one for preloading. Then i used the BitBlt function to copy the pixel data into the preload bitmap. I assigned the first bitmap to all of my picture boxes and deleted the preload bitmap afterwards. BUT no improvement :(
    I also tried to copy the pixel data with the use of a Graphics object, but also no improvement...

  • Hello,
    which HW you are using?
    can you post the "BitBlt" code you are using above?

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • hi,
    i am using the Net8DCU board with WinCE 5.0


  • Shouldn't this be something like

    Code
    1. BitBlt(hdc_pre_img, 0, 0, 100, 100, hdc_img, 0, 0, 0xcc0020);


    with the image size in parameters 4 and 5? In your case with width and height set to zero, nothing was actually copied and therefore the original image still was not loaded.

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • omg!
    yes you are right this is will not work....


    anyway i fixed this bug, but no positive effects...


    I tested if the image is painted into the preload image by drawing the preload image into the form.

  • Quote from "Klaus_Sch"

    anyway i fixed this bug, but no positive effects...


    I tested if the image is painted into the preload image by drawing the preload image into the form.


    Hmm, then I'm out of ideas. Have you tried to use the preloaded image instead of the original image? Is this still slow?


    We had similar problems with our SlideShow program. This is a program that shows some predefined images in an endless loop on the screen, e.g. for demo purposes. The first time the images were shown were completely slow, later loops were remarkably faster. Here copying the image before showing it the first time brought the requested speedup. However this was coded in C/C++ directly under Win32 API. But I can't imagine that using a .NET form should work in a completely different way. In the end the same underlying mechanisms should apply. Unless we are interpreting the slow appearance in the wrong way and the problem is not the demand paged loading at all... But what else?

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Maybe the problem is in the windows code....
    Based on the results of my test i think the drawing itself is not the problem. I think its the time between the OnPaint() methodes of the controls.


    Do you know a way to maualy implement the .net form double buffer? Maybe this would be the slution but double buffering is not supported in the .net CF

  • You could try to replace the GC (graphics context) of the Form with a GC for a bitmap. Instead of drawing the form on the screen, WinCE would draw it into the bitmap, and when done, you can copy it to the screen. Then you must switch back the GC to the original one for that WinCE uses the screen again for any further updates. However right now I can't estimate if this can easily be done or if there will be some problems.

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.