Discussion:
[Pipmak-Devel] This code show the image-cache-bug...
Andrea Viarengo
2007-10-24 10:48:59 UTC
Permalink
Hi,

I post a little piece of lua code that show the bug concerned cached image,
could be useful for debug:

You can start from a new project, I used only 2 image file "white.png" and "
black.png" both
512x512 and with just one color inside
----------------------------------------------------------------------------------------------------------------
cubic {"white.png","white.png","white.png","white.png","white.png","
white.png"}

function draw(t)

dimx,dimy=t.image:size()
p=patch {face=3,nw=2,nh=2,anchorv=dimy/2,anchorh=dimx/2,
x=0,y=0,
ny=t.height,nz=t.distance,nx=t.lateral,
visible=true,
image=t.image}
end

pipmak.setverticalfov(80)

-- draw a RED square in the middle of face 3

img=pipmak.loadimage("black.png")
img:color(1,0.5,0.5,1):fill()
draw{distance=4,lateral=0,height=0,image=img}

-- draw a BLACK square at the left of red square

img2=pipmak.loadimage("black.png")
draw{distance=4,lateral=2,height=0,image=img2}

-- draw a BLACK square at the right of red square

img3=pipmak.loadimage("black.png")
draw{distance=4,lateral=-2,height=0,image=img3}

-- draw a RED square above the first red square

img4=pipmak.loadimage("black.png")
-- next statement show the bug:
-- all the square become red!!!! Why?????
img4:color(1,0.5,0.5,1):fill()
draw{distance=4,lateral=0,height=2,image=img4}
----------------------------------------------------------------------------------------------------------------

With this code you should get 2 squares red and 2 squares black, but instead
you get 4 squares red!!!!
You can see the result in picture 1
If you comment-out last 2 lines the bug disapear, as you can see in picture
2

Bye.

Andrea
Christian Walther
2008-01-02 17:26:05 UTC
Permalink
Post by Andrea Viarengo
-- draw a BLACK square at the left of red square
img2=pipmak.loadimage("black.png")
draw{distance=4,lateral=2,height=0,image=img2}
-- draw a BLACK square at the right of red square
img3=pipmak.loadimage("black.png")
draw{distance=4,lateral=-2,height=0,image=img3}
-- draw a RED square above the first red square
img4=pipmak.loadimage("black.png")
-- all the square become red!!!! Why?????
img4:color(1,0.5,0.5,1):fill()
draw{distance=4,lateral=0,height=2,image=img4}
I've just had a look at this, and I've come to the conclusion that it
works as designed - though admittedly the design is flawed.

What trips you up is this (from section 3.12 "Image Manipulation" of the
reference):
"pipmak.loadimage(filename) ... Calling this function multiple times
with the same path returns the same object, and the image is only
reloaded from disk if it isn’t already in memory."

So what happens is that img2, img3, and img4 all refer to the same
object, and when you modify that object in the second-to-last line, the
change reflects in all three patches that use it.

(img1 is not involved because you modify it before loading img2, so at
that point loadimage knows that it really needs to reload the file and
give you a new image object.)

I'm not sure what the best solution to this is. I don't think giving up
the returns-the-same-object behavior of pipmak.loadimage is a good idea,
as I rely on it in many places. I'll try to think of something better,
but in the meantime I just wanted to let you know this much (I've kept
you waiting long enough...).

Thinking out loud: The fundamental issue is that the caching behavior of
pipmak.loadimage, which was good for immutable objects, clashes with the
fact that images have now become mutable. Perhaps some kind of
copy-on-write scheme could reunite the two.

-Christian

Loading...