Page 1 of 3
FastImageOutput
Posted: Sat Jun 17, 2006 7:52 pm
by S.M.
Code: Select all
Structure DrawingInfoStruct
Type.l
Window.l
DC.l
ReleaseProcedure.l
PixelBuffer.l
Pitch.l
Width.l
Height.l
Depth.l
PixelFormat.l
StopDirectAccess.l
StartDirectAccess.l
EndStructure
Global FastImgOutputID.DrawingInfoStruct
Procedure ___ReleaseFastImageOutput()
If FastImgOutputID\DC:DeleteDC_(FastImgOutputID\DC):FastImgOutputID\DC=0:EndIf ; free the created memory DC
EndProcedure
Procedure ___StopDirectAccess()
ProcedureReturn FastImgOutputID\DC
EndProcedure
Procedure ___StartDirectAccess()
GetPixel_(FastImgOutputID\DC,0,0) ; make sure all GDI operations are finished
ProcedureReturn FastImgOutputID\PixelBuffer
EndProcedure
; FastImageOutput() provides a faster pixel access for 32-,24- and 15 bit images(DIBSesctions).
; However, for now only plot(x,y,color) works faster. (point(x,y) seems to be not optimized for direct memory access at the moment. You can use the PointFast() command from the E2D Userlib to get a faster point command.)
Procedure FastImageOutput(Image)
If GetObject_(ImageID(Image),SizeOf(DIBSECTION),ds.DIBSECTION)=0
ProcedureReturn 0 ; no BITMAP/DIBSECTION
EndIf
If ds\dsBm\bmBits=0
ProcedureReturn 0 ; no DIBSECTION
EndIf
FastImgOutputID\Type=7 ; allows direct memory access
FastImgOutputID\ReleaseProcedure=@___ReleaseFastImageOutput()
FastImgOutputID\PixelBuffer=ds\dsBm\bmBits+ds\dsBm\bmWidthBytes*(ds\dsBm\bmHeight-1) ;needed because the image if top down
FastImgOutputID\Pitch=-ds\dsBm\bmWidthBytes
FastImgOutputID\Width=ds\dsBm\bmWidth
FastImgOutputID\Height=ds\dsBm\bmHeight
Select ds\dsBm\bmBitsPixel
Case 32
FastImgOutputID\Depth=32
FastImgOutputID\PixelFormat=#PB_PixelFormat_32Bits_BGR
Case 24
FastImgOutputID\Depth=24
FastImgOutputID\PixelFormat=#PB_PixelFormat_24Bits_BGR
Case 16
FastImgOutputID\Depth=15
FastImgOutputID\PixelFormat=#PB_PixelFormat_15Bits
Default
ProcedureReturn 0 ; only 32-,24- and 15bit DIBSections are supported
EndSelect
MemDC=CreateCompatibleDC_(0)
If MemDC=0:ProcedureReturn 0:EndIf ; the memory DC cannot be created
SelectObject_(MemDC,ImageID(Image))
FastImgOutputID\DC=MemDC
FastImgOutputID\StopDirectAccess=@___StopDirectAccess()
FastImgOutputID\StartDirectAccess=@___StartDirectAccess()
ProcedureReturn FastImgOutputID
EndProcedure
;Test:
OpenWindow(1,0,0,600,500,"FastImageOutput Test")
CreateImage(1,600,500,32) ; only 32bit seems to be really faster...
Start=GetTickCount_()
StartDrawing(FastImageOutput(1)) ; replace this by ImageOutput(1)
For Y=0 To 499
For X=0 To 599
Plot(X,Y,X*Y)
Next
Next
StopDrawing()
Result=GetTickCount_()-Start
StartDrawing(WindowOutput(1))
DrawImage(ImageID(1),0,0)
StopDrawing()
MessageRequester("Result:",Str(Result)+" ms")
E2D for PureBASIC v4.0
//edit:
Link corrected,thanks DoubleDutch
Posted: Sat Jun 17, 2006 8:42 pm
by DoubleDutch
Your routine make it 6x faster than normal on my machine!
Fred: You should build this in!
btw: the link doesn't work.
Posted: Sat Jun 17, 2006 10:03 pm
by djes
Posted: Sat Jun 17, 2006 10:35 pm
by Flype
FastImageOuput() : 15ms
ImageOutput() : 125ms
I noticed that ImageOutput() is bound-protected but not FastImageOutput().
Code: Select all
For Y=0 To 500 ;-1
For X=0 To 600 ;-1
Plot(X,Y,X*Y)
Next
Next
Posted: Sat Jun 17, 2006 11:12 pm
by Xombie
FastImageOutput(): 0ms - 16ms
ImageOutput(): 94ms
So... what's the catch?

As the saying goes, if something sounds really good, it usually is

Posted: Sun Jun 18, 2006 9:35 am
by S.M.
@Xombie
There is no hook.(At least I don't know any)
It just use the features of DIBSections.
You can even use direct memory access:
Code: Select all
*Buffer=DrawingBuffer()
Pitch=DrawingBufferPitch()
For Y=0 To 499
*ptr.long=*Buffer+Pitch*Y
For X=0 To 599
*ptr\l=X*Y
*ptr+4
Next
Next
Fred: You should build this in!
Yes, please
And a faster point command (wasn't this already included in 3.94 ?!?)
regards
Stefan
Posted: Sun Jun 18, 2006 10:19 am
by netmaestro
GetTickCount_() is too low-res for something this fast. When I turned the debugger off it was always showing 0 ms. So I added this routine and turned the debugger off, it executes in 5 ms vs. 193 ms normal ImageOutput():
Code: Select all
;By Rescator
Procedure.l Ticks_HQ()
Static maxfreq.q
Protected t.q
If maxfreq=0
QueryPerformanceFrequency_(@maxfreq)
maxfreq=maxfreq/1000
EndIf
QueryPerformanceCounter_(@t.q)
ProcedureReturn t/maxfreq
EndProcedure
Posted: Sun Jun 18, 2006 10:58 am
by djes
Here it seems to be 20x faster!
Posted: Sun Jun 18, 2006 6:03 pm
by Flype
you do you think that this difference of speed is due to the fact that FastImageOutput() is not protected against writing out of the image area ?
Posted: Sun Jun 18, 2006 7:13 pm
by S.M.
@Flype
No, it's because Plot() uses direct memory access in this case (like the example I posted above), instead of the SetPixel(V) API function.
Posted: Sun Jun 18, 2006 7:34 pm
by Polo
Flype wrote:you do you think that this difference of speed is due to the fact that FastImageOutput() is not protected against writing out of the image area ?
Not possible, the checking should only be done with the Debug library ?
Posted: Mon Jun 19, 2006 8:58 am
by Dr. Dri
where did you get the DrawingInfoStruct structure ?
in the purebasic library descriptor there is
Code: Select all
Structure DrawingInfoStruct
Type.l
Window.l
DC.l
ReleaseProcedure.l
PixelBuffer.l
Pitch.l
Width.l
Height.l
Depth.l
PixelFormat.l
EndStructure
Dri

Posted: Mon Jun 19, 2006 12:31 pm
by S.M.
Dr. Dri wrote:in the purebasic library descriptor there is
It's even only:
Code: Select all
Structure DrawingInfoStruct
Type.l ; Type of the DC
Window.l ; Window associated to the DC (if any)
DC.l ; DC
ReleaseProcedure.l ; Address to a procedure to release the DC when StopDrawing() is called
PixelBuffer.l ; Address of the memory pixel buffer (DirectX)
Pitch.l ; Pitch
Width.l
Height.l
Depth.l
EndStructure
Dr. Dri wrote:where did you get the DrawingInfoStruct structure ?
Reverse Engineering (whitout dissasembling anything)
I just looked at the pointer which SpriteOutput() returns.
Posted: Fri Jun 23, 2006 3:42 pm
by dige
With FastImageOutput() I have got some strange illegal memory
access errors....
@Fred: what du you think about that way?
Posted: Fri Jun 23, 2006 5:37 pm
by S.M.
@dige
With the same code posted above ?