Re: fast blitting with Quartz

Hi Greg.
I suppose should be no problem to letting the size of the view grow
to infinity  as long as I'm not drawing any more of it. I guess I
just have to get over the mental hurdle.
Thanks!
Kenny
On Sep 28, 2007, at 9:38 AM, Greg Titus wrote:
> Hey Kenny,
>
> (Long time no see!)
>
> If you are using NSScrollView and NSClipView for your scrolling,
> then this is all built in for you. (See setCopiesOnScroll: in
> NSClipView, which defaults to YES.) The clip view will do the
> blitting of your view content that was already on screen, and the
> rectangle passed into your view's drawRect: method will just
> consist of the 1% of new data. So all you need to do to be
> efficient is to just make sure that you pay attention to the
> rectangle argument passed in to your drawRect: and only draw that
> rectangle.
>
> Hope this helps,
>  Greg
>
> On Sep 28, 2007, at 9:28 AM, Kenny Leung wrote:
>
>> Hi All.
>>
>> Part of this is more curiosity than anything, but I hope you will
>> indulge me.
>>
>> The situation is this: I would like to have very fast onscreen
>> blitting to support a scrollingchart like drawing.
>>
>> In the old NeXTstep days of pswraps, there was this cool
>> PostScript operator called "composite" that would blit bits in the
>> current graphics context. So if you were doing a scrolling chart,
>> you would just have to composite the 99% of stuff you already had
>> onscreen, and draw the 1% of new data.
>>
>> Question 1: Does anybody know of the current Quartz equivalent for
>> doing this? I image that the NSScrollView/NSClipView combination
>> knows how to do this, but I have not been able to find the
>> function to do it.
>>
>> Question 2: If you can no longer do this, what would be an
>> efficient strategy to do this? Seems like the same could be
>> achieved using 2 NSImages  composite 99% from one to the other,
>> draw the 1%, composite onscreen, flip, rinse, lather, repeat. But
>> that seems high on both memory usage, and takes one more composite
>> than the optimal version.
>>
>> Thanks for any insight into this!
>>
>> Kenny
>>
>> P.S. If any of you remember my NeXTstep program KPerfmon, it used
>> this trick.
>

> I suppose should be no problem to letting the size of the view grow
> to infinity  as long as I'm not drawing any more of it. I guess I
> just have to get over the mental hurdle.
Note that there is a practical limit to the size of an NSView, beyond
which all sorts of funkiness occurs (visible as drawing artefacts) as
a consequence of CoreGraphics using floats, and thus having very much
finite precision. It depends on your particular code as to when
exactly you'll see problems, but I wouldn't let any view (inside a
scrollview) get more than 10,000,000 pixels in any dimension.
(I know that sounds huge, but it's pretty easy to naively hit if
you're not careful)
Wade 
On Sep 28, 2007, at 10:53 AM, Wade Tregaskis wrote:
> Note that there is a practical limit to the size of an NSView,
> beyond which all sorts of funkiness occurs (visible as drawing
> artefacts) as a consequence of CoreGraphics using floats, and thus
> having very much finite precision. It depends on your particular
> code as to when exactly you'll see problems, but I wouldn't let any
> view (inside a scrollview) get more than 10,000,000 pixels in any
> dimension.
It might make sense for a scrolling graph like KPerfMon to directly
use just an NSClipView, and then grow/slide your graph view inside
it, and when you hit some large view size (a million pixels or so)
just reset the graph view bounds to the clip view size. Then you'd
have a full redraw every so often, but it'd be pretty rare.
 Greg 
On Sep 28, 2007, at 12:53 PM, Wade Tregaskis wrote:
>> I suppose should be no problem to letting the size of the view grow
>> to infinity  as long as I'm not drawing any more of it. I guess I
>> just have to get over the mental hurdle.
>
> Note that there is a practical limit to the size of an NSView,
> beyond which all sorts of funkiness occurs (visible as drawing
> artefacts) as a consequence of CoreGraphics using floats, and thus
> having very much finite precision. It depends on your particular
> code as to when exactly you'll see problems, but I wouldn't let any
> view (inside a scrollview) get more than 10,000,000 pixels in any
> dimension.
>
> (I know that sounds huge, but it's pretty easy to naively hit if
> you're not careful)
Are you sure about the magnitude of your dimension there? I was under
the impression (potentially mistaken) that the problems started around
10,000 (ten thousand) instead of 10,000,000 (10 million).
Scott 
On Sep 28, 2007, at 11:27 AM, Scott Thompson wrote:
>
> On Sep 28, 2007, at 12:53 PM, Wade Tregaskis wrote:
>
>>> I suppose should be no problem to letting the size of the view
>>> grow to infinity  as long as I'm not drawing any more of it. I
>>> guess I just have to get over the mental hurdle.
>>
>> Note that there is a practical limit to the size of an NSView,
>> beyond which all sorts of funkiness occurs (visible as drawing
>> artefacts) as a consequence of CoreGraphics using floats, and thus
>> having very much finite precision. It depends on your particular
>> code as to when exactly you'll see problems, but I wouldn't let
>> any view (inside a scrollview) get more than 10,000,000 pixels in
>> any dimension.
>>
>> (I know that sounds huge, but it's pretty easy to naively hit if
>> you're not careful)
>
> Are you sure about the magnitude of your dimension there? I was
> under the impression (potentially mistaken) that the problems
> started around 10,000 (ten thousand) instead of 10,000,000 (10
> million).
Nope, it's somewhat less than 10 million but much much larger than 10
thousand. That's about the point where the "float" type no longer has
enough precision to represent individual pixels.
An IEEE binary float has 1 bit of sign, 8 bits of exponent, and 23
bits of fractional value. Which means you should be able to exactly
represent pixel values between +8,388,608 and 8,388,608. (2^23)
 Greg 
> Nope, it's somewhat less than 10 million but much much larger than
> 10 thousand. That's about the point where the "float" type no longer
> has enough precision to represent individual pixels.
>
> An IEEE binary float has 1 bit of sign, 8 bits of exponent, and 23
> bits of fractional value. Which means you should be able to exactly
> represent pixel values between +8,388,608 and 8,388,608. (2^23)
Okee dokee... I just had it wrong in my head.
Scott 
On Sep 28, 2007, at 11:35 AM, Greg Titus wrote:
>
> On Sep 28, 2007, at 11:27 AM, Scott Thompson wrote:
>
>>
>> On Sep 28, 2007, at 12:53 PM, Wade Tregaskis wrote:
>>
>>>> I suppose should be no problem to letting the size of the view
>>>> grow to infinity  as long as I'm not drawing any more of it. I
>>>> guess I just have to get over the mental hurdle.
>>>
>>> Note that there is a practical limit to the size of an NSView,
>>> beyond which all sorts of funkiness occurs (visible as drawing
>>> artefacts) as a consequence of CoreGraphics using floats, and
>>> thus having very much finite precision. It depends on your
>>> particular code as to when exactly you'll see problems, but I
>>> wouldn't let any view (inside a scrollview) get more than
>>> 10,000,000 pixels in any dimension.
>>>
>>> (I know that sounds huge, but it's pretty easy to naively hit if
>>> you're not careful)
>>
>> Are you sure about the magnitude of your dimension there? I was
>> under the impression (potentially mistaken) that the problems
>> started around 10,000 (ten thousand) instead of 10,000,000 (10
>> million).
>
> Nope, it's somewhat less than 10 million but much much larger than
> 10 thousand. That's about the point where the "float" type no
> longer has enough precision to represent individual pixels.
>
> An IEEE binary float has 1 bit of sign, 8 bits of exponent, and 23
> bits of fractional value. Which means you should be able to
> exactly represent pixel values between +8,388,608 and 8,388,608.
> (2^23)
Oops! My mistake. I forgot that the first bit of the fractional value
is assumed and is always 1. So you can actually accurately represent
individual pixels up to 2^24: 16.7 million.
 Greg 
> Are you sure about the magnitude of your dimension there? I was
> under the impression (potentially mistaken) that the problems
> started around 10,000 (ten thousand) instead of 10,000,000 (10
> million).
I had it my head that 100,000 was the magic number, for whatever
reason, but I went and actually tested before posting, and in my
particular test app, problems are hit at around 11.4 million pixels.
But as I said, it really depends on your code as well  most
significantly (in my experience) if you're using floats throughout
(e.g. for consistency with CoreGraphics), you're adding additional
rounding error versus using doubles for your own "internal"
calculations. Always* use the highest floatingpoint precision
available for intermediate calculations, even if you know you'll be
reducing precision somewhere down the line.
it also depends on when and how you calculate clipping, how you do
rounding, coalescing, etc etc etc. Very much implementation
dependent. But if you're careful in your own code, like I've had to
be in the aforementioned example case, you can get to 10 million
pixels without noticeable glitches.
Wade
* = Converting doubles to floats does have a nonzero cost, but
there's no point trying to guess whether this will matter; Shark your
code once you've written the conservative, working version, and go
from there.