2009-05-30 10 views
5

Voglio disegnare un grafico che si aggiorna in tempo reale (cresce da destra). Il modo più efficace a cui posso pensare sarebbe quello di copiare tutto da x [0 .. width-2] lasciato da 1 pixel, quindi disegnare il nuovo valore in x [width-1].Android: scorre in modo efficiente il contenuto di una tela?

Ho poca esperienza con Android, ma da quello che posso dire, Canvas non funziona affatto sui suoi contenuti. Devo ridipingere l'intero schermo ogni volta? Ciò comporta ridimensionamento e livellamento quindi sono preoccupato che sarà lento.

Devo disegnare in un byte [] [] quindi utilizzare questo per dipingere sullo schermo (spostando il contenuto del mio buffer lasciato ogni volta)?

+0

Penso di vedere un possibile approccio usando Bitmap, getPixels e setPixels. Non sono sicuro se questo è un approccio negativo, ma sto dando un colpo. Si prega di avvisare! –

risposta

0

Solo un pensiero, che potreste aver già considerato, ma non sposterei il contenuto del buffer: proverei solo a usarlo come un buffer circolare. Mantieni un indice per la colonna corrente e una volta che ti sei riavvolto verso la colonna più a sinistra puoi disegnare alla destinazione in due segmenti: ciò che è sul lato destro della colonna corrente e poi ciò che è a sinistra, incluso la colonna riempita più di recente. In questo modo non dovrai spostare nulla, e ogni aggiornamento dello schermo è solo di due blit (copie bitmap) per i due segmenti. Se quel bit è troppo lento, puoi sempre dipingerlo in un secondo buffer fuori dallo schermo prima di passare all'intero schermo tutto in una volta. Sicuramente un grande blit allo schermo è abbastanza veloce, no?

+0

Inoltre, qualcosa che ho dimenticato di menzionare (che di nuovo potresti considerare ovvio, ma non so cosa tu sappia, quindi perdonami) - Mi assicurerei che le tue immagini di buffer siano/siano inizializzate per corrispondere alla dimensione dell'area dello schermo su cui desideri disegnare e ridimensionare il disegno del grafico che fai a quelli, in modo che quando fai le grandi blitz la sorgente e la destinazione corrispondano il più possibile (stessa altezza e formato bitmap) e no il ridimensionamento è necessario. – themightyjon

1

Se il grafico è limitato, provare a visualizzarlo tutto in una volta su Immagine, quindi miscelare le parti pertinenti da quella Immagine al Tela. Cerca di evitare di "spostare" effettivamente i pixel nel buffer, poiché ciò potrebbe introdurre delle dipendenze tra le tue letture e le tue scritture e potrebbe davvero uccidere le prestazioni. In realtà potrebbe essere meglio copiare da 1 buffer a un altro e alternare quello che viene visualizzato sullo schermo. Infine, se si finisce per dover lavorare manualmente sui pixel, assicurarsi di eseguire l'immagine in linee anziché in colonne e di iniziare dalla riga per aiutare con la memorizzazione nella cache.

1

Per quanto riguarda le prestazioni, senza profilazione non possiamo dire.

È possibile che il disegno a linee sia accelerato via hardware sul telefono di destinazione e che si debba disegnare il grafico da zero usando le primitive di disegno a linee ogni fotogramma.

D'altra parte, la manipolazione dei pixel diretto di un buffer di immagine sarebbe:

creare un'immagine che è la dimensione giusta e liberate a un "background_color". Questa immagine deve avere la funzionalità setpixel().

Avere una matrice di valori che registrano la y di ogni x volta, quindi per qualsiasi colonna si conosce l'ultimo grafico tracciato.

Trattare questo "chart_image" e "chart_array" come un buffer circolare. Per ogni intervallo di tempo:

Y = ...; 
X = time_since_start % chart_width; 
chart_image.setpixel(X,chart_array[X],background_color); // clear previous line 
chart_array[X] = Y; 
chart_image.setpixel(X,chart_array[X],foreground_color); // draw new plot 

E ora è necessario blitarlo. È necessario blit l'immagine due volte:

X = time_since_start % chart_width; 
// the newest data is on the left of the chart_image but gets drawn on the right side of the output 
blit(out_x+X,out_y, // destination coordinates 
    chart_image, 
    0,0, // top left of part of chart_image to blit 
    X,chart_height); // bottom right of chart_image part 
// the oldest data is on the right of the chart_image but gets drawn on the left side of the output 
blit(out_x,out_y, 
    chart_image, 
    X,0, 
    chart_width,chart_height); 

Le cose si fanno più difficili, se si desidera utilizzare le linee piuttosto che i singoli pixel, ma un drawline() invece di un setpixel() può fare quel lavoro con questo approccio troppo.

(Chiede scusa per non conoscere le API Android, ma l'approccio è generico.)

0

Dato che posso dare per scontato che si stiano memorizzando i dati del grafico in memoria, il ridisegno non dovrebbe essere un problema. Non è affatto intensivo ridisegnare un set di punti ogni fotogramma. Spostare la memoria sarebbe intensa, spostando tutto contro solo dipingendo solo ciò di cui hai bisogno. Scenario peggiore, poiché è una funzione del tempo, solo un valore per colonna del display, aprox 800 pixel/valori in orizzontale che il sistema deve disegnare. È banale. Hai profilato questo? EDIT: Ricorda, non è che il sistema debba disegnare ogni punto, attinge solo alla memoria, quindi ne fa l'uso primitivo. Non pensare che iterazioni prenda spunto, scaricando nella memoria video, poi ancora.

Problemi correlati