Misterioso problema de "desaceleración progresiva" en run loop / drawRect

Aquí hay un verdadero misterio.

Imagine que está haciendo el process convencional de dibujar una image compleja fuera de la pantalla (CGLayer), y está actualizando la image en la pantalla intermitentemente a medida que dibuja.

Como saben, la forma de hacer esto es: ejecutar el process de dibujo grande en segundo plano, y llamar al primer plano para establecer las visualizaciones de núcleo como se desee, haciendo que la image se actualice. Esto es trivial y se logra con dos líneas de código.

Sin embargo, cuando haces esto, hay un problema misterioso: el time requerido para cada ciclo de dibujo, aumenta cada vez, volviéndose inutilizable . Además, el time puede variar erráticamente.

¿Es este un error conocido de iOS? ¿Alguien ha visto esto antes?

Aquí hay una aplicación extremadamente trivial, extremadamente fácil de entender, que demos el problema:

http://www.fileswap.com/dl/p8lU3gAi/stepwiseDrawingV2.zip.html

Ejemplo de salida a continuación.

¿Alguien sabe por qué pasa esto? Es un comportamiento muy extraño del sistema operativo.

Más tarde … FELZ descubrió un trabajo asombroso. Felz copy el CGLayer una vez en cada ronda. Esto detiene por completo el extraño comportamiento.

Sin embargo, todavía no hay una comprensión realmente clara de qué diablos sucedía exactamente: por lo tanto, literalmente, ¿dónde está el time que se usa cuando el problema extraño exhibe?

Y aquí hay un largo ejemplo de la salida …

Tenga en count que a veces obtiene un resultado "doblemente extraño" como el siguiente: muestra el comportamiento extraño "normal": el time aumenta cada vez que ocurre. Sin embargo, de vez en cuando el time se networkingucirá a "increíblemente rápido" durante un par de rondas, y luego regresará. Extraño eh Además, si está ejecutando en su simulador, haga clic hacia atrás y adelante rápidamente a aplicaciones no relacionadas en su Mac para get resultados "incluso más extraños".

Aunque Felz ha dado una respuesta de trabajo perfecta, el mecanismo real sigue siendo un misterio.

:26:56.697 stepwiseDrawing[5334:1a03] time difference was 0 :26:56.707 stepwiseDrawing[5334:1a03] time difference was 10 :26:56.717 stepwiseDrawing[5334:1a03] time difference was 10 :26:56.744 stepwiseDrawing[5334:1a03] time difference was 27 :26:56.771 stepwiseDrawing[5334:1a03] time difference was 27 :26:56.807 stepwiseDrawing[5334:1a03] time difference was 37 :26:56.829 stepwiseDrawing[5334:1a03] time difference was 22 :26:56.864 stepwiseDrawing[5334:1a03] time difference was 35 :26:56.891 stepwiseDrawing[5334:1a03] time difference was 28 :26:56.936 stepwiseDrawing[5334:1a03] time difference was 45 :26:56.949 stepwiseDrawing[5334:1a03] time difference was 12 :26:56.981 stepwiseDrawing[5334:1a03] time difference was 32 :26:57.008 stepwiseDrawing[5334:1a03] time difference was 27 :26:57.041 stepwiseDrawing[5334:1a03] time difference was 33 :26:57.074 stepwiseDrawing[5334:1a03] time difference was 34 :26:57.109 stepwiseDrawing[5334:1a03] time difference was 34 :26:57.143 stepwiseDrawing[5334:1a03] time difference was 35 :26:57.179 stepwiseDrawing[5334:1a03] time difference was 36 :26:57.220 stepwiseDrawing[5334:1a03] time difference was 42 :26:57.271 stepwiseDrawing[5334:1a03] time difference was 51 :26:57.312 stepwiseDrawing[5334:1a03] time difference was 40 :26:57.356 stepwiseDrawing[5334:1a03] time difference was 45 :26:57.400 stepwiseDrawing[5334:1a03] time difference was 44 :26:57.447 stepwiseDrawing[5334:1a03] time difference was 46 :26:57.493 stepwiseDrawing[5334:1a03] time difference was 46 :26:57.542 stepwiseDrawing[5334:1a03] time difference was 49 :26:57.593 stepwiseDrawing[5334:1a03] time difference was 50 :26:57.707 stepwiseDrawing[5334:1a03] time difference was 114 :26:57.766 stepwiseDrawing[5334:1a03] time difference was 58 :26:57.801 stepwiseDrawing[5334:1a03] time difference was 36 :26:57.856 stepwiseDrawing[5334:1a03] time difference was 55 :26:57.918 stepwiseDrawing[5334:1a03] time difference was 62 :26:57.976 stepwiseDrawing[5334:1a03] time difference was 58 :26:58.039 stepwiseDrawing[5334:1a03] time difference was 62 :26:58.101 stepwiseDrawing[5334:1a03] time difference was 63 :26:58.165 stepwiseDrawing[5334:1a03] time difference was 63 :26:58.229 stepwiseDrawing[5334:1a03] time difference was 64 :26:58.294 stepwiseDrawing[5334:1a03] time difference was 66 :26:58.365 stepwiseDrawing[5334:1a03] time difference was 70 :26:58.436 stepwiseDrawing[5334:1a03] time difference was 72 :26:58.507 stepwiseDrawing[5334:1a03] time difference was 70 :26:58.572 stepwiseDrawing[5334:1a03] time difference was 65 :26:58.652 stepwiseDrawing[5334:1a03] time difference was 81 :26:58.726 stepwiseDrawing[5334:1a03] time difference was 74 :26:58.809 stepwiseDrawing[5334:1a03] time difference was 82 :26:58.879 stepwiseDrawing[5334:1a03] time difference was 70 :26:58.965 stepwiseDrawing[5334:1a03] time difference was 87 :26:59.043 stepwiseDrawing[5334:1a03] time difference was 77 :26:59.126 stepwiseDrawing[5334:1a03] time difference was 83 :26:59.210 stepwiseDrawing[5334:1a03] time difference was 84 :26:59.215 stepwiseDrawing[5334:1a03] time difference was 6 :26:59.310 stepwiseDrawing[5334:1a03] time difference was 95 :26:59.397 stepwiseDrawing[5334:1a03] time difference was 87 :26:59.486 stepwiseDrawing[5334:1a03] time difference was 89 :26:59.577 stepwiseDrawing[5334:1a03] time difference was 91 :26:59.668 stepwiseDrawing[5334:1a03] time difference was 91 :26:59.768 stepwiseDrawing[5334:1a03] time difference was 100 :26:59.856 stepwiseDrawing[5334:1a03] time difference was 88 :26:59.857 stepwiseDrawing[5334:1a03] time difference was 1 :26:59.965 stepwiseDrawing[5334:1a03] time difference was 108 :27:00.064 stepwiseDrawing[5334:1a03] time difference was 100 :27:00.165 stepwiseDrawing[5334:1a03] time difference was 101 :27:00.268 stepwiseDrawing[5334:1a03] time difference was 103 :27:00.371 stepwiseDrawing[5334:1a03] time difference was 103 :27:00.377 stepwiseDrawing[5334:1a03] time difference was 7 :27:00.493 stepwiseDrawing[5334:1a03] time difference was 115 :27:00.601 stepwiseDrawing[5334:1a03] time difference was 108 :27:00.710 stepwiseDrawing[5334:1a03] time difference was 109 :27:00.820 stepwiseDrawing[5334:1a03] time difference was 111 :27:00.939 stepwiseDrawing[5334:1a03] time difference was 119 :27:01.053 stepwiseDrawing[5334:1a03] time difference was 114 :27:01.162 stepwiseDrawing[5334:1a03] time difference was 108 :27:01.278 stepwiseDrawing[5334:1a03] time difference was 116 :27:01.396 stepwiseDrawing[5334:1a03] time difference was 118 :27:01.515 stepwiseDrawing[5334:1a03] time difference was 119 :27:01.637 stepwiseDrawing[5334:1a03] time difference was 122 :27:01.648 stepwiseDrawing[5334:1a03] time difference was 11 :27:01.769 stepwiseDrawing[5334:1a03] time difference was 121 :27:01.775 stepwiseDrawing[5334:1a03] time difference was 6 :27:01.910 stepwiseDrawing[5334:1a03] time difference was 135 :27:01.911 stepwiseDrawing[5334:1a03] time difference was 1 :27:02.045 stepwiseDrawing[5334:1a03] time difference was 134 :27:02.175 stepwiseDrawing[5334:1a03] time difference was 131 :27:02.314 stepwiseDrawing[5334:1a03] time difference was 139 :27:02.441 stepwiseDrawing[5334:1a03] time difference was 127 :27:02.586 stepwiseDrawing[5334:1a03] time difference was 145 :27:02.715 stepwiseDrawing[5334:1a03] time difference was 129 :27:02.853 stepwiseDrawing[5334:1a03] time difference was 138 :27:03.000 stepwiseDrawing[5334:1a03] time difference was 146 :27:03.133 stepwiseDrawing[5334:1a03] time difference was 134 :27:03.276 stepwiseDrawing[5334:1a03] time difference was 142 :27:03.419 stepwiseDrawing[5334:1a03] time difference was 143 :27:03.564 stepwiseDrawing[5334:1a03] time difference was 145 :27:03.717 stepwiseDrawing[5334:1a03] time difference was 153 :27:03.858 stepwiseDrawing[5334:1a03] time difference was 141 :27:04.008 stepwiseDrawing[5334:1a03] time difference was 149 :27:04.159 stepwiseDrawing[5334:1a03] time difference was 151 :27:04.318 stepwiseDrawing[5334:1a03] time difference was 159 :27:04.471 stepwiseDrawing[5334:1a03] time difference was 153 :27:04.620 stepwiseDrawing[5334:1a03] time difference was 149 :27:04.778 stepwiseDrawing[5334:1a03] time difference was 158 :27:04.939 stepwiseDrawing[5334:1a03] time difference was 161 :27:05.098 stepwiseDrawing[5334:1a03] time difference was 160 :27:05.269 stepwiseDrawing[5334:1a03] time difference was 171 :27:05.433 stepwiseDrawing[5334:1a03] time difference was 164 :27:05.600 stepwiseDrawing[5334:1a03] time difference was 166 :27:05.765 stepwiseDrawing[5334:1a03] time difference was 165 :27:05.932 stepwiseDrawing[5334:1a03] time difference was 167 :27:06.107 stepwiseDrawing[5334:1a03] time difference was 175 :27:06.269 stepwiseDrawing[5334:1a03] time difference was 163 :27:06.441 stepwiseDrawing[5334:1a03] time difference was 171 :27:06.617 stepwiseDrawing[5334:1a03] time difference was 176 :27:06.798 stepwiseDrawing[5334:1a03] time difference was 181 :27:06.971 stepwiseDrawing[5334:1a03] time difference was 173 :27:07.154 stepwiseDrawing[5334:1a03] time difference was 183 :27:07.326 stepwiseDrawing[5334:1a03] time difference was 172 :27:07.513 stepwiseDrawing[5334:1a03] time difference was 187 :27:07.689 stepwiseDrawing[5334:1a03] time difference was 176 :27:07.875 stepwiseDrawing[5334:1a03] time difference was 185 :27:08.059 stepwiseDrawing[5334:1a03] time difference was 184 :27:08.251 stepwiseDrawing[5334:1a03] time difference was 192 :27:08.432 stepwiseDrawing[5334:1a03] time difference was 181 :27:08.620 stepwiseDrawing[5334:1a03] time difference was 188 :27:08.811 stepwiseDrawing[5334:1a03] time difference was 190 :27:09.004 stepwiseDrawing[5334:1a03] time difference was 193 :27:09.195 stepwiseDrawing[5334:1a03] time difference was 191 :27:09.393 stepwiseDrawing[5334:1a03] time difference was 198 :27:09.590 stepwiseDrawing[5334:1a03] time difference was 197 :27:09.795 stepwiseDrawing[5334:1a03] time difference was 205 :27:09.989 stepwiseDrawing[5334:1a03] time difference was 193 :27:10.189 stepwiseDrawing[5334:1a03] time difference was 200 :27:10.392 stepwiseDrawing[5334:1a03] time difference was 203 :27:10.600 stepwiseDrawing[5334:1a03] time difference was 208 :27:10.801 stepwiseDrawing[5334:1a03] time difference was 202 :27:11.006 stepwiseDrawing[5334:1a03] time difference was 205 :27:11.220 stepwiseDrawing[5334:1a03] time difference was 213 :27:11.430 stepwiseDrawing[5334:1a03] time difference was 210 :27:11.633 stepwiseDrawing[5334:1a03] time difference was 203 :27:11.843 stepwiseDrawing[5334:1a03] time difference was 210 :27:12.055 stepwiseDrawing[5334:1a03] time difference was 213 :27:12.276 stepwiseDrawing[5334:1a03] time difference was 220 :27:12.484 stepwiseDrawing[5334:1a03] time difference was 208 :27:12.700 stepwiseDrawing[5334:1a03] time difference was 216 :27:12.919 stepwiseDrawing[5334:1a03] time difference was 219 :27:13.145 stepwiseDrawing[5334:1a03] time difference was 226 :27:13.360 stepwiseDrawing[5334:1a03] time difference was 215 :27:13.584 stepwiseDrawing[5334:1a03] time difference was 224 :27:13.813 stepwiseDrawing[5334:1a03] time difference was 229 :27:14.049 stepwiseDrawing[5334:1a03] time difference was 236 :27:14.269 stepwiseDrawing[5334:1a03] time difference was 220 :27:14.496 stepwiseDrawing[5334:1a03] time difference was 228 :27:14.725 stepwiseDrawing[5334:1a03] time difference was 229 :27:14.963 stepwiseDrawing[5334:1a03] time difference was 238 :27:15.196 stepwiseDrawing[5334:1a03] time difference was 232 :27:15.423 stepwiseDrawing[5334:1a03] time difference was 227 :27:15.657 stepwiseDrawing[5334:1a03] time difference was 235 :27:15.901 stepwiseDrawing[5334:1a03] time difference was 243 :27:16.133 stepwiseDrawing[5334:1a03] time difference was 232 :27:16.372 stepwiseDrawing[5334:1a03] time difference was 240 :27:16.613 stepwiseDrawing[5334:1a03] time difference was 241 :27:16.863 stepwiseDrawing[5334:1a03] time difference was 250 :27:17.101 stepwiseDrawing[5334:1a03] time difference was 238 :27:17.346 stepwiseDrawing[5334:1a03] time difference was 245 :27:17.593 stepwiseDrawing[5334:1a03] time difference was 247 :27:17.849 stepwiseDrawing[5334:1a03] time difference was 256 :27:18.093 stepwiseDrawing[5334:1a03] time difference was 244 :27:18.344 stepwiseDrawing[5334:1a03] time difference was 251 :27:18.603 stepwiseDrawing[5334:1a03] time difference was 260 :27:18.854 stepwiseDrawing[5334:1a03] time difference was 251 :27:19.114 stepwiseDrawing[5334:1a03] time difference was 259 :27:19.376 stepwiseDrawing[5334:1a03] time difference was 263 :27:19.646 stepwiseDrawing[5334:1a03] time difference was 270 :27:19.927 stepwiseDrawing[5334:1a03] time difference was 281 :27:20.202 stepwiseDrawing[5334:1a03] time difference was 274 :27:20.460 stepwiseDrawing[5334:1a03] time difference was 259 :27:20.743 stepwiseDrawing[5334:1a03] time difference was 283 :27:21.011 stepwiseDrawing[5334:1a03] time difference was 268 :27:21.281 stepwiseDrawing[5334:1a03] time difference was 270 :27:21.563 stepwiseDrawing[5334:1a03] time difference was 282 :27:21.848 stepwiseDrawing[5334:1a03] time difference was 284 :27:22.126 stepwiseDrawing[5334:1a03] time difference was 278 :27:22.398 stepwiseDrawing[5334:1a03] time difference was 272 :27:22.677 stepwiseDrawing[5334:1a03] time difference was 279 :27:22.970 stepwiseDrawing[5334:1a03] time difference was 293 :27:23.258 stepwiseDrawing[5334:1a03] time difference was 288 :27:23.545 stepwiseDrawing[5334:1a03] time difference was 287 :27:23.834 stepwiseDrawing[5334:1a03] time difference was 289 :27:24.122 stepwiseDrawing[5334:1a03] time difference was 288 :27:24.413 stepwiseDrawing[5334:1a03] time difference was 292 :27:24.708 stepwiseDrawing[5334:1a03] time difference was 295 :27:25.002 stepwiseDrawing[5334:1a03] time difference was 294 :27:25.303 stepwiseDrawing[5334:1a03] time difference was 301 :27:25.585 stepwiseDrawing[5334:1a03] time difference was 282 :27:25.880 stepwiseDrawing[5334:1a03] time difference was 294 :27:26.174 stepwiseDrawing[5334:1a03] time difference was 294 :27:26.470 stepwiseDrawing[5334:1a03] time difference was 296 :27:26.475 stepwiseDrawing[5334:1a03] time difference was 5 :27:26.777 stepwiseDrawing[5334:1a03] time difference was 302 :27:27.077 stepwiseDrawing[5334:1a03] time difference was 299 :27:27.373 stepwiseDrawing[5334:1a03] time difference was 297 

Primero déjeme decir que este fue un interesante rompecabezas. Me divertí mucho trabajando en esto. Buena pregunta y buen código de muestra.

Aquí está mi opinión sobre una posible respuesta:

El problema que veo es el siguiente. CGLayer son excelentes para pintar repetidamente porque almacenan en caching su representación en una image plana. El caching se invalida cuando se agregan operaciones adicionales al context. Cuando esto sucede, el CGLayer se vuelve a representar. La desaceleración es causa porque el código mantiene un único CGLayer ( fuera de pantallaPrefabCGL ) que tiene su context modificado en cada iteración del ciclo en paintActualGutsOfHugeImage . Debido a que la secuencia de operaciones en el context de outscreenPrefabCGL crece con cada flor, cada renderización lleva más time. Esto explica el aumento de time para cada pantalla.

Veo dos soluciones:

  1. Recorte la nueva representación en una particular en PaintView. En lugar de invalidar la vista completa, invalida solo el CGRect que realmente necesita volver a pintar. Esto, como lo entiendo, es la solución propuesta por @ v01d.
  2. Aplana la capa. En lugar de mantener un solo CGLayer, copie el CGLayer en cada iteración. Esto mantiene una image plana en la capa que es muy rápida de representar.

Implementé (2) con buenos resultados. Las primeras 100 flores son más rápidas y luego se estabilizarán en 120 ms (en el Dispositivo). Probé mi versión modificada con hasta 2000 flores.

Mi versión modificada está en:

http://dl.dropbox.com/u/9866261/felz_mod_stepwiseDrawingV2.zip

EDIT2:

Aquí hay un proyecto de debugging que funciona (sin ralentización): http://bit.ly/eukSgR

Este proyecto no es de ninguna manera óptimo.

Lo que es interesante aquí es la necesidad de un context bitmap. Un CGLayer guarda en caching tus sorteos de imágenes y provoca tu ralentización progresiva. Con un context bitmap se fuerza a renderizar; y luego simplemente estás empujando esos píxeles al CALayer de UIView en drawRect :.

Supongo que para get más velocidad, puede usar setNeedsDisplayInRect: para minimizar el área para volver a dibujar.

Pero, aparte de tal vez una optimization o dos aquí y allá, empujar píxeles a través de una UIView siempre será más lento que hacerlo en la GPU completamente a través de decir GL.

Como un experimento, sugiero que actualice su vista de progreso animada sin tratar de dibujar o leer desde el bitmap de imágenes grandes sin terminar o el dibujo de capas en progreso. Leer o dibujar con una composition sin terminar en otro context de dibujo puede estar haciendo cosas interesantes para el estado de la tubería o el estado de dibujo de la GPU. Intenta dibujar algo más en tu método de pimienta. Un contador simple o algo así.