ImageOutput in threads

Just starting out? Need help? Post your questions and find answers here.
Hugo
New User
New User
Posts: 6
Joined: Fri Nov 25, 2005 8:46 am
Location: Germany

ImageOutput in threads

Post by Hugo »

If I use StartDrawing(ImageOutput(#Image3)) in a tread and 'create threadsave executable' is activated, the debugger shows the error message: The specified output is NULL.

The reason for this is that ImageOutput(#Image3) returns 0.

It works without any problems when I disable 'create threadsave executable'.

So at the moment it's not possible for me to use 2D drawings to an image inside a thread.

Code: Select all

#WindowMain    =  1
#Image3        =  3
#ImageGadget   = 22

Global gBY_Exit.b
;Global gMX_Image3.l

Procedure MainThread( wert )
  
  ;LockMutex( gMX_Image3 )
  Debug "2. ImageOutput: " + Str( ImageOutput( #Image3 ) )
  ;UnlockMutex( gMX_Image3 )
   
  Repeat
    Delay(10)
  ForEver
  
EndProcedure


If OpenWindow( #WindowMain, 100, 100, 500, 400, "Test", #PB_Window_SizeGadget | #PB_Window_SystemMenu )

  CreateImage( #Image3, 200, 200 )
  ;gMX_Image3 = CreateMutex()
  
  If CreateGadgetList( WindowID( #WindowMain ) )
     ImageGadget( #ImageGadget, 20, 20, 200, 200, ImageID( #Image3 ) ) 
     
     ;LockMutex( gMX_Image3 )
     Debug "1. ImageOutput: " + Str( ImageOutput( #Image3 ) )
     ;UnlockMutex( gMX_Image3 )
        
     CreateThread( @MainThread(), 0 )
     
     Repeat
       Select WaitWindowEvent()
         Case #PB_Event_CloseWindow  : gBY_Exit = #True
       EndSelect
        
     Until gBY_Exit
        
  EndIf
  
EndIf
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Threadsafety means image #s are maintained separately between main program and thread. You can reuse #image3 in your thread, even set it to a different image if you want. All you have to remember is that images created in the main program belong to the main program, and if you want to access them in a safe thread, you have to initialize them there, too. It's for all intents and purposes a separate program. It's a good thing, not a bug!
BERESHEIT
Hugo
New User
New User
Posts: 6
Joined: Fri Nov 25, 2005 8:46 am
Location: Germany

Post by Hugo »

Ok, if this is the case, how can I initialize the image in the thread so I can access it form both the main program and the thread?

One other point here is that IsImage(#Image3) gives true back in the tread.
Fred
Administrator
Administrator
Posts: 18350
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

I think it's a bug, i will take a closer look.
Fred
Administrator
Administrator
Posts: 18350
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

My bad, you can't access to the same image in 2 differents threads. It's possible to draw to 2 differents images tough.
freak
PureBasic Team
PureBasic Team
Posts: 5946
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

The problem in your code is that ImageOutput() cannot be used on its own.
You have to use it together with StartDrawing() and call the proper StopDrawing()
again before you can use the image again with StartDrawing()
Otherwise the image is not properly released from the device context used
for the drawing and it cannot be reused in another thread.


This works just fine:

Code: Select all

#WindowMain    =  1
#Image3        =  3
#ImageGadget   = 22

Global gBY_Exit.b
;Global gMX_Image3.l

Procedure MainThread( wert )
 
   If StartDrawing(ImageOutput(#Image3))
     Debug "2: OK"
     
     Line(0, 0, 200, 200, $FFFFFF)     ; test the drawing   
     StopDrawing()
     
     SetGadgetState(#ImageGadget, ImageID(#Image3)) ; update the gadget
   Else
     Debug "2: FAILED"
   EndIf  
   
  Repeat
    Delay(10)
  ForEver
 
EndProcedure


If OpenWindow( #WindowMain, 100, 100, 500, 400, "Test", #PB_Window_SizeGadget | #PB_Window_SystemMenu )

  CreateImage( #Image3, 200, 200 )
  ;gMX_Image3 = CreateMutex()
 
  If CreateGadgetList( WindowID( #WindowMain ) )
     ImageGadget( #ImageGadget, 20, 20, 200, 200, ImageID( #Image3 ) )
     
     If StartDrawing(ImageOutput(#Image3))
       Debug "1: OK"
       StopDrawing()
     Else
       Debug "1: FAILED"
     EndIf
     
     CreateThread( @MainThread(), 0 )
     
     Repeat
       Select WaitWindowEvent()
         Case #PB_Event_CloseWindow  : gBY_Exit = #True
       EndSelect
       
     Until gBY_Exit
       
  EndIf
 
EndIf 
quidquid Latine dictum sit altum videtur
Post Reply