Silverfrost Forums

Welcome to our forums

Draw_Filled_Polygon

12 Apr 2013 2:18 #12041

I am using the Draw_Filled_Polygon routine to write to an RGB Virtual Screen many thousands of times (5k-20k polygons, sometimes the same shape and sometimes different) with each draw being of a different colour (up to 20000 colours). This works fine but depending on the code used there does seem to be a limit (typically around 5000 or 10000) draw executions after which the error 'Unable to create polygon' occurs.

In 'the old days' I seem to remember the need to delete drawn regions and wondered if the above behaviour may be memory related? I can probably find an alternate way around the problem if I have to. I am not using the latest compiler version at present.

Any ideas would be gratefully received.

Thanks, Bill

12 Apr 2013 3:27 #12042

Bill,

This is just a guess. As there is a filled polygon method in the GDI, it is probable that FTN95's routine is simply a wrapper for the GDI function (Paul may know). In that case, it is unlikely that Clearwin is allocating memory for polygons and creating a memory leak. Also, you aren't going to get any benefit from writing your own polygon fill routine, using (say) the code in Angell and Griffith's book, as this is likely to be slower.

Have you tried 'printing' the polygon vertex coords to a file to see if they are all valid? You may need to do 2 passes through your routine while testing, once to generate and store the coords without drawing, and once with drawing (which will produce the crash, but at least you will know which polygon did it - with one pass, you won't see the last few polygons in your file).

It seems more likely to me that there is something about your cords that prevents forming a polygon than something in the GDI (such as the limit on number of polygon vertices of 8192 that existed in Win 98/Me but has since been lifted).

Eddie

12 Apr 2013 3:36 #12043

Hi, Thanks for the quick response.

I had printed out the co-ordinates exactly as per your suggestion and all are fine. Most polygons have 4 or 5 vertices at most - running on Windows 7 by the way.

Thank again.. Bill

12 Apr 2013 3:41 #12044

ClearWin+ keeps a pen for each colour so memory overflow is a real possibility. Can you monitor memory usage?. I have had a quick look and cannot see any leaks so far.

12 Apr 2013 4:04 #12045

Thanks Paul, very useful.

I think I can overcome this by using 2 virtual screens and limiting the colours on each to (say) 256 - but I didnt want to go that route if there might be some other reason for the problem [the screen - colour variables - are used for reference purposes]

Thanks again - Bill

12 Apr 2013 5:43 #12046

It might be worth my adding an internal limit to the number of pens that ClearWin+ keeps before discarding old ones. I just need to be reasonably sure that this is the problem.

Can you get some idea from the Windows Task Manager about memory usage?

12 Apr 2013 6:22 #12047

Can you post small example of using virtual screen (for smooth 2D plotting i suppose)?

12 Apr 2013 7:59 #12049

Paul,

Is this related to the limit on number of GDI handles per process (65536 - or less on Windows 2000)? If so, a useful test would be to execute on Windows 2000 and see if it went wrong earlier. That assumes Bill has access to a Win 2000 machine - not likely perhaps. If it were the GDI handles limit, then there isn't a limit on the number of pens per se, but it rather depends on what other GDI objects there are using up the available handles. In any case, Bill might be advised to use fewer colour steps.

Does OpenGL suffer from a related limitation?

Eddie

13 Apr 2013 10:25 #12050

Paul / Dan - Example below, here writing to the real screen. Memory does not seem to be the issue though?...

Example code (here to the real screen) below:

Blows up at 9000 odd - but other versions (the original) blew up earlier.

c c simplified program to recreate error when using a large number of different colours c winapp options(intl) include <windows.ins> external quiter common /closing/ ictrl1,ictrl2,iquit dimension ix(4),iy(4) c c set up whole screen as RGB graphics area and colour black
c ixscrn = clearwin_info@('screen_width') iyscrn = clearwin_info@('screen_depth') idscrn = 1 iwiw = winio@('%ww[naked]%`gr&',ixscrn,iyscrn,idscrn) iwiw = winio@('%lw',ictrl1) call use_rgb_colours@(1,1) call draw_filled_rectangle@(0,0,ixscrn,iyscrn,0) c c set up button / parameter to close program c iquit = 0 ixbut = ixscrn*0.75 iybut2 = iyscrn * 0.83 iwiw = winio@('%sp&',ixbut,iybut2) iwiw = winio@('%ww[naked,topmost]%^tt[Quit]&',quiter) iwiw = winio@('%lw',ictrl2) c c
c call select_graphics_object@(1) call perform_graphics_update@ c c draw a 250 x 200 grid of rectangles each in a new colour (indexed by k) c c (we draw them as polygons as the original program involved both c rectangles and parallelograms) c k = 0 do 10 i = 1,250 ix(1) = (i-1)*6 + 1 ix(2) = ix(1) + 5 ix(3) = ix(2) ix(4) = ix(1) do 20 j = 1,200 k = k + 1 c c convert integer k to standard RGB match by extracting c the 3 8-bit codes for blue, green and red c (note the error occurs in the same place if we use kol = k) c kolb = mod(k,256) kolg = mod(intl(k/256),256) kolr = int(k/256**2) kol = rgb@(kolr,kolg,kolb) c c set up 4 corners of rectangular polygon and draw c iy(1) = (j-1)*5 + 1 iy(2) = iy(1) iy(3) = iy(1) + 4 iy(4) = iy(3)
call draw_filled_polygon@(ix,iy,4L,kol) c c c 20 continue call perform_graphics_update@ 10 continue c c hold image on screen until quit button is activated c 100 if(iquit .eq. 1)then ictrl1 = 0L call window_update@(ictrl1) else call yield_program_control@(y_temporarily) goto 100 endif end c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c call back for quit ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c subroutine quiter common /closing/ ictrl1,ictrl2,iquit iquit = 1 ictrl2 = 0L call window_update@(ictrl2) return end

13 Apr 2013 11:28 #12051

The problem is solved if I prevent ClearWin+ from saving the HBRUSH for the colour. As it is, it is running out of space for Windows resources (i.e. a system failure).

I will fix this and let you know when a new DLL is available for download. Probably early next week.

13 Apr 2013 12:45 #12052

Dear Paul,

What service - Many thanks for finding the problem and for the future solution.

All the best

Bill

Someone might be asking - Why does he need to use 20,000 colours and as the idea might help someone else!:

On the real screen I build up a drawing of a 3D picture of a loaded shipping container containing crates and drums etc loaded in an efficient way drawn using a SMALL number of colours. There can be up to 20,000 items and space on screen obviously does not allow detailed labels on these. The user can use the mouse to point at any of these and as the mouse moves over each 'crate' a detailed description is displayed on screen. To identify which crate is being pointed at, the same picture is drawn on a virtual screen but using a unique colour (1-20000) thus providing a reference.

15 Apr 2013 7:28 #12058

I have uploaded a beta version of salflibc.dll to http://www.silverfrost.com/beta/salflibc.exe

This is a self-extracting archive. Remember to keep a backup of the current DLL. You may need to have Administrator privileges in order to copy the DLL and LIB to your FTN95 folder.

15 Apr 2013 9:56 #12059

Many thanks for this Paul.

I have used the DLL with a ready compiled version of the real program (compiler 5.5) that was failing 'reliably' with a given dataset (5000+ colours) and all worked fine.

However when I extended (doubled) the number of loaded units (10,000 colours) once again the program crashed out in a similar fashion as before. I will have to examine which routines in addition to draw_polygon I am calling repeatedly and try to produce a further simple program to illustrate the problem to see if there is any solution.

Thanks again.. Bill

ps. If you can indicate via PM or otherwise how I can under Windows 7 identify which type of resources visible under Windows Task manager I should be looking at to spot up-coming problems that would be most helpful.

15 Apr 2013 11:36 #12060

I would try something like 'GDI objects'.

In the current fix I have avoided the ClearWin+ cache for HBRUSH objects. If you also have a large number of HPENs (for drawing lines) then the problem will occur there also.

15 Apr 2013 12:56 #12062

Thanks Paul, very useful to know what to look for as it shows that I hit the Windows 10000 GDI objects limit at exactly the point of crashing.

I will have to look carefully at the code to see what additional routines I use a large number of times and see if any of these might be avoided (doubtful) or substituted and report back to this thread in due course.

Thanks again, Bill

15 Apr 2013 2:15 #12064

Bill

You don't need to replace these routines. I can fix similar problems in other places. ClearWin+ should allow you to call these routines any number of times. Just let me know which routine(s) are causing a problem.

16 Apr 2013 8:13 #12071

I have sent you a PM with a minor update to the original program posted above for which you provided a DLL update which showed some improvement.

In the update I create a virtual region in addition to the real screen and in turn write the draw_filled_polygon to each. Whilst the write to the real screen does not add to the GDI count that to the virtual region adds +1 on each call thus crashing eventually

I am pleased to say that this is really the only routine I use 'in anger' in my real program.

Thanks

Bill

16 Apr 2013 11:02 #12076

I have uploaded a new DLL to the same place. This includes a more comprehensive fix for this problem.

ClearWin+ now limits the number of cached GDI objects to a little under 10000 which is the default limit for Windows 7.

I have added a routine that allows the user to set this maximum to another value.

16 Apr 2013 11:12 #12077

Once again many thanks

First tests on both demo program and real program seem fine.

Will spend time doing more exhaustive tests and report back

Thanks again

Bill

Paul: All tests I have done to date have worked fine.

From what I can see from the GDI behaviour (on my full program), whilst the GDI count does rise eventually to hit the 10,000 limit once this is reached the complete 'buffer' is cleared and the count re-starts. As 10,000 is the limit on Windows XP and later then this should be fine.

Please login to reply.