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 on-screen
    >> blitting to support a scrolling-chart 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
    >> on-screen, 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 on-screen, 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 floating-point 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 non-zero 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.
previous month september 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today