Slowdown when putting symbols into image data

William Prothero prothero at earthednet.org
Tue Sep 9 13:51:03 EDT 2014


Folks:
Seems I’ve found the offending line in my draw script. Its:

>      put byte 1 to tLength of tbrushBinaryData into byte tNewStart * 4 - 3 to tNewStart*4 - 3  + tLength -1 of imgdata  -- insert brushimageData into image 

If I comment out this line, the symbols are drawn in 2.85 seconds, more than a factor of 10 speedup.
The context is indicated in the code below.

Is this to be expected in LC V7?

Best,
Bill

On Sep 9, 2014, at 9:40 AM, William Prothero <prothero at earthednet.org> wrote:

> Folks:
> Drawing symbols on an image, in my app, has gone up a factor of 10, from 2.25 seconds in version 6.6.2 to 24 seconds in version 7.0RC1. I’m on OSX, Mavericks. This is a significant slowdown. The slowdown occurs in the drawSymbol method. If I comment it out, so all the operations happen without actually drawing the symbol, the speed without drawing the symbol is 4.55 seconds in v7.0. I can tolerate the delay from 2.25 to 4.55 seconds, but the symbol drawing routine slowdown is quite significant and I’d like to see it speeded up.
> 
> My drawing code is derived from Colin’s SimplePaint program, modified for byte operations. The drawing code is below. First an array of the symbol image data is created, then when drawing all of the symbols, that array is accessed to put the image data into the binary of the image. I included the setSymbolArray handler (which is only called once), for clarity. The major slowdown is not in this method.
> 
> Can anybody, with a quick scan suggest how to optimize this, or perhaps its a problem with livecode. If it’s not obvious to anybody, I’ll see if I can narrow the problem to a specific line of script.
> 
> Thanks,
> Bill
> 
> —This is the draw program. For each symbol, the correct element of the symbol array is loaded to the array: sBrushDataArray
> on drawTheSymbol x,y
>   put round(x) into startX
>   put round(y) into startY
>   put round(sBrushWidth/4) into sXDelta
>   put round(sBrushHeight/2) into sYDelta
>   put the keys of sBrushDataArray into tBrushKeys
>   repeat for each line aKey in tBrushKeys
>      put sBrushDataArray[aKey] into tbrushBinaryData --  the current part of a row of binary data of brush 
>      put length (tbrushBinaryData) into tLength -- the length of the binary data
>      put aKey div sBrushWidth into tBrushRow -- calculate the row of the brush the data comes from
>      -- get currentBrushRow for calculation of imagedata row to fit it into the image, sYDelta offsets the brush
>      put tBrushRow + startY - sYDelta  into tImageCurrRow
> 
>      put aKey mod sBrushWidth into tCurrBrushColumn -- the column of the brush the current data comes from
>      put tCurrBrushColumn + startX - sXDelta into tCurrImageColumn -- the column in the image to fit into the imageData; sXDelta offsets the brush
> 
>      put tImageCurrRow * sMyWidth + tCurrImageColumn into tNewStart -- calculate the byte in xy coord of the image where to insert brushData

—** The following line is the one that causes the slowdown.
>      put byte 1 to tLength of tbrushBinaryData into byte tNewStart * 4 - 3 to tNewStart*4 - 3  + tLength -1 of imgdata  -- insert brushimageData into image imageData
>   end repeat
> end drawTheSymbol
> 
> —This method is called only once. The array is created with an element for each symbol that is to be plotted
>   --This puts image data into the quakeBrushForMag[#] array
> on setSymbolArray currentbrush
>   put the imageData of image currentbrush into currentbrushdata
>   put the alphaData of image currentbrush into brushalpha
>   put the width of image currentBrush into sBrushWidth
>   put the height of image currentBrush into sBrushHeight
> 
>   put  round(sBrushWidth/2) into sXDelta  -- to offset the brush so it is visible when using the finger
>   put  sBrushHeight into sYDelta -- same as above
>   put 0 into sXDelta
>   put 0 into sYDelta
>   put "" into sBrushDataArray
> 
>   --- build array of brush imagedata
>   repeat with y = 0 to sBrushHeight - 1
>      put byteToNum (byte ((y*sBrushWidth)+1) of brushalpha)
>      if byteToNum (byte ((y*sBrushWidth)+1) of brushalpha) > sAlphaCutOff  then
>         put true into tAlphaOn
>         put "" into tCollect
>         put ((y*sBrushWidth ) + 1) into tStartDot
>      else 
>         put false into tAlphaOn
>         put "" into tCollect
>      end if
>      repeat with x = 0 to sBrushWidth - 1
>         put ((x+(y*sBrushWidth))+1) into tDot
>         put (byteToNum(byte tDot of brushalpha) > sAlphaCutOff) into tNowAlphaOn
>         if tNowAlphaOn then 
>            put byte tDot * 4 - 3 to tDot * 4  of currentbrushdata after tCollect -- above threshold-> collect
>         end if
>         -- test if state of alpha threshold changed
>         if tAlphaOn <> tNowAlphaOn then
>            if tAlphaOn then 
>               -- state changed to alpha below threshold, write array
>               put tDot into tStopDot
>               put tCollect into sBrushDataArray[tStartDot]
>               put "" into tCollect -- clear tCollect since it is passed to the array
>            else
>               -- state changed to alpha above threshold
>               put tDot into tStartDot
>            end if
>            -- reset tAlphaOn to current state of alpha threshold since it changed
>            put tNowAlphaOn into tAlphaOn
>            -- end alpha state changed
>         end if
>      end repeat
>      if tCollect <> "" then put tCollect into sBrushDataArray[tStartDot]
>      put "" into tCollect
>   end repeat
>   --- end build array
> end setSymbolArray
> 
> 
> William A. Prothero
> http://es.earthednet.org/
> 
> _______________________________________________
> use-livecode mailing list
> use-livecode at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode





More information about the use-livecode mailing list