Mostrando entradas con la etiqueta solution. Mostrar todas las entradas
Mostrando entradas con la etiqueta solution. Mostrar todas las entradas

jueves, 23 de abril de 2009

Cache:true ... otro detalle para mejorar el rendimiento gráfico


Si, por ejemplo, utilizas una figura con una gradiente -o sombra- como fondo de un área, es mejor agregar a esa figura el parámetro cache:true, de manera de evitar que el objeto sea re-dibujado con cada cambio que se realiza por encima de él (en el caso de una gradiente, debe volver a recalcular y redibujar cada franja de color que conforma la transición entre los colores... lo que resulta sumamente "caro" en términos de procesamiento).



El código al pie del artículo

Al agregar cache:true se le indica al sistema que debe generar la imagen una vez y guardarla en cache, de esta menera, cuando se realiza un cambio sobre ella, sólo recupera la imagen desde una copia almacenada en memoria (como bytes) y pinta los cambios encima, lo que resulta sumamente rápido y menos "costoso" en ciclos de procesamiento.

En todo caso, no debes utilizar cache:true cuando la imagen va a cambiar con frecuencia, porque esto sólo producirá que sea re-generada con cada cambio, pero además almacenada, lo que da por resultado un proceso mucho más "costoso". El cache:true debe ser utilizado en imágenes que NO cambian frecuentemente.




import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.shape.Rectangle;
import javafx.scene.paint.Color;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.scene.effect.DropShadow;

var px:Number;
var py:Number;
Timeline {
repeatCount: Timeline.INDEFINITE
autoReverse:true
keyFrames : [
KeyFrame {
time : 0s
values: [px=>100, py=>100]
}
KeyFrame {
time : 3s
canSkip : true
values: [px=>1180, py=>680]
}
]
}.play();

var angle:Number;
Timeline {
repeatCount: Timeline.INDEFINITE
autoReverse:true
keyFrames : [
KeyFrame {
time : 0s
values: [angle=>0]
}
KeyFrame {
time : 1.5s
canSkip : true
values: [angle=>360]
}
]
}.play();

Stage {
title: "Application title"
width: 1024
height: 768
scene: Scene {
content: [
Rectangle {
cache:true
x: 0, y: 0
width: 1280, height: 768
fill: LinearGradient {
startX : 0.0
startY : 0.0
endX : 1.0
endY : 0.0
stops: [
Stop {
color : Color.BLACK
offset: 0.0
},
Stop {
color : Color.BLUE
offset: 1.0
},

]
}
effect: DropShadow { offsetX:10, offsetY:10 }
}
Rectangle {
x: bind px, y: bind py
width: 200, height: 200
fill: Color.RED
rotate: bind angle
}

]
}
}

martes, 17 de marzo de 2009

Un pequeño bug en el Timeline y una solución


Estaba haciendo unas pruebas y de vez en cuando notaba un comportamiento extraño, finalmente descubrí que el problema se origina en la reutilización de un Timeline, que estaba definido como:

var timeline= Timeline {
repeatCount: 1
keyFrames: [
at (0s) { currentX => startX }
at (0.5s) { currentX => posX }
]
};

Aunque no es el ideal que haya bugs, es algo habitual en una plataforma nueva (he leído que Adobe Flex tiene demasiados bugs, así que -aunque es consuelo de tontos- me voy a conformar con este pequeño error en JavaFX).

La solución fue tan simple como... no reutilizar el Timeline una y otra vez, sino que recrearlo cuando lo voy a usar:

var timeline:Timeline;

...

timeline = Timeline {
repeatCount: 1
keyFrames: [
at (0s) { currentX => startX }
at (0.5s) { currentX => posX }
]
};
timeline.playFromStart();

El problema específico de mi programa, era que a veces asignaba currentX igual a 0 en at (0s), aunque startX no tenia ese valor.

En todo caso, no es un problema que ocurra con frecuencia (supongo que debe ser un pequeño error el compilador), así que no es necesario hacer esto cada vez que utilicen un Timeline... pero si notan algo extraño como que un elemento asociado de alguna manera a un timeline salta de manera no esperada, intenten esto (por lo menos hasta que el bug sea corregido).