CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Przyspieszenie wyświetlania na ekranie

Przyspieszenie wyświetlania na ekranie

problemy z tworzeniem aplikacji graficznych oraz audio i wideo

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez Cyfrowy Baron » poniedziałek, 10 stycznia 2011, 14:46

operuję BEZPOŚREDNIO na bitmapie w pamięci a nie na TBitmap. :x


Wypisujesz głupoty. Nie możesz operować na bitmapie inaczej niż poprzez klasę TBitmap. Operujesz w pamięci, gdyż inaczej się nie da, ale to niczego nie zmienia. W C++ wszystkie standardowe operacje są wykonywane w oparciu o GDI, nawet okno formularza jest tworzone przez GDI, podobnie jak wszystkie obiekty na formularzu. Image1->Picture->Bitmap - jak sądzisz czym jest to Bitmap w Picture? To obiekt klasy TBitmap.

Z tego co się orientuję to Direct2D dostępne jest chyba dopiero od DirectX w wersji 10.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez GrassHoppeR » poniedziałek, 10 stycznia 2011, 14:49

w takim razie wracamy do początku - jak najlepiej zrobić, aby obciążenie procesora przy pracy na pełnym ekranie było jak najmniejsze?
przy włączonym DoubleBuffered wydajność leci na pysk z samego tylko faktu buforowania. skoro zatem GDI wyrabia w znacznie bardziej złożonych sprawach to dlaczego nie wyrabia w tak prostym? (pomińmy czyszczenie bitmapy, bo rozwiążę to w inny sposób).
Cyfrowy Baron napisał(a):Wypisujesz głupoty.

może i wypisuję głupoty. robię to analogicznie jak w Twoim Invert z porady->grafika.
Ostatnio edytowano poniedziałek, 10 stycznia 2011, 14:54 przez GrassHoppeR, łącznie edytowano 1 raz
Avatar użytkownika
GrassHoppeR
Homos antropiczny
Homos antropiczny
 
Posty: 63
Dołączył(a): wtorek, 4 stycznia 2011, 01:17
Podziękował : 3
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 2491715
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez Cyfrowy Baron » poniedziałek, 10 stycznia 2011, 14:52

jak najlepiej zrobić, aby obciążenie procesora przy pracy na pełnym ekranie było jak najmniejsze?


To może coś sobie wyjaśnijmy. Ty chcesz zrobić program, który nie korzysta z procesora, czy program, który wykonuje jakieś operacje?! :shock:
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez polymorphism » poniedziałek, 10 stycznia 2011, 14:53

Wyniki w porywach dla 8 klocków (E5200, choć tu karta gr. ma większe znaczenie):

  • DB_noFillRect - 24%
  • noDB_FillRect - ~60%
  • noDB_noFillRect - ~26%
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez GrassHoppeR » poniedziałek, 10 stycznia 2011, 14:56

polymorphism napisał(a):Wyniki w porywach dla 8 klocków (E5200, choć tu karta gr. ma większe znaczenie):

  • DB_noFillRect - 24%
  • noDB_FillRect - ~60%
  • noDB_noFillRect - ~26%

a to mnie zaskoczyło... czyli chodzi prawdopodobnie o kartę. to też niestety tylko połowicznie dobra wiadomość.

Cyfrowy Baron napisał(a):To może coś sobie wyjaśnijmy. Ty chcesz zrobić program, który nie korzysta z procesora, czy program, który wykonuje jakieś operacje?!

chcę zrobić program, który nie obciąża procesora pierdołami. :roll:

chociaż w sumie można powiedzieć, że tak. chcę zrobić program, który nie korzysta (prawie) z procesora. procesor ma w tym momencie np. renderować video w tle. ;)
dlatego z chęcią pokazywanie klocków przekazałbym karcie graficznej. to jedna opcja. a druga - żeby jak najmniej obciążał procesor w przypadku słabej grafiki (np. w VirtualBox).
Avatar użytkownika
GrassHoppeR
Homos antropiczny
Homos antropiczny
 
Posty: 63
Dołączył(a): wtorek, 4 stycznia 2011, 01:17
Podziękował : 3
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 2491715
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez Cyfrowy Baron » poniedziałek, 10 stycznia 2011, 15:10

a to mnie zaskoczyło... czyli chodzi prawdopodobnie o kartę. to też niestety tylko połowicznie dobra wiadomość.


Już kilka postów wcześniej zostało wyjaśnione, że GDI korzysta ze wsparcia sprzętowego.

Przejrzałem te twoje programy i mogę stwierdzić jedno. Wystarczy tutaj zastosować styl pędzla pmNotXor i nie ma potrzeby odświeżania tła, przy założeniu że przesuwany prostokąt jest nieprzeźroczysty. Wtedy kod będzie działał szybko nawet gdy tłem będzie bitmapa. Co więcej nie trzeba wogóle tej bitmapy odświeżać ani przerysowywać. Jest to prostsza wersja kodu, który zaproponowałem we wcześniejszym poście. Coś podobnego zrobiłem z punktami w wątku: http://programowanie.cal.pl/forum/viewtopic.php?f=4&t=1170


Nie wiem o co chodzi z tym czyszczeniem bitmapy, ale u mnie z zastosowaniem funkcji FillRect odbywa się to błyskawicznie:

KOD cpp:     UKRYJ  
 Image1->Picture->Bitmap->Canvas->Brush->Color = clWhite;
 Image1->Picture->Bitmap->Canvas->FillRect(Image1->ClientRect);


a tak jest nawet szybciej.

KOD cpp:     UKRYJ  
#include <memory>
 std::auto_ptr<Graphics::TBitmap> tmpBmp(new Graphics::TBitmap);
 Image1->Picture->Bitmap->Assign(tmpBmp.release());
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez polymorphism » poniedziałek, 10 stycznia 2011, 15:13

jak najlepiej zrobić, aby obciążenie procesora przy pracy na pełnym ekranie było jak najmniejsze?

Jeśli chodzi o metodę, to już napisałem jak ja to robię. Wiesz, odnoszę wrażenie, że starasz się wyciągnąć jak najwięcej fps-ów, co w przypadku statycznej kontrolki jest nieporozumieniem. Zrób tak, żeby przy przeciąganiu klocków nie cięło się i żeby nie spadał komfort pracy. A to, czy CPU osiągnie w porywach 100% czy 10%, nie ma aż takiego znaczenia.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez polymorphism » poniedziałek, 10 stycznia 2011, 15:27

a tak jest nawet szybciej.
KOD cpp:     UKRYJ  
#include <memory>
 std::auto_ptr<Graphics::TBitmap> tmpBmp(new Graphics::TBitmap);
 Image1->Picture->Bitmap->Assign(tmpBmp.release());

Przecież to nie jest to samo co FillRect? Przypisujesz pustą bitmapę, zmieniając rozmiar docelowej bitmapy. Jeśli dobrze pamiętam, Assign służy do deserializacji obiektów, a nie kopiowania bitmap. A nawet jeśli jest inaczej, to tworzenie nowej bitmapy tylko po to, żeby wyczyścić inną, jest bez sensu...
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez Cyfrowy Baron » poniedziałek, 10 stycznia 2011, 15:50

Dokładnie tak jest. Posłużyłem się nową pustą bitmapą, gdyż działa to szybciej niż funkcja FillRect. By jednak móc potem rysować po Image, trzeba wczytać nową bitmapę. Troszkę zresztą zaszalałem, bo do wyczyszczenia bitmapy w Image wystarczy:

KOD cpp:     UKRYJ  
Image1->Picture = NULL;


Co się tyczy Assign to w pomocy dla TImage możemy przeczytać: method Assign public - Copies the contents of another, similar object.

Poza tym funkcja FillRect też nie służy do czyszczenia bitmapy lecz do wypełnienia obszaru kolorem.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez polymorphism » poniedziałek, 10 stycznia 2011, 16:24

Czyszczenie to skrót myślowy, chodzi o zamalowanie rysunku tłem. Więc w tym kontekście FillRect czyści bitmapę.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez Cyfrowy Baron » poniedziałek, 10 stycznia 2011, 16:35

Nie czyści lecz zamalowuje. Wczytanie nowej bitmapy do starej czyści. Można by się oczywiście sprzeczać o znaczenie jednego i drugiego, a tutaj tylko chodzi o wybranie najodpowiedniejszej i najwydajniejszej metody przywrócenia bitmapy do pierwotnego stanu jak zakładam. Moim zdaniem najskuteczniejszą metodą jest przechowywanie oryginalnej bitmapy w buforze i przekopiowywanie całej bitmapy lub wybranego jej fragmentu co zaproponowałem we wcześniejszym poście. Funkcja FillRect jest niewydajna.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez Cyfrowy Baron » poniedziałek, 10 stycznia 2011, 17:04

Przeprowadziłem dwa testy z pomiarem czasu:



przykład 1:
KOD cpp:     UKRYJ  
 float Start = GetTickCount();

 Image1->Picture->Bitmap->Canvas->Brush->Color = clBlue;
 Image1->Picture->Bitmap->Canvas->FillRect(Image1->ClientRect);

 float End = GetTickCount();

 ShowMessage(FloatToStr(End - Start) + " ms");
6 ms.



przykład 2:
KOD cpp:     UKRYJ  
 float Start = GetTickCount();

 std::auto_ptr<Graphics::TBitmap> tmpBmp(new Graphics::TBitmap);
 tmpBmp->Width = Image1->Width;
 tmpBmp->Height = Image1->Height;
 tmpBmp->Canvas->Brush->Color = clBlue;
 tmpBmp->Canvas->FillRect(Image1->ClientRect);
 Image1->Picture->Bitmap->Assign(tmpBmp.release());

 float End = GetTickCount();

 ShowMessage(FloatToStr(End - Start) + " ms");


0 ms.




Druga metoda jest szybsza mimo iż wykonywanych jest więcej operacji. Przypuszczam iż wiąże się to z faktem, że wypełnianie obiektu typu TBitmap kolorem odbywa na bitmapie, która jest pusta. Przeprowadziłem również test z bitmapą tylko w pamięci, czyli w buforze i uzyskałem gorszy efekt niż w drugim przykładzie:

przykład 3:
KOD cpp:     UKRYJ  
 float Start = GetTickCount();

 Buffer->Canvas->Brush->Color = clBlue;
 Buffer->Canvas->FillRect(Image1->ClientRect);
 Image1->Picture->Bitmap->Assign(Buffer);


 float End = GetTickCount();

 ShowMessage(FloatToStr(End - Start) + " ms");


Po pierwszym wywołaniu uzyskałem czas 0 ms, ale kolejne wywołania były gorsze, gdyż dawały ponad 20 ms. W drugim przykładzie po każdym wywołaniu uzyskałem 0 ms.

Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez GrassHoppeR » poniedziałek, 10 stycznia 2011, 18:04

polymorphism napisał(a):Czyszczenie to skrót myślowy, chodzi o zamalowanie rysunku tłem. Więc w tym kontekście FillRect czyści bitmapę.

racja, przynajmniej jeśli chodzi o "czyszczenie" w tym sensie, że jest to zamalowanie powierzchni kolorem (255,255,255).

Cyfrowy Baron napisał(a):Przejrzałem te twoje programy i mogę stwierdzić jedno. Wystarczy tutaj zastosować styl pędzla pmNotXor

być może w tym konkretnym przykładzie klocków - tak. jednak to tylko przykład, gdyż docelowo elementy te miały wyglądać inaczej. prawdopodobnie wykorzystam sporą część kodu, który zaprezentowałeś, ale w tej chwili ważniejsze jest dla mnie obranie właściwej koncepcji całości. wygląda na to, że lepiej unikać rzeźbienia na własną rękę. ewentualnie zmienię koncepcję i faktycznie wykorzystam ten styl.

polymorphism napisał(a):Wiesz, odnoszę wrażenie, że starasz się wyciągnąć jak najwięcej fps-ów, co w przypadku statycznej kontrolki jest nieporozumieniem.

w zasadzie masz rację. staram się wyciągnąć max fps'ów = jak najmniej obciążający sposób rysowania. w końcu nie po to siedziałem nad skryptami i pluginami do przetwarzania obrazu, żeby mi teraz jakieś kopiowanie bitmap zżerało większość mocy procesora, potrzebnej w tym czasie gdzie indziej.

Cyfrowy Baron napisał(a):Troszkę zresztą zaszalałem, bo do wyczyszczenia bitmapy w Image wystarczy:

KOD cpp:     UKRYJ  
Image1->Picture = NULL;

no z tym to zwolnił u mnie maksymalnie...

Cyfrowy Baron napisał(a):Moim zdaniem najskuteczniejszą metodą jest przechowywanie oryginalnej bitmapy w buforze i przekopiowywanie całej bitmapy lub wybranego jej fragmentu co zaproponowałem we wcześniejszym poście.

zgadza się, jednak te metody już wypróbowałem zanim rozpocząłem ten wątek, i przyrost wydajności był pomijalny w stosunku do wyłączenia buforowania. rozumiem teraz, że to przez kartę graficzną, prawda?

dzięki za testy, spróbuję u siebie z GetTickCount i zobaczę jak to wychodzi. potem skoczę po kartę i sprawdzę z nią, bo przyznam szczerze, że wyniki tego testu mnie zdziwiły. z drugiej strony samo "czyszczenie" nie jest tak istotne jeśli zastosuję inny algorytm przywracania tła tylko pod klockiem. jednak sposób z tworzeniem nowej bitmapy, o ile faktycznie będzie szybsze, przyda się w innym miejscu, np. przy zmianie wielkości albo przesuwaniu (tutaj sposób z drugą bitmapą zmniejszył wydajność).

korci mnie jednak ten DirectDraw. samo wyświetlanie bitmapy powinno mi wystarczyć. tylko jak to zrobić w okienku?!
Avatar użytkownika
GrassHoppeR
Homos antropiczny
Homos antropiczny
 
Posty: 63
Dołączył(a): wtorek, 4 stycznia 2011, 01:17
Podziękował : 3
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 2491715
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez Cyfrowy Baron » poniedziałek, 10 stycznia 2011, 18:12

zgadza się, jednak te metody już wypróbowałem zanim rozpocząłem ten wątek, i przyrost wydajności był pomijalny w stosunku do wyłączenia buforowania. rozumiem teraz, że to przez kartę graficzną, prawda?


Nie miałem na myśli podwójnego buforowania - DoubleBuffered = true, lecz chodziło mi o przechowywanie w odrębnym obiekcie klasy TBitmap grafiki do szybszego pobierania. Tak jak to masz w moim przykładzie - obiekt Buffer.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Przyspieszenie wyświetlania na ekranie

Nowy postprzez GrassHoppeR » poniedziałek, 10 stycznia 2011, 18:37

tak właśnie miałem. druga bitmapa zawierała wszystkie namalowane klocki oprócz aktywnego, następnie przekopiowywałem tylko fragment zmieniony. to było najprostsze i sprawdziłem jako pierwsze. jednak mimo tego i tak podczas przesuwania klocka program się przytykał. przy przesuwaniu całej powierzchni (scrollbarem albo kółkiem) albo przy powiększaniu okna i w wielu innych okolicznościach trzeba było nie tylko odświeżyć bitmapę tymczasową ale i przekopiować ją całą na bitmapę główną, choć próbuję znaleźć sposób na ograniczenie zasięgu odświeżania. trochę trudno mi tłumaczyć motywy tego mojego szukania wydajności, ale to naprawdę istotne. to tylko jeden z elementów całości, którą planuję napisać.

konkluzja jest taka - nie da się przeskoczyć DoubleBufferingu, w grę wchodzi jedynie przyspieszenie malowania. tak?
Avatar użytkownika
GrassHoppeR
Homos antropiczny
Homos antropiczny
 
Posty: 63
Dołączył(a): wtorek, 4 stycznia 2011, 01:17
Podziękował : 3
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 2491715
    Windows XPFirefox

Poprzednia stronaNastępna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje multimedialne, graficzne

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 1 gość