Page 1 of 1
Problem with ASM and Threadsafe
Posted: Sun Nov 05, 2006 12:31 pm
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
Posted: Sun Nov 05, 2006 12:41 pm
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.
Posted: Sun Nov 05, 2006 12:55 pm
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 ?
Posted: Sun Nov 05, 2006 1:20 pm
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
Posted: Sun Nov 05, 2006 1:28 pm
by nicolaus
Thanks for the very fast help!
It works perfect.
Posted: Sun Nov 05, 2006 3:37 pm
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.
Posted: Sun Nov 05, 2006 3:46 pm
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?
Posted: Sun Nov 05, 2006 5:47 pm
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
Posted: Wed Jul 18, 2007 2:05 am
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!
Posted: Wed Jul 18, 2007 5:06 pm
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.)
Re: Problem with ASM and Threadsafe
Posted: Fri Jan 08, 2010 5:13 pm
by DoubleDutch
Fred: Any chance of an update of this routine for 4.40 or to build StartDrawingEx into the command set?