Autore Topic: SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?  (Letto 1805 volte)

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
0
Da 4-5 giorni sto cercando di allocare memoria (il come non è importante ai fini del topic) manipolare il contenuto byte per byte e disegnarlo su schermo. In parole povere un caro vecchio framebuffer.

Premetto che OpenGL non è una opzione valida per quello che devo fare (e conseguentemente non lo sono andengine e compagnia).

Avevo del codice semi-funzionante venerdì scorso con prestazioni piuttosto scarse e ieri sono riuscito a ottenere un framerate buono e stabile senza utilizzare l'NDK (100% codice Java).

Durante la fase di sviluppo/ottimizzazione ho provato una miriade di soluzioni differenti (possibile che abbia tralasciato qualcosa alla luce delle ultime ottimizzazioni). Quello che mi lascia basito è che sul mio Galaxy S2 il lock/unlock del Canvas NON E' ASINCRONO.

Non ho idea se questo sia un comportamento normale ma se lo è ogni libro/tutorial/post/esempio che ho trovato in rete sulle surfaceview è completamente ERRATO!!!  :-o :-o :-o

Qualcuno sa se solo il mio device ha questo "difetto"????

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #1 il: 01 Marzo 2012, 12:36:19 CET »
0
Ma asincrono rispetto a cosa, al vsync?
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #2 il: 01 Marzo 2012, 12:58:20 CET »
0
Si rispetto al vsync.... e il problema è proprio che è sincrono, almeno sul mio device!

Quando faccio lock-modifica-unlock del canvas si attacca al vertical retrace del mio device (16.666ms... 60hz).

La cosa che secondo me non ha senso è che quando chiamo il canvas (dirtyrect a parte) non è garantito che sia rimasto intatto dal frame precedente. Questo implica che il sistema ha uno schema interno per il buffering (e fin qui ci siamo).

Ma se la chiamata è sincrona temporizzata sul vertical retrace questo significa anche che (almeno su un galaxy s2) lo schema utilizzato è, nella migliore delle ipotesi, double buffering. Non è una scelta furba infatti se utilizzassero triple buffering il problema della chiamata sincona non sussisterebbe perchè avrebbero un buffer corrente e due backbuffer e ogni volta che viene richiesto un lock non c'è bisogno di aspettare perchè hai due backbuffer e mi passi quello di due-tre (dipende da quando è stato aggiornato il frontbuffer) frame fa.

Così come è implementato su un galaxy s2 io chiamo il lock/unlock e questo invece di farmi lavorare subito col buffer attende il vertical retrace.

Infatti ad un certo punto tra un debug e l'altro devo avere mandato qualcosa in palla perchè l'app mi si bloccava con un bel "Layout repeat skipped after too many iterations" (messaggio del windowmanager che da google sembra venie fuori a volte su dei FW custom... a scanso di equivoci ho il FW originale e niente rooting) , mi distruggeva la surface e la ricreava. Ma "stranamente" prima che il windowmanager mi distruggesse la surface perchè facevo troppe richieste andava velocissimo!

Se la chiamata fosse asincrona o avessero implementato un triple buffer le miriadi di eventi che vengono generate dal telefono (wifi-sensori-servizi-gps-garbage collector) non mi andrebbero ad intaccare il framerate. Così come è stato implementato nel momento in cui accade qualcosa in background (e accade spesso) scendo automaticamente a 30hz perchè se "salto" la finestra di questo retrace anche se mi da subito il via libera devo ovviamente aspettare il prossimo retrace per vedere il prossimo frame!

A questo punto temo che questo sia il vero motivo per cui tutti dicono di NON usare surfaceview ma passare ad OpenGL.

Nessuno ha mai provato a calcolare un numero di pixel molto grande e poi disegnarlo su una surfaceview?

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #3 il: 02 Marzo 2012, 10:31:43 CET »
0
Stavo pensando che magari potrei postare del codice di prova... o un apk??? Forse qualcuno mi può aiutare a scoprire se è "difettato" il galaxy s2 o se è normale. :'(

Il problema è facilmente riproducibile, si tratta solo di avere una surfaceview che implementa Runnable con un thread di rendering che fa il lock/unlock (senza nemmeno toccare il canvas) e un blocco try/catch che manda se stesso in sleep.

Senza sleep il lock/unlock impiega 16-17ms.
Con lo sleep il lock/unlock impiega 0ms.

 >:( >:( >:(

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #4 il: 02 Marzo 2012, 10:54:48 CET »
+1
A questo punto temo che questo sia il vero motivo per cui tutti dicono di NON usare surfaceview ma passare ad OpenGL.

Leggendo un po' in giro pare proprio che tutte le view della UI lavorino con lock e unlock in double-buffering, quindi legate al vsync. E mi sembra anche la soluzione corretta (per un double buffer). Più che NON usare le SurfaceView, dipende dalle proprie esigenze... se proprio servono performance grafiche c'è la openGL.

NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #5 il: 02 Marzo 2012, 11:50:09 CET »
0
Leggendo un po' in giro pare proprio che tutte le view della UI lavorino con lock e unlock in double-buffering, quindi legate al vsync. E mi sembra anche la soluzione corretta (per un double buffer). Più che NON usare le SurfaceView, dipende dalle proprie esigenze... se proprio servono performance grafiche c'è la openGL.
Purtroppo openGL non può fisicamente fare quello che mi serve..  :-(

Comunque se tutte le view della UI lavorano in questo modo almeno non è il galaxy s2 difettato!

Tanto per "filosofeggiare" il comportamento sarebbe corretto se android fosse principalmente singlethreaded tipo iPhone o se avessi una scelta tra avere artefatti e andare in sleep.

In questo modo si verifica sistematicamente che qualcosa in background mi interrompe il thread di rendering, mi fa passare i 60hz e scendo subito a 30hz. Anche se nel tempo avrei potuto essere 1-2 frame "avanti" e non preoccuparmi del rallentamento temporaneo.  :-(


Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #6 il: 02 Marzo 2012, 12:07:05 CET »
0
Non conosco il tuo caso specifico, però concorderai che cercare di ottenere prestazioni tipiche di openGL con gli strumenti della UI standard è una cosa abbastanza insolita.

Se il rallentamento a 30Hz ti crea problemi per qualcosa che "si sfasa", tipo un gameloop o in generale un contatore di tempo, in linea di principio dal tempo di sistema potresti rilevare il salto e compensarlo. Questo ovviamente non sapendo minimamente cosa ci devi fare.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #7 il: 02 Marzo 2012, 13:55:12 CET »
+1
Non ho niente contro OpenGL ma quando lavori a poligoni non hai la stessa libertà che puoi avere con un framebuffer.

Per esempio:

https://market.android.com/details?id=com.xianle.doomtnt

E' vero che con OpenGL può farci Quake ma è proprio il concetto che è differente tra avere una mappa bidimensionale e tirare su delle linee di pixel e avere un livello poligonale organizzato con un BSP.   :'(

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #8 il: 28 Giugno 2012, 08:37:30 CEST »
0
Mi dispiace per il necroposting ma....

Non è una scelta furba infatti se utilizzassero triple buffering il problema della chiamata sincona non sussisterebbe

Google I/O: Android Jelly Bean and Nexus devices  - Mobile Phones - CNET - CNET Asia

Citazione
Project Butter, a performance-based enhancement to make the phone experience smooth (like butter). It uses VSync and Triple Buffering to enhance the touch responsiveness.

FINALMENTE SE NE SONO ACCORTI.  :-P

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #9 il: 28 Giugno 2012, 08:41:37 CEST »
0
FINALMENTE SE NE SONO ACCORTI.  :-P

Eheh vero  :D

...magari tra 9 mesi arriva anche su qualche device.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #10 il: 28 Giugno 2012, 08:52:15 CEST »
0
...magari tra 9 mesi arriva anche su qualche device.
hei detto bene... MAGARI!  :D

Dai almeno loro non presentano un sistema operativo nuovo di zecca e poi te lo rendono disponibile sul tuo telefono con 1 feature su 10. :D

Offline Nicola_D

  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:SurfaceView: Canvas lock-unlock non asincrono!?!?!?!?!?!?!?!?
« Risposta #11 il: 28 Giugno 2012, 08:56:49 CEST »
0
Eheh vero  :D

...magari tra 9 mesi arriva anche su qualche device.
io confido che il mio Nexus S ad agosto venga aggiornato.... ahhh che ottima scelta che ho fatto! :D
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia