View Full Version : Methods for video acceleration
I've started to test out my final revision for my video driver, but I'm slightly disapointed at the time it takes to draw objects on screen.
I've already made sure that all calculations are done before drawing on the screen, however, some methods are still·somewhat slow. Its pretty much between you seeing movement sometimes and not seeing movement other times.
So, does anyone have expierence with this? What tricks can I use to make my methods draw faster, I believe I'm made the spin as fast as possible.
Heres a code example:
· startRow··· := limitRow(startRow)
· endRow····· := limitRow(endRow)
· startColumn := limitColumn(startColumn)········
· endColumn·· := limitColumn(endColumn)
· if(lines and (startRow < endRow) and (startColumn =< endColumn))
··· temp := (++endColumn - startColumn)
··· startRow := ((startRow * 32) + startColumn)
··· endRow·· := ((endRow * 32) + startColumn)
··· colors := computeColors(colors)
··· lines := limitLines(lines)
··· repeat lines
····· repeat index from startRow to (endRow - 32) step 32
······· wordmove(@lumaBuffer[index], @lumaBuffer[index + 32], temp)
······· longmove(@chromaBuffer[index], @chromaBuffer[index + 32], temp)
····· longfill(@chromaBuffer[endRow], colors, temp)··
As you can see all the drawing is done after calculating everything.
03-28-2009, 04:21 PM
Well, I also can't see anything that slows down this code as dramatically as you describe. However, I wonder about the implementation of wordmove(...) in the SPIN interpreter. If it is implemented the simple way - using assembly instructions rdword / wrword without loop unrolling you could speed it up by using longmove(...) with some additional code instead.
Still thinking about the problem... What should your code excerpt show on screen? And what does it show instead? How much is 'pretty much' measured in seconds? Approximately? I am wondering about the double loop
repeat index from startRow to (endRow - 32) step 32
What does it mean? Okay, I don't know the API of your video driver.
Oh, there might be another cause. Check the input data. There might be an overflow somewhere. As with the waitcnt(cycles) instead of waitcnt(cycles + cnt) error.
Airspace V - international hangar flying!
www.airspace-v.com/ggadgets (http://www.airspace-v.com/ggadgets) for tools & toys
03-29-2009, 04:03 AM
startRow := ((startRow * 32) + startColumn)
endRow := ((endRow * 32) + startColumn)
I guess that the spin multiplication does not check, if one of the factors is 2 to the power of x value. So, you should use the shift operator here. startRow<<5 ...
For each outer loop iteration you calculate endRow-32. Do it before and store the value in a new variable.
index-32 is calculated twice. Might be faster to do it once and use it twice (don't know that, but I'd give it a try)
repeat index from startRow to endR step 32
indexp := index+32
wordmove(@lumaBuffer[index], @lumaBuffer[indexp], temp)
longmove(@chromaBuffer[index], @chromaBuffer[indexp], temp)
longfill(@chromaBuffer[endRow], colors, temp)
What I don't know either is how the array stuff is implemented. I could imagine that it is more expensive to use the  instead of directly add your index to @chromaBuffer. Depending of the type of the array, you have to multiply the index with 2 for word and 4 for longs. But you can do this by changing the repeat of course.
Well, I wasn't asking so much about my code but about techniques in general. It takes about 4 frames to scroll 30 times and less than one frame to scroll less than 5 times.
The code I have above is acceptable, but I'm looking to see if anyone knows any tricks for making tile drivers smoother.
Things like not starting until the screen is refreshing, etc.
03-29-2009, 07:01 AM
Do you have a VBLANK flag? And is the display double buffered?
Those are the two biggies.
If you've got two buffers, you draw in one, while displaying the other one. Then flip during the VBLANK.
If you've only got one buffer, then you draw only during the VBLANK, so that transitory stuff isn't seen, or you generate the display dynamically every single frame.
When drawing only during the VBLANK, you've a limited amount of time. So you look at the system counter, before each draw operation to be sure there is time enough to make it atomic, so that there is no tearing or flicker.
For larger operations, you divide them across frames to keep those things to a minimum. So, lots of lines, for example, would just get drawn X lines per frame. If the operation just takes a lot of time, and it's too large to be atomic over the span of one VBLANK, you suck it up and draw it anyway. (flicker)
Another approach that would work from SPIN is to encode scrolling into the driver. Define a larger display buffer area, then to scroll, you just move the display base address. If you want line, by line scrolling, you also need a tile index, so that the two together can start the display at any point. Done that way, you can draw the transitory objects off screen, then scroll to display them once they are done.
Is that the kind of thing you were looking for?
Propeller Wiki: Share the coolness! (http://propeller.wikispaces.com/)
Chat in real time with other Propellerheads on IRC #propeller @ freenode.net (http://propeller.wikispaces.com/Join+us+on+IRC%21/)
Safety Tip: Life is as good as YOU think it is!
Yes,·vblank·worked, everything looks great now.
I was getting some nasty tearing with my box drawing methods, but now you can't see the drawing anymore. It looks great.