Problém s CPU a OnPaint(..) – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Problém s CPU a OnPaint(..) – .NET – Fórum – Programujte.comProblém s CPU a OnPaint(..) – .NET – Fórum – Programujte.com

 

ingiraxo+15
Grafoman
7. 6. 2012   #1
-
0
-

zdravim,

mám takový problém. Potřebuju přes OnPaint(..) vykreslit čáry X,Y podle toho, kde se nachází myš (tohle není problém), ale problém je, že musím mít ještě event OnMouseMove(..) kde volám Refresh() na překreslení a to mi bere nimimálně 30% CPU a to mám QuadCore 4GHz... nechápu.. můžete mi někdo říct, jak tohle vyřešit, abych měl CPU kolem 0-1% na tuhle prkotinu?

PS: neznám žádnej způsob, jak pohybovat myší po formu a přitom nevolat Refresh() pro překreslení z události OnMouseMove... a pokud hýbu myší, tak CPU letí vzhůru.. kór když tam mám další objekty k vykreslení (třeba cyklus pro vykreslení 20 bodů), tak se musí znovu provést vždy, když hejbnu myší.. takže CPU jde ještě výš :((

PPS: měl jsem tam ještě timer, co mi překresloval okno každých 30ms, ale pokud jsem tam zahrnul to vykreslení čar (os) myši, tak instantně CPU 25% (max)

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
liborb
~ Redaktor
+18
Guru
7. 6. 2012   #2
-
0
-

A to kreslíš do paměťového DC a následně jenom uděláš jenom BitBlt nebo jedeš bez double bufferingu?

Nahlásit jako SPAM
IP: 78.80.52.–
ingiraxo+15
Grafoman
7. 6. 2012   #3
-
0
-

normálně přes DoubleBuffer na form

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
liborb
~ Redaktor
+18
Guru
7. 6. 2012   #4
-
0
-

Lepší by byla diskuze nad konkrétním zdrojákem (projektem), jinak to budou jen obecné rady.

Zasláno z mobilního telefonu.

Nahlásit jako SPAM
IP: 82.145.209.–
ingiraxo+15
Grafoman
7. 6. 2012   #5
-
0
-

však mě stačej obecný rady... prostě máš např...

// instancni promenna
private Point mouseLocation = Point.Empty;

// kresleni na form
protected override void OnPaint(obj, e)
{
    Graphics g = e.Graphics;

    // vykresluje cary v osach X,Y podle pozice mysi
    // (promenny "mouseLocation")
    g.DrawLine(...); // pro X (horizontalni)
    g.DrawLine(...); // pro Y (vertikalni)
}

// pohyb mysi po formu
protected override void OnMouseMove(obj, e)
{
    mouseLocation = e.Location;

    // zavola OnPaint na prekresleni
    // a diky tomu, mam pri pohybu mysi po formu cca 20% CPU
    Refresh();
}

Je to zjednodušený, ale princip je snad jasnej.. jde o to, že jakmile OnMouseMove volá překreslení, tak při pohybu myši po formu mám CPU kolem 20% cca (záleží jak je okno velký) a tady mi to přijde jako nesmysl, abych jen kvůli aktualizaci souřadnic měl o tolik zvednutý CPU...

Vim že souřadnice se dají zjistit i přes: Control.MousePosition, ale stále potřebuju zavolat překreslení...

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
liborb
~ Redaktor
+18
Guru
8. 6. 2012   #6
-
0
-

Tak pro začátek zkus: 

protected override void OnPaint(obj, e)
{
	Graphics clientDC = this.CreateGraphics();

	clientDC.DrawLine(...); // pro X (horizontalni)
	clientDC.DrawLine(...); // pro Y (vertikalni)
}
Nahlásit jako SPAM
IP: 78.80.52.–
ingiraxo+15
Grafoman
8. 6. 2012   #7
-
0
-

promiň, ale nejspíš nechápeš co rešim... to co si napsal zkoušet rozhodně nehodlam, nepotřebuju mít při pohybu myši z formu stroboskop a stejně by to neměnilo nic na vytížení CPU

hlavně potřebuju kreslit na form, nikoli na nějakej novej buffer, kterej se mi jednoduše smaže a hlavně odpadá možnost obnovovat překreslení

já už nevim jak to říct.. prostě si zkus udělat to co jsem předtim napsal, nemusíš tam ani dávat ty DrawLine, roztáhni si okno aspon na 3/4 plochy a sleduj CPU (doufám že máš HD rozlišení na monitoru) a uvidíš, jak ti CPU poleze nahoru jen při pohybu myši po formu díky překreslení při pohybu

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
ingiraxo+15
Grafoman
8. 6. 2012   #8
-
0
-

Ještě pošlu ukázku, jak to myslim...

using System.Drawing;
using System.Windows.Forms;

namespace Program
{
    public partial class CPUProblem : Form
    {
        private Point mousePosition;

        public CPUProblem()
        {
            InitializeComponent();
            DoubleBuffered = true;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;
            Pen axisLine = new Pen(new SolidBrush(Color.Gray), 1);

            g.DrawLine(axisLine, mousePosition.X, 0, mousePosition.X, Height - 2);
            g.DrawLine(axisLine, 0, mousePosition.Y, Width - 2, mousePosition.Y);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            mousePosition = e.Location;
            Refresh();
        }
    }
}

Nevim jestli je jiná možnost jak to udělat, ale docela mě štve, že jen blbej pohyb myši vytíží tolik CPU... aby se mi zobrazili čáry pozice myši, tak při pohybu to prostě musim překreslit.. kdybych vykreslovat víc věcí než ty čáry, tak CPU leze přímo exponenciálně nahoru při přidání jen pár dalších objektů k vykreslení

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
KIIV
~ Moderátor
+43
God of flame
8. 6. 2012   #9
-
0
-

a musi se to nutne refreshovat? mozna by stacilo vykreslit na stare pozici cary barvou pozadi, a pak na nove pozici vykreslit normalne (aspon do doby co tam nic jinyho nemas)

jeste zkus co ucela ciste ten refresh bez jakyhokoliv kresleni v on paint... a jeste musi existovat i neco jako "invalidate" casti okna.. (ale to nevim jestli by ti pomohlo jen nad tou kreslici plochou)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ingiraxo+15
Grafoman
8. 6. 2012   #10
-
0
-

#9 KIIV
právě že musí.. Refresh() je jen alias k Invalidate().. pokud bych nezavolal invalidate při pohybu myši, tak se nezavolá znovu OnPaint() a neaktualizujou se mi čáry pozice myši

ono to vytížení dělá to překreslení okna při pohybu myši i když nic nemám v OnPaint, chápu že se ta funkce volá celkem rychle při pohybu ale zaráží mě, že to dokáže tolik vytížit CPU, by nemělo bejt ani znát snad

existuje invalidate pouze pro část okna, ale ty čáry sahají po celém oknu (prostě velkej kríž, kde průnik čar je pozice myši), takže tohle odpadá

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
liborb
~ Redaktor
+18
Guru
8. 6. 2012   #11
-
0
-

Celý problém je v tom, že Refresh volá neprodleně překreslení a zapnutý double buffering je tedy pěkný žrout (nikdy jsem to nezkoumal a docela mě ten rozdíl překvapil).

Co můžeš udělat?

- zneplatnit pouze oblasti, které se to opravdu týká (a pak Update)

- udělat si vlastní double buffer (něco jako tady)

- použít radu od KIIVa a nejlépe XOR PEN

- no a samozřejmě v Paint dělat jenom to, co je nutné (to pero stačí vytvořit jednou apod.)

Nahlásit jako SPAM
IP: 78.80.52.–
ingiraxo+15
Grafoman
8. 6. 2012   #12
-
0
-

no, i když jsem to teď zkusil bez doubleBufferu, tak CPU má kolem 7% sice se to zlepšilo, ale stejně mi přijde šílený mít takový vytížení jen pro překreslení podle pohybu myši

co se týká toho vlastního bufferu, tak jsem právě nechtěl používat externí knihovny kvůli tomu (jak tam máš import GDI)

pokusim si to udělat ve WPF jakej bude rozdíl, on by měl používat buffer přes DX

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
13. 6. 2012   #13
-
0
-

Určitě jasná volba WPF. Ten je na to perfektně optimalizovaný.

Nahlásit jako SPAM
IP: 82.208.25.–
http://www.davidrosko.gekoni.cz/
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 65 hostů

Podobná vlákna

CPU — založil sin_x

00% zatazenie CPU — založil joker

CPU info — založil praxc

C++: Zaťaženie CPU — založil gaben

C# teplota CPU — založil Dingo

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý