c ++ - Jeg leder efter optimeringer, jeg kan lave i et grafikredigeringsprogram

Indlæg af Hanne Mølgaard Plasc

Problem



Heyo, det her er min første gang, der stiller et spørgsmål her, så giv mig tilstedeværelse, hvis jeg redder noget> ~ <


Jeg arbejder på et program, der ligner openCanvas, de tidligere, der tillod flere mennesker at tegne på samme lærred i realtid via internettet. OC er virkelig buggy og har mange begrænsninger, og derfor ønskede jeg at skrive dette.


Jeg har den oprettet, så lærredet strækker sig 'ubestemt' i alle retninger og består af 512x512 blokke af pixels, der ikke bliver aktive indtil de er trukket på, hvilket burde være meget nemt at lave, og jeg tænkte på bruger Direct3D for at gøre det hardware accelereret, således 512 square blokke.


Mit problem kommer, når jeg vil bruge lag, jeg er ikke helt sikker på, hvordan jeg kan komponere lag hurtigt og uden at bruge masser af hukommelse, da mit mål er DirectX9 kompatible videokort med 128m hukommelse og et system med ca. 3,2 ghz af CPU strøm og mellem 2 og 8 gigs ram. Jeg havde et par forskellige tilgange, jeg tænkte på at bruge og undrede mig over, som sandsynligvis ville være det bedste, og hvis der var noget, jeg kunne se på for at få det til at løbe bedre.


Min første idé var at få gfx-hardware til at gøre så meget arbejde som muligt ved at have alle lagene på alle blokke tjene som teksturer, og de opdateres ved at låse det ændrede område, ajourføre dem på cpu og låse dem op. Blokke, der ikke ændres i øjeblikket, er fladt i en tekstur, og de enkelte lag selv bevares i systemhukommelsen, hvilket ville reducere den anvendte gfx-hukommelse, men kan betydeligt øge båndbreddeforbruget mellem system og gfx-hukommelse. Jeg kan se den konstante låsning og oplåsning, der muligvis sænker systemet ganske slemt også. Et andet muligt problem er, at jeg har hørt nogle mennesker bruger op til 200 lag, og jeg kan ikke tænke på nogen gode måder at optimere det ovenstående.


Min anden ide var at komponere teksturerne - helt i systemhukommelsen, skrive dem i en tekstur og kopiere den tekstur til gfx-hukommelsen, der skal gengives i hver blok. Dette ser ud til at eliminere mange af problemerne med den anden metode, men samtidig flytter jeg alt arbejdet ind i CPU'en, i stedet for at afbalancere det. Det er ikke så meget, så længe det stadig kører hurtigt, men . Igen er der imidlertid spørgsmålet om at have et par hundrede lag. I dette tilfælde kunne jeg nok kun opdatere de endelige pixler, der faktisk ændrer sig, hvilket er, hvad jeg synes, at de større navnsprogrammer som Sai og Photoshop gør.


Jeg søger mest efter anbefalinger, forslag, der kan forbedre ovenstående, bedre metoder eller links til artikler, der kan være relateret til et sådant projekt. Mens jeg skriver det i C ++, har jeg ingen problemer med at oversætte fra andre sprog. Tak for din tid ~

Bedste reference


Datastruktur

Du bør helt sikkert bruge en quadtree (eller en anden hierarkisk datastruktur) til at gemme dit lærred og dets knuder skal indeholde meget mindre blokke end 512x512 pixels. Måske ikke så lille som 1x1 pixels, for da vil den hierarkiske overhead dræbe dig - du vil finde en god balance gennem test.


Tegning

Lad dine brugere kun tegne en (højeste) opløsning. Forestil dig et uendeligt stort ensartet net (todimensionelt array). Da du kender musens position og det beløb, som dine brugere har rullet fra oprindelsen, kan du udlede absolutte koordinater. Gå gennem quadtree til den pågældende region (til sidst tilføje nye knuder) og indsæt blokkene (for eksempel 32x32), når brugeren trækker dem ind i quadtree. Jeg ville buffer, hvad brugeren trækker i et 2D array (for eksempel så stort som hans skærmopløsning) og bruge en separat tråd til at krydse/ændre quadtree og kopiere data fra bufferen for at omgå eventuelle forsinkelser.


Rendering

Traverserer quadtree og kopierer alle fliser til en tekstur og sender den til GPU'en? Ingen! Du ser, sender en tekstur, der er så stor som skærmopløsningen, er ikke problemet (båndbredde klog). Men at krydse quadtreeen og samle det endelige billede er (i det mindste hvis du vil have mange fps). Svaret er at gemme quadtree i systemhukommelsen og streame det fra GPU'en. Midler: Asynkront en anden tråd gør traversen og kopierne aktuelt set data til GPU'en i stykker så hurtigt som muligt. Hvis din bruger ikke ser lærredet i fuld opløsning, behøver du ikke at krydse træet til bladniveau, hvilket giver dig automatisk detaljeringsgrad (LOD).


Nogle tilfældige tanker om den foreslåede strategi




  • Quadtree-tilgangen er stor, fordi den er meget hukommelseseffektiv.

  • Streaming ideen kan udvides til HDD'en ... SeaDragon

  • En sofistikeret implementering ville kræve noget som CUDA.

  • Hvis din GPU ikke tilbyder den nødvendige ydeevne/programmerbarhed, skal du blot gennemføre overgangen på CPU'en - lidt længere forsinkelse, indtil billedet vises fuldt ud, men det skal være acceptabelt. Husk at programmere asynkront ved at bruge flere tråde at skærmen ikke fryser, mens du venter på CPU'en. Du kan spille med forskellige effekter: Viser hele billedet på en gang, uklar først og langsomt stigende detaljer (bredde første søgning (BFS)) eller gør det flise ved flise første søgning (DFS)) - måske blandet med nogle flotte effekter.

  • Software implementering skal være temmelig let, når det kun tillader visning af lærredet i fuld opløsning. Hvis man kan zoome ud i trin, der er en mindre ændring i krydset. Hvis man kan zoome sømløst, kræver det 'lineær interpolation mellem nabokvadetræer' fliser - ikke trivielt mere, men gennemførlig.

  • Lag: Quadtree'en skal give dig lavt nok hukommelsesforbrug, så du kun kan gemme en quadtree per lag. Men når du har mange lag, skal du have nogle optimeringer til at forblive i realtid: Du kan ikke samle 200 teksturer pr. Ramme og sende dem til GPU'en. Måske (ikke helt sikker på om det er s den bedste løsning) for hvert lag sletter alle knudepunkter i kvadrater under det lag, hvis flise pixels er fuldstændigt dækket af ovenstående lag. Det skal gøres ved kørsel under tegning, og der kræves en dybdebuffer. viskelæderværktøj, kan du ikke slette noder, men skal markere dem som 'usynlige', så de kan udelades under traversal.



.. fra toppen af ​​mit hoved Hvis du har yderligere spørgsmål, lad mig vide! [1]