How to speed up drawing of scaled image? Audio playback chokes during window resize
I am writing an audio player for OSX. One view is a custom view that displays a waveform. The waveform is stored as a instance variable of type NSImage
with an NSBitmapImageRep
. The view also displays a progress indicator (a thick red line). Therefore, it is updated/redrawn every 30 milliseconds.
Since it takes a rather long time to recalculate the image, I do that in a background thread after every window resize and update the displayed image once the new image is ready. In the meantime, the original image is scaled to fit the view like this:
// The drawing开发者_如何学Go rectangle is slightly smaller than the view, defined by
// the two margins.
NSRect drawingRect;
drawingRect.origin = NSMakePoint(sideEdgeMarginWidth, topEdgeMarginHeight);
drawingRect.size = NSMakeSize([self bounds].size.width-2*sideEdgeMarginWidth,
[self bounds].size.height-2*topEdgeMarginHeight);
[waveform drawInRect:drawingRect
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1];
The view makes up the biggest part of the window. During live resize, audio starts choking. Selecting the "big" graphic card on my Macbook Pro makes it less bad, but not by much. CPU utilization is somewhere around 20-40% during live resizes.
Instruments suggests that rescaling/redrawing of the image is the problem. Once I stop resizing the window, CPU utilization goes down and audio stops glitching.I already tried to disable image interpolation to speed up the drawing like this:
[[NSGraphicsContext currentContext]
setImageInterpolation:NSImageInterpolationNone];
That helps, but audio still chokes during live resizes.
Do you have an idea how to improve this?
The main thing is to prevent the audio from choking.The graphics redraw should not affect audio playback. I have an audio app that does live redraw when resizing the window, as well as a background thread to render the waveform, and it has no problem playing back audio. The audio thread that the ioProc which reads the audio data is a real-time thread, and has a higher priority than most other threads.
If your graphics thread has a lock or calls something that blocks (including memory allocations or freeing) something in the audio thread, that could cause the audio to stutter. Multi-threading issues are complex, with issues such as thread-safety of data structures, locks, priority inversion, blocking, and many other things to deal with.
精彩评论