The MASM Forum

General => The Campus => Topic started by: Fraile on April 23, 2014, 06:38:28 AM

Title: BitBlt And CPU 100%
Post by: Fraile on April 23, 2014, 06:38:28 AM
Hi,

I am trying to implement a Win32 screen capture application similar to VNC.
The issue is, the Bit blt function call that i am using to capture the screen chokes up the cpu when the hardware acceleration is FULL. The Cpu goes upto 100% and stays there.

I tried BItBlt on the HDC obtained from CreateDIBSection and CreateCompatibleBitmap funtions, but both gave the same result.

When i set the Hardware acceleration to NONE the cpu utilisation is atmost 30%.

Is there any way that i can reduce the BitBlt CPU usage when hardware accleration is set to FULL.

How disabled hardware acceleration with API?

Please help.

Thanks,
Title: Re: BitBlt And CPU 100%
Post by: dedndave on April 23, 2014, 08:34:41 AM
you didn't show us any code
but, i can guess what the problem is
you handle the WM_PAINT message without validating the update region
it will continually send WM_PAINT messages until the region is updated
one way to avoid this is to call BeginPaint and EndPaint
another way is to exit WndProc via DefWindowProc for WM_PAINT messages
still another way would be to call ValidateRect
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 23, 2014, 09:41:30 AM
Correct, I handle  to message "WM_PAINT". Attached code Hook.

When detect "WM_PAINT", sent a message for capturing screen.

Please could you explain with my example?

Thank you very much
Title: Re: BitBlt And CPU 100%
Post by: dedndave on April 23, 2014, 10:28:40 AM
i don't know what you're tring to do, there   :P

but, give me a few minutes, and i will post a simple example using WM_PAINT, BeginPaint, EndPaint
Title: Re: BitBlt And CPU 100%
Post by: dedndave on April 23, 2014, 10:42:43 AM
see attached...

Title: Re: BitBlt And CPU 100%
Post by: Gunther on April 23, 2014, 11:27:02 AM
Hi Dave,

good catch.  :t I hope it'll help our friend.

Gunther
Title: Re: BitBlt And CPU 100%
Post by: Adamanteus on April 23, 2014, 11:58:39 AM
 I not very clear understand you code, but by concepts could remark - BitBlt algo making few MFLOPS processing all pixels, so easy could overload processor. For avoiding it is need to split algo on more smaller parts, that's running in threads, meanwhile main thread calling Yield function waiting results - so, you need to manually rewrite you version of BitBlt (suppose even part of it), and support this processing big (attended to time when original code was written) resolution of modern screens.
Title: Re: BitBlt And CPU 100%
Post by: Farabi on April 23, 2014, 02:19:10 PM
AFAIK, WM_PANIT sometime called hundreds time a seconds and that is why it make your CPU usage goes to 100%. I used to limited the Bitblt to 60 FPS, and bitblt is very efficient compared than creating your own using the CPU. Bitblt is hardware accelerated, even on my old zyrex EGT there is only bitblt which is hardware accelerated, and OpenGL used it too to create the texture maping.
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 23, 2014, 05:57:08 PM
Thank to All,

Sorry my english is very bad.

I capture  the screen in several frames, but the cpu performance is up 100%. I divide the screen into columns and rows.

I thinks as Farabi says: "WM_PANIT sometime called hundreds time a seconds "

Farabi, how limit "BitBLt" to 60 FPS?
Is best to use timer in lieu of a hook?
Title: Re: BitBlt And CPU 100%
Post by: dedndave on April 23, 2014, 11:50:04 PM
multimedia timers are a bit more complicated, but provide higher resolution
the standard windows timer has a resolution of either 10 or 16 mS, depending on the system
if you want exactly 60 FPS, you'll have to use the multimedia timer resolution of 1 mS and fudge
Title: Re: BitBlt And CPU 100%
Post by: MichaelW on April 24, 2014, 02:32:43 AM
The  timeBeginPeriod (http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624(v=vs.85).aspx) function sets the minimum resolution for all of the periodic timers, not just the multimedia timers. But if CPU usage is a problem, setting a higher resolution for the periodic timers will likely make the problem worse.

To limit the frequency of an event, you could poll a suitable timer in your message loop.  QueryPerformanceCounter (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx) is one possibility.

Title: Re: BitBlt And CPU 100%
Post by: jj2007 on April 24, 2014, 02:48:53 AM
If your WM_PAINT message is coming too often, it's a design problem.

Anyways, check pDueTime in SetWaitableTimer (http://msdn.microsoft.com/en-us/library/windows/desktop/ms686289%28v=vs.85%29.aspx).
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 24, 2014, 03:09:17 AM
You could give a example to  " SetWaitableTimer"?

Please, thank you very much.
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 24, 2014, 03:21:26 AM
You could give a example to  " QueryPerformanceCounter"?

Please, thank you very much.
Title: Re: BitBlt And CPU 100%
Post by: jj2007 on April 24, 2014, 08:03:30 AM
Quote from: AsmAlmeria12 on April 24, 2014, 03:09:17 AM
You could give a example to  " SetWaitableTimer"?

Try this. (https://www.google.com/search?q=SetWaitableTimer+example)
BTW, in your hook code I see
                .elseif [edx].message  == WM_KEYDOWN
                    invoke PostMessage, HWND_BROADCAST, HwdMensaje,0,0

... shouldn't that be
                    invoke PostMessage, HWND_BROADCAST, HwdMensaje,wParam,lParam
??? You want to know which key was pressed, right?
Title: Re: BitBlt And CPU 100%
Post by: qWord on April 24, 2014, 08:25:43 AM
Why is HWND_BROADCAST used? This produce useless message processing in all GUI threads except the thread of the actual target window.
For WM_PAINT I would pool the paint requests over a specific time interval and then copy the corresponding screen region.
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 24, 2014, 08:59:48 AM
Hi, good night from southern Spain.

My program used the hook for see if there change of the screen. If there change ("WM_PAINT" , "WM_KEYDOWN" And "WM_MOUSEMOVE"), sent a message for capture to the all screen.

I use "HWND_BROADCAST " . Fails to reach the message specifying the handler my thread. I've tried "invoke PostMessage, HwndMyThread, HwdMensaje,0,0" but doesn't  work.

My hook is only a jumper for capture to the screen.

Farabi, MichaelW and Qword, tell me limit the frequency of an event ("WM_PAINT", "WM_KEYDOWN" Y "WM_MOUSEMOVE"),  for reducing  the use CPU. I dont know how  limit the frequency??.

Another example, please?

Other way, please?
Title: Re: BitBlt And CPU 100%
Post by: qWord on April 24, 2014, 09:26:38 AM
Can you please give us some more details about your intention? Why do you need to write a program for remote control in Assembler?
Title: Re: BitBlt And CPU 100%
Post by: MichaelW on April 24, 2014, 09:58:14 AM
Edit: Finished the example :lol:

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
          pc_frequency  dq 0
          pc_count      dq 0
          r8            REAL8 ?
          hTimer        HANDLE 0
          msg           MSG <>
    .code
;==============================================================================
TimerProc proc hwnd:HWND, uMsg:UINT, idEvent:DWORD, dwTime:DWORD
    ;---------------------------------------------------
    ; On the first call initialize pc_count and return.
    ;---------------------------------------------------
    mov eax, DWORD PTR pc_count
    or  eax, DWORD PTR pc_count+4
    jnz @F
    invoke QueryPerformanceCounter, ADDR pc_count
    ret
  @@:
    ;---------------------------------------------------------------
    ; Calc and display the elapsed seconds since the previous call.
    ;---------------------------------------------------------------
    fild pc_count
    invoke QueryPerformanceCounter, ADDR pc_count
    fild pc_count
    fsubr
    fild pc_frequency
    fdiv
    fstp  r8
    printf("%f\n", r8)
    ret
TimerProc endp
;==============================================================================
start:
;==============================================================================
    invoke QueryPerformanceFrequency, ADDR pc_frequency
    printf("%I64d\n", pc_frequency)
    invoke SetTimer, 0, 0, 1000, ADDR TimerProc
    push eax
    ;-------------------------------------------------
    ; For this type of timer to work in a console app
    ; the calling thread must dispatch messages.
    ;-------------------------------------------------
  @@:
    invoke GetMessage, ADDR msg, NULL, 0, 0
    invoke DispatchMessage, ADDR msg
    invoke GetAsyncKeyState, VK_ESCAPE
    test eax, 1
    jz  @B
    pop eax
    invoke KillTimer, 0, eax
    inkey "Press any key to exit..."
    exit
;==============================================================================
end start


3579545
1.001420
1.001432
1.001438
1.001461
1.001426
1.001437
1.001436
1.001504
1.001374
1.001440
1.001449
1.001435
1.001436
1.001443


QuoteMy program used the hook for see if there change of the screen. If there change ("WM_PAINT" , "WM_KEYDOWN" And "WM_MOUSEMOVE"), sent a message for capture to the all screen.

Why do you need to capture every change in the screen?

Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 24, 2014, 10:54:40 AM
Yes, my intention is to create a program to view multiple PCs remotely.

Attached Demo.

Config.INI:

ip=192.168.1.197 (Ip Server)
puerto=8889        (Port)
tipocursor=0         (1 = BitBlt with CAPTUREBLT Or SRCCOPY. 0 = BitBlt only SRCCOPY)
modo=1               (1 = Server. 0 = Client)
coldivpantalla=1  (Columns split screen)
fildivpantalla=1    (Rows split screen)
tipoenvio=1         (Send)
tipoimg = 0          (0 = type image JPG. 1 = type image BMP)

The program still did not work well. Is a prototype.
Is only for 32bits.
On some computers the CPU is high.
The program only send images, when GPS.DLL (hook) see a change.


Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 24, 2014, 11:07:53 AM
MichaelW, thanks for the example, I now understand the function "QueryPerformanceFrequency"


Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 25, 2014, 04:52:16 AM
Hi,

This is correct, for calculate the time (miliseconds) it takes my function in  screen capture?

Code:

.Data

pc_frequency   DQ 0
IniTime           DQ 0
FinTime           DQ 0


.Code
.
.

                        Invoke QueryPerformanceFrequency, Addr pc_frequency
                        Invoke QueryPerformanceCounter, Addr IniTime
                      
                               Invoke CaptureScreen ; Function capture the screen.

                        Invoke QueryPerformanceCounter, Addr FinTime


                        Xor Edx, Edx
                        Mov Eax, DWord Ptr FinTime
                        Mov Ebx, DWord Ptr IniTime
                        Sub Eax, Ebx
                        Mov Ebx, 1000
                        Mul Ebx
                        Mov Ebx, DWord Ptr pc_frequency
                        Div Ebx

.
.
.
Title: Re: BitBlt And CPU 100%
Post by: dedndave on April 25, 2014, 05:30:15 AM
;calculate performance counter counts per millisecond
;this only needs to be done once, at program initialization
;the result may then replace the low dword of pc_frequency

    mov     eax,dword ptr pc_frequency
    mov     edx,dword ptr pc_frequency[4]
    mov     ecx,1000
    div     ecx
;round to nearest
    shr     ecx,1
    cmp     edx,ecx
    sbb     eax,-1
    mov dword ptr pc_frequency,eax

;then, to calculate elapsed time...

    mov     eax,dword ptr FinTime
    mov     edx,dword ptr FinTime[4]
    mov     ecx,dword ptr pc_frequency
    sub     eax,dword ptr IniTime
    sbb     edx,dword ptr IniTime[4]
    div     ecx
;round to nearest
    shl     edx,1
    cmp     edx,ecx
    sbb     eax,-1
Title: Re: BitBlt And CPU 100%
Post by: Farabi on April 25, 2014, 03:29:22 PM
I think you can use the Bitblt calling on separate thread, and then set the thread to run each 100ms by set the thread execution delay using Sleep function.
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 26, 2014, 10:58:14 AM
Hi all,

Attached a example, for screen capture.

Screen capture at 25 FPS.

I capture the screen using BitBlt and GetDiBits for save bits and then send. I do not know if I can use only GetDibits for capture the bits. You know if you can?

I'm desperate!. Thanks in advance
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 28, 2014, 05:19:25 AM
Hi all,

I'm debugging my program, I have seen, a problem in my send by socket.

I use socket Async, I use the function "WSAAsyncSelect" for know when to send packet.

What type of socket should I use me?, socket type of blocking or not?

Thanks is advance!.
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 28, 2014, 10:18:11 PM
Hi all,

The performance problem is in the size of image.

Anyone have any example to zlib version 1.2.8?, for  function "compress".

I  tried "zlibstat.lib and zlibstat.inc" but gives error: "zlibstat.lib(crc32.obj) : fatal error LNK1103: debugging information corrupt; recompile module"

If anyone has ".Lib and .Inc" would greatly appreciate it.

Thank you very much.
Title: Re: BitBlt And CPU 100%
Post by: dedndave on April 29, 2014, 12:04:40 AM
use the forum search tool for "zlib"
i seem to recall someone playing with that a while back
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 29, 2014, 03:18:53 AM
Hi Debndave,

In the forum mams32, I have seen some examples and I have also read your manual and faq to zlib.

But I can not make it work, the function "compress/uncompress"

I have the following error:

"fatal error LNK1103: debugging information corrupt; recompile module"

You could help me?.
you would have some example for masm32? Or zlib.lib and zlib.inc for masm32?.

Thank is advance.
Title: Re: BitBlt And CPU 100%
Post by: fearless on April 29, 2014, 03:38:44 AM
This might be something that will help you: http://www.masmforum.com/board/index.php?topic=9039.0

Ive attached zlibstat.inc and zlibstat.lib (which is zlib v1.1.4) unfortunately i havent been able to find a newer version of the static library or compile it from the various sources online - always get issues with unresolved externals and name decoration issues (even using vortex's undecor tool). Maybe someone else can take a stab at compiling a static zlib library that can be linked with assembler projects. Anyhow v1.1.4 works mostly, and this is the version i used for the zlibextract lib i created as well, which can be found in the following thread http://masm32.com/board/index.php?topic=421.0
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 29, 2014, 04:17:35 AM
Thank fearless   :eusa_clap: :eusa_clap:
This lib and inc, if well.

Thank you very much.
Title: Re: BitBlt And CPU 100%
Post by: Adamanteus on April 30, 2014, 02:07:46 AM
As you found - problem in size of image, so compressing only will add MFLOPS to you thread - what will be in such case you could test on GER program example (MT) from my site packing any data over 5 GB. The reason is simple - threads in my archiver make each time more then 1 MFLOPS per thread.  So could work only on machive with plants cooling, and even for me modify packing algo that will fit to limit is quite difficult.
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 30, 2014, 04:59:03 AM
Hi Adamanteus,

Debugging my program, I have seen several errors:

1 Compressing and size the image.

If the packet too large to send, the "socket", overload the processor and network.

2  Like you said in your previous post, "BitBlt algo making few MFLOPS processing all pixels, so easy could overload processor".

I tried  to changed the image size with function "StretchBlt" and colour, the performance is better.

I managed to reduce the use CPU from 100% to 30%.

But I see another program like "Teamviewer" that the use to CPU is 5%. How is does?.

My program is ready for divide the screen in columns and rows. But the result does not vary much.

I need advices.

Title: Re: BitBlt And CPU 100%
Post by: dedndave on April 30, 2014, 05:07:03 AM
i don't think TeamViewer supports 25 FPS   :P
Title: Re: BitBlt And CPU 100%
Post by: Fraile on April 30, 2014, 08:51:08 AM
I think if you could scale down the image with the function "StretchBlt" and send it.

And when on the other side is received, the image is enlarged, and pixel-level retouching for to view it.

This may be correct?

The first part, this clear. the dificult is the second part.

Understand what I like to do?. (my english is very bad).

Any tips?

Thank you very much.
Title: Re: BitBlt And CPU 100%
Post by: dedndave on April 30, 2014, 12:01:14 PM
BitBlt will normally be a little faster than StretchBlt

either way, you end up with a DIB
you could shrink it considerably by converting it to a JPG or PNG
perhaps even moreso if you converted it to 256 colors and made a GIF