Re: UIView underlying rects for drawRect
Re: UIView underlying rects for drawRect
- Subject: Re: UIView underlying rects for drawRect
- From: Roland King <email@hidden>
- Date: Sun, 06 Dec 2015 09:50:45 +0800
You thought CGContext had it, I thought CALayer had it, neither of them appear to have it!
AFAICT UIView is clearing the entire rectangle before drawing, so that idea doesn’t work either. That was a good way to confirm I was on the wrong road so thanks.
So I implemented the code to capture setNeedsDisplayInRect(), drawRect() etc and ensure only one contiguous rectangle goes to the setNeedsDisplayInRect at a time, if there’s another one it waits until drawRect() finishes and then queues that one up. The results were good until they weren’t and I’m really at a loss to explain some of the oddities I saw. It was never going to be stable enough for real use so that idea got tossed.
Current workaround it not to take things off the back, it’s history, I don’t really care, and the code moves the view along anyway so it quickly gets clipped and every few minutes the view is moved to a new chunk of data (it’s like a horizontal scroll view where only 1.5 screens wide of data is shown at a time which are incrementally drawn and then moved to a new chunk every few minutes with one single redraw).
I think a better plan for this whole thing is to use a CALayer with a persistent bitmap for the graph I’m drawing.
Currently I’m seeing a new point come in, working out what that is in view coordinates, calling setNeedsDisplayinRect() on that, then in drawRect I’m converting back to time coordinates, padding out each side so I definitely redraw the whole area cleared including the fuzzy edges of lines a point or two over on the display, then drawing. This is probably nowhere near as efficient as possible.
If I use a CALayer with a bitmap I can put a point on the bitmap asynchronously as soon as it comes in, one point, or one tiny line segment from the previous point, I can do my own clearing when they expire and then all I have to do is arrange the bitmap to be blitted onto the CALayer’s content on a regular basis for update and sort out some full redraw stuff on bounds change stuff.
What’s the right way to synchronise the update of the content property of a CALayer? I could do it every time I add a point, but that sounds a bit unnecessary. Is this where I use CADisplayLink? Is there a recommended format for the bitmap which eases the work the CPU/GPU has to do to transfer it to and from the layer? 8 bit with alpha is all I really need for the plot but if that’s going to trigger a huge conversion every time it’s run through CGBitmapContextCreateImage() and stuffed on the layer I’ll use something else.
Sigh .. I feel a few hours of pain coming up.
> On 5 Dec 2015, at 18:59, Mike Abdullah <email@hidden> wrote:
>
> I thought CGContext had API to tell you the rects being drawn, but can’t see that now, so I think I imagined it!
>
> I’d say your next port of call is to ascertain whether the system is smart enough to be only drawing the required area or not. There are debugging tools to show you the portions of the screen being updated — does that suggest the entire view is being redrawn, or just the ends?
>
> Mike.
>
>> On 5 Dec 2015, at 03:02, Roland King <email@hidden> wrote:
>>
>> NSView has a method getRectsBeingDrawn:count: which gives you the actual rects being drawn in a drawRect: call. Is there something equivalent for a UIView? Does UIView even do as I believe NSView does and only invalidate just the areas passed to setNeedsDisplayInRect:, meaning those are the only areas you actually need to redraw, or does it blow away the entire containing rectangle so you must repaint the entire area?
>>
>> I have a time-series view which only invalidates a tiny sliver of view which changed and only draws that in drawRect:. However when the series gets long enough it trims the left hand end, so two tiny slivers of view are invalidated, one at each end, drawRect: coalesces them into one rect the entire size of the window and the whole series redraws on every iteration. I spotted this when I left the simulator running for an hour and the fans suddenly started spinning up.
>>
>> I can work around it by overriding setNeedsDisplayInRect: and queuing up non-contiguous updates, releasing them only when drawRect has been called, but it would be nice not to have to. I suspect I’m SOL on this one.
>> _______________________________________________
>>
>> Cocoa-dev mailing list (email@hidden)
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden