Estoy desarrollando una aplicación de dibujo en modo retenido en GDI +. La aplicación puede dibujar formas simples en un lienzo y realizar una edición básica. La matemática que hace esto está optimizada para el último byte y no es un problema. Estoy dibujando en un panel que está usando Controlstyles.DoubleBuffer incorporado.Winforms: Cómo acelerar Invalidate()?
Ahora, mi problema surge si ejecuto mi aplicación maximizada en un monitor grande (HD en mi caso). Si trato de dibujar una línea desde una esquina del lienzo (grande) hasta la diagonal opuesta a la otra, comenzará a lag y la CPU se disparará hacia arriba.
Cada objeto gráfico en mi aplicación tiene un cuadro delimitador. Por lo tanto, cuando invalido el cuadro delimitador de una línea que va de una esquina de la aplicación maximizada a la diagonal opuesta, ese cuadro delimitador es prácticamente tan grande como el lienzo. Cuando un usuario dibuja una línea, esta invalidación del cuadro delimitador ocurre así en el evento mousemove, y hay un retraso claro visible. Este retraso también existe si la línea es el único objeto en el lienzo.
He intentado optimizar esto de muchas maneras. Si dibujo una línea más corta, la CPU y el retraso disminuyen. Si elimino el Invalidate() y guardo el resto del código, la aplicación es rápida. Si uso una Región (que solo abarca la figura) para invalidar en lugar de la caja delimitadora, es igual de lenta. Si divido el cuadro delimitador en una serie de cuadros más pequeños que se encuentran uno detrás del otro, reduciendo así el área de invalidación, no se puede ver ninguna ganancia de rendimiento visible.
Por lo tanto, estoy perdido aquí. ¿Cómo puedo acelerar la invalidación?
En una nota lateral, Paint.Net y Mspaint sufren de las mismas deficiencias. Word y PowerPoint, sin embargo, parecen ser capaces de pintar una línea como se describió anteriormente sin retraso y sin carga de CPU en absoluto. Por lo tanto, es posible lograr los resultados deseados, la pregunta es ¿cómo?
Word y Powerpoint no usan GDI + ... No creo que GDI + alguna vez haya sido elogiado por su velocidad (a través de GDI normal). –
¿Ha intentado utilizar un generador de perfiles para ver dónde ocurre realmente la desaceleración? He hecho un montón de este tipo de cosas (hace años, en Delphi) y nunca he encontrado Invalidate() para tomar una cantidad de tiempo discernible. Pintar, por otro lado, fue "divertido" correr lo suficientemente rápido como para pegar una línea. – Bevan
Bueno, creo que Delphi es mucho más rápido para este tipo de trabajo en cualquier caso. Como dice Henk, GDI + no es conocido por su velocidad, es más probable que carezca de ella. Sin embargo, el código de dibujo real no es el cuello de botella. La invalidación de la gran área parece ser. Estoy considerando usar mi propio backbuffer y ajustar manualmente la imagen para ver si puedo obtener un aumento en el rendimiento. ¿Podría recomendar algún perfilador en particular para VS2005? – Pedery