1
0
mirror of synced 2024-11-27 23:50:47 +01:00

Speed up animation rendering a bit by caching some calculated properties from PIL.

This commit is contained in:
Jennifer Taylor 2021-05-16 00:18:59 +00:00
parent afb5eaa6fb
commit f74dd8c136
2 changed files with 35 additions and 28 deletions

View File

@ -433,7 +433,7 @@ class AFPRenderer(VerboseOutput):
transform.c == 0.0 and transform.c == 0.0 and
transform.a == 1.0 and transform.a == 1.0 and
transform.d == 1.0 and transform.d == 1.0 and
blend == 0 (blend == 0 or blend == 2)
): ):
# We can! # We can!
cutin = transform.multiply_point(Point.identity().subtract(origin)) cutin = transform.multiply_point(Point.identity().subtract(origin))
@ -451,34 +451,41 @@ class AFPRenderer(VerboseOutput):
imgmap = list(img.getdata()) imgmap = list(img.getdata())
texmap = list(texture.getdata()) texmap = list(texture.getdata())
# These are calculated properties and caching them outside of the loop
# speeds things up a bit.
imgwidth = img.width
imgheight = img.height
texwidth = texture.width
texheight = texture.height
# Calculate the maximum range of update this texture can possibly reside in. # Calculate the maximum range of update this texture can possibly reside in.
pix1 = transform.multiply_point(Point.identity().subtract(origin)) pix1 = transform.multiply_point(Point.identity().subtract(origin))
pix2 = transform.multiply_point(Point.identity().subtract(origin).add(Point(texture.width, 0))) pix2 = transform.multiply_point(Point.identity().subtract(origin).add(Point(texwidth, 0)))
pix3 = transform.multiply_point(Point.identity().subtract(origin).add(Point(0, texture.height))) pix3 = transform.multiply_point(Point.identity().subtract(origin).add(Point(0, texheight)))
pix4 = transform.multiply_point(Point.identity().subtract(origin).add(Point(texture.width, texture.height))) pix4 = transform.multiply_point(Point.identity().subtract(origin).add(Point(texwidth, texheight)))
# Map this to the rectangle we need to sweep in the rendering image. # Map this to the rectangle we need to sweep in the rendering image.
minx = max(int(min(pix1.x, pix2.x, pix3.x, pix4.x)), 0) minx = max(int(min(pix1.x, pix2.x, pix3.x, pix4.x)), 0)
maxx = min(int(max(pix1.x, pix2.x, pix3.x, pix4.x)) + 1, img.width) maxx = min(int(max(pix1.x, pix2.x, pix3.x, pix4.x)) + 1, imgwidth)
miny = max(int(min(pix1.y, pix2.y, pix3.y, pix4.y)), 0) miny = max(int(min(pix1.y, pix2.y, pix3.y, pix4.y)), 0)
maxy = min(int(max(pix1.y, pix2.y, pix3.y, pix4.y)) + 1, img.height) maxy = min(int(max(pix1.y, pix2.y, pix3.y, pix4.y)) + 1, imgheight)
announced = False announced = False
for imgy in range(miny, maxy): for imgy in range(miny, maxy):
for imgx in range(minx, maxx): for imgx in range(minx, maxx):
# Determine offset # Determine offset
imgoff = imgx + (imgy * img.width) imgoff = imgx + (imgy * imgwidth)
# Calculate what texture pixel data goes here. # Calculate what texture pixel data goes here.
texloc = inverse.multiply_point(Point(float(imgx), float(imgy))).add(origin) texloc = inverse.multiply_point(Point(float(imgx), float(imgy))).add(origin)
texx, texy = texloc.as_tuple() texx, texy = texloc.as_tuple()
# If we're out of bounds, don't update. # If we're out of bounds, don't update.
if texx < 0 or texy < 0 or texx >= texture.width or texy >= texture.height: if texx < 0 or texy < 0 or texx >= texwidth or texy >= texheight:
continue continue
# Blend it. # Blend it.
texoff = texx + (texy * texture.width) texoff = texx + (texy * texwidth)
if blend == 0 or blend == 2: if blend == 0 or blend == 2:
imgmap[imgoff] = self.__blend_normal(imgmap[imgoff], texmap[texoff], mult_color, add_color) imgmap[imgoff] = self.__blend_normal(imgmap[imgoff], texmap[texoff], mult_color, add_color)
@ -544,13 +551,13 @@ class AFPRenderer(VerboseOutput):
return src return src
# Calculate alpha blending. # Calculate alpha blending.
srcpercent = (float(src[3]) / 255.0) srcpercent = src[3] / 255.0
destpercent = (float(dest[3]) / 255.0) destpercent = dest[3] / 255.0
destremainder = 1.0 - srcpercent destremainder = 1.0 - srcpercent
return ( return (
self.__clamp((float(dest[0]) * destpercent * destremainder) + (float(src[0]) * srcpercent)), self.__clamp((dest[0] * destpercent * destremainder) + (src[0] * srcpercent)),
self.__clamp((float(dest[1]) * destpercent * destremainder) + (float(src[1]) * srcpercent)), self.__clamp((dest[1] * destpercent * destremainder) + (src[1] * srcpercent)),
self.__clamp((float(dest[2]) * destpercent * destremainder) + (float(src[2]) * srcpercent)), self.__clamp((dest[2] * destpercent * destremainder) + (src[2] * srcpercent)),
self.__clamp(255 * (srcpercent + destpercent * destremainder)), self.__clamp(255 * (srcpercent + destpercent * destremainder)),
) )
@ -582,11 +589,11 @@ class AFPRenderer(VerboseOutput):
return dest return dest
# Calculate alpha blending. # Calculate alpha blending.
srcpercent = (float(src[3]) / 255.0) srcpercent = src[3] / 255.0
return ( return (
self.__clamp(dest[0] + (float(src[0]) * srcpercent)), self.__clamp(dest[0] + (src[0] * srcpercent)),
self.__clamp(dest[1] + (float(src[1]) * srcpercent)), self.__clamp(dest[1] + (src[1] * srcpercent)),
self.__clamp(dest[2] + (float(src[2]) * srcpercent)), self.__clamp(dest[2] + (src[2] * srcpercent)),
self.__clamp(dest[3] + (255 * srcpercent)), self.__clamp(dest[3] + (255 * srcpercent)),
) )
@ -618,11 +625,11 @@ class AFPRenderer(VerboseOutput):
return dest return dest
# Calculate alpha blending. # Calculate alpha blending.
srcpercent = (float(src[3]) / 255.0) srcpercent = src[3] / 255.0
return ( return (
self.__clamp(dest[0] - (float(src[0]) * srcpercent)), self.__clamp(dest[0] - (src[0] * srcpercent)),
self.__clamp(dest[1] - (float(src[1]) * srcpercent)), self.__clamp(dest[1] - (src[1] * srcpercent)),
self.__clamp(dest[2] - (float(src[2]) * srcpercent)), self.__clamp(dest[2] - (src[2] * srcpercent)),
self.__clamp(dest[3] - (255 * srcpercent)), self.__clamp(dest[3] - (255 * srcpercent)),
) )
@ -656,10 +663,10 @@ class AFPRenderer(VerboseOutput):
# Calculate alpha blending. # Calculate alpha blending.
return ( return (
self.__clamp(255 * ((float(dest[0]) / 255.0) * (float(src[0]) / 255.0))), self.__clamp(255 * ((dest[0] / 255.0) * (src[0] / 255.0))),
self.__clamp(255 * ((float(dest[1]) / 255.0) * (float(src[1]) / 255.0))), self.__clamp(255 * ((dest[1] / 255.0) * (src[1] / 255.0))),
self.__clamp(255 * ((float(dest[2]) / 255.0) * (float(src[2]) / 255.0))), self.__clamp(255 * ((dest[2] / 255.0) * (src[2] / 255.0))),
self.__clamp(255 * ((float(dest[3]) / 255.0) * (float(src[3]) / 255.0))), self.__clamp(255 * ((dest[3] / 255.0) * (src[3] / 255.0))),
) )
def __process_tags(self, clip: PlacedClip, prefix: str = " ") -> bool: def __process_tags(self, clip: PlacedClip, prefix: str = " ") -> bool:
@ -749,7 +756,7 @@ class AFPRenderer(VerboseOutput):
try: try:
while root_clip.running: while root_clip.running:
# Create a new image to render into. # Create a new image to render into.
time = spf * float(frameno) time = spf * frameno
color = swf.color or Color(0.0, 0.0, 0.0, 0.0) color = swf.color or Color(0.0, 0.0, 0.0, 0.0)
self.vprint(f"Rendering Frame {frameno} ({time}s)") self.vprint(f"Rendering Frame {frameno} ({time}s)")

View File

@ -44,7 +44,7 @@ class Point:
} }
def as_tuple(self) -> Tuple[int, int]: def as_tuple(self) -> Tuple[int, int]:
return (int(self.x), int(self.y)) return (round(self.x), round(self.y))
def add(self, other: "Point") -> "Point": def add(self, other: "Point") -> "Point":
x = self.x + other.x x = self.x + other.x