Problem with ASM and Threadsafe

Just starting out? Need help? Post your questions and find answers here.
nicolaus
Enthusiast
Enthusiast
Posts: 456
Joined: Tue Aug 05, 2003 11:30 pm
Contact:

Problem with ASM and Threadsafe

Post by nicolaus »

Hi Fred
If you wat compile this code with threadsafe enabled, it don´t go.
Without threadsafe it works fine!

Code: Select all

!EXTRN _PB_2DDrawing_GlobalStructure

Procedure StartDrawingEx(hWindow)
  Protected hdc.l
 
  hdc = GetDC_(hWindow)
 
  !MOV Eax, [p.v_hDC]
  !MOV [_PB_2DDrawing_GlobalStructure], Eax
 
  ProcedureReturn 1
EndProcedure

Procedure StopDrawingEx(hWindow)
  Protected hdc.l
 
  hdc = 0
 
  !MOV Eax,[_PB_2DDrawing_GlobalStructure]
  !MOV [p.v_hDC], Eax
 
  ReleaseDC_(hWindow, hdc)
EndProcedure

OpenWindow(0, 0, 0, 640, 480, "Test")

Repeat
  StartDrawingEx(WindowID(0))
  Box(10, 10, 400, 300, RGB(255, 0, 0))
  LineXY(200, 100, 250, 300, RGB(255, 255, 0))
  StopDrawingEx(WindowID(0))
  Delay(10)
Until WindowEvent() = #PB_Event_CloseWindow
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

With threadsafe, there is no global variable used for the context, all is located in a Thread Local Storage area (TLS). That's why your hack doesn't work in threaded mode as it has no effect.
nicolaus
Enthusiast
Enthusiast
Posts: 456
Joined: Tue Aug 05, 2003 11:30 pm
Contact:

Post by nicolaus »

Fred wrote:With threadsafe, there is no global variable used for the context, all is located in a Thread Local Storage area (TLS). That's why your hack doesn't work in threaded mode as it has no effect.
Aha ok but hafe you one more way for my prob like this http://www.purebasic.fr/english/viewtopic.php?t=24470 ?
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Thanks to the v4 Import/EndImport feature, we don't need ASM anymore to access the external variables. Here is your example adapted for v4, to work with and without threadsafe switch

Code: Select all

Structure PB_2DDrawingInfo
  *hDC
  ; There is more stuff here, but we try to keep this private
EndStructure


Import "kernel32.lib" ; It's not in the kernel32.lib, but it's the one always linked :)
  PB_2DDrawing_GlobalStructure.PB_2DDrawingInfo   ; For non-threaded
  PB_2DDrawing_Globals           ; For threadedsafe mode
  PB_Object_GetThreadMemory(*Globals)
EndImport


Procedure StartDrawingEx(hWindow)
 
  CompilerIf #PB_Compiler_Thread
  
    *Globals.PB_2DDrawingInfo = PB_Object_GetThreadMemory(PB_2DDrawing_Globals)
    *Globals\hDC = GetDC_(hWindow)
    
  CompilerElse
  
    PB_2DDrawing_GlobalStructure\hDC = GetDC_(hWindow)
    
  CompilerEndIf
 
  ProcedureReturn 1
EndProcedure

Procedure StopDrawingEx(hWindow)
 
  CompilerIf #PB_Compiler_Thread
  
    *Globals.PB_2DDrawingInfo = PB_Object_GetThreadMemory(PB_2DDrawing_Globals)
    ReleaseDC_(hWindow, *Globals\hDC)

  CompilerElse
  
    ReleaseDC_(hWindow, PB_2DDrawing_GlobalStructure\hDC)
    
  CompilerEndIf
  
EndProcedure

OpenWindow(0, 0, 0, 640, 480, "Test")

Repeat
  StartDrawingEx(WindowID(0))
  Box(10, 10, 400, 300, RGB(255, 0, 0))
  LineXY(200, 100, 250, 300, RGB(255, 255, 0))
  StopDrawingEx(WindowID(0))
  Delay(10)
Until WindowEvent() = #PB_Event_CloseWindow
nicolaus
Enthusiast
Enthusiast
Posts: 456
Joined: Tue Aug 05, 2003 11:30 pm
Contact:

Post by nicolaus »

Thanks for the very fast help!
It works perfect.
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Please note that you are messing with private PB internal and there is no warranty it will work forever. A new release can break that and you will have to adapt your code again.
nicolaus
Enthusiast
Enthusiast
Posts: 456
Joined: Tue Aug 05, 2003 11:30 pm
Contact:

Post by nicolaus »

Fred wrote:Please note that you are messing with private PB internal and there is no warranty it will work forever. A new release can break that and you will have to adapt your code again.
Ok but can you add in the next update for Win a function so that i can Draw at a Window wat is not create with PB functions?
The prob ist that StartDrawing wand the WindowOutpu() but a better way is that StartDrawing want the Handle of the window.

Wat is this WindowOutput() for a handle or so? How i can have this from a non PB createt window?
nicolaus
Enthusiast
Enthusiast
Posts: 456
Joined: Tue Aug 05, 2003 11:30 pm
Contact:

Post by nicolaus »

@Fred
With your Code (the DrawingEx functions) i have a smal prob.
All the drawing functions from PB works but not the DrawText() function.
The x and y param in the function DrawText() don´t work with the EX functions.
Example:

Code: Select all

Structure PB_2DDrawingInfo
  *hDC
  ; There is more stuff here, but we try to keep this private
EndStructure
Import "kernel32.lib" ; It's not in the kernel32.lib, but it's the one always linked :)
  PB_2DDrawing_GlobalStructure.PB_2DDrawingInfo   ; For non-threaded
  PB_2DDrawing_Globals           ; For threadedsafe mode
  PB_Object_GetThreadMemory(*Globals)
EndImport
Procedure StartDrawingEx(hWindow)
  CompilerIf #PB_Compiler_Thread
  *Globals.PB_2DDrawingInfo = PB_Object_GetThreadMemory(PB_2DDrawing_Globals)
  *Globals\hdc = GetDC_(hWindow)
  CompilerElse
  PB_2DDrawing_GlobalStructure\hdc = GetDC_(hWindow)
  CompilerEndIf
  ProcedureReturn 1
EndProcedure
Procedure StopDrawingEx(hWindow)
  CompilerIf #PB_Compiler_Thread
  *Globals.PB_2DDrawingInfo = PB_Object_GetThreadMemory(PB_2DDrawing_Globals)
  ReleaseDC_(hWindow, *Globals\hdc)
  CompilerElse
  ReleaseDC_(hWindow, PB_2DDrawing_GlobalStructure\hdc)
  CompilerEndIf
EndProcedure

If OpenWindow(0, 100, 200, 300, 200, "2D Drawing Test")
    If StartDrawingEx(WindowID(0))
      Circle(100,100,50,RGB(0,0,255))
      Box(150,20,20,20, RGB(0,255,0))
      FrontColor(RGB(255,0,0))
      For k=0 To 20
        LineXY(10,10+k*8,200, 0)
      Next
      DrawingMode(1)
      BackColor(RGB(0,155,155))
      FrontColor(RGB(255,255,255)) 
      ;here is the prob with DrawText(), the x and y cord´s dont work
      DrawText(20,150,"Hello, this is a test")
      StopDrawingEx(WindowID(0))
    EndIf
  Repeat
    EventID = WaitWindowEvent() 
  Until EventID = #PB_Event_CloseWindow  
EndIf
End
r_hyde
Enthusiast
Enthusiast
Posts: 155
Joined: Wed Jul 05, 2006 12:40 am

Post by r_hyde »

Hate to revive an old thread, but I would still like to know why DrawText() x,y coordinates don't work with this. If the problem could be solved, it would provide a fabulous way to render text directly onto an hbitmap without mucking about in api calls!
PureLust
Enthusiast
Enthusiast
Posts: 477
Joined: Mon Apr 16, 2007 3:57 am
Location: Germany, NRW

Post by PureLust »

Hi Fred,

thanks for the very nice example - it works fine under Windows.
But could you make this to work under Linux as well?

Code: Select all

Import "2ddrawing.a"
  PB_2DDrawing_GlobalStructure.PB_2DDrawingInfo   ; For non-threaded 
  PB_2DDrawing_Globals           ; For threadedsafe mode 
EndImport
Although we know and be aware that it may not work in further releases, it seems to be the only way (so far) to realise several things like this.

Anyway it would be the best if you can provide informations like this in an official and supported PB-way.
(Maybe via a Pointer to a copy of the PB-internal Structure or something like this. Also a Structure wich will be limited to special fields would help.)
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Re: Problem with ASM and Threadsafe

Post by DoubleDutch »

Fred: Any chance of an update of this routine for 4.40 or to build StartDrawingEx into the command set?
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
Post Reply