Re: RFC Speeding up graphics

From: msevior_at_physics.unimelb.edu.au
Date: Sat Dec 13 2003 - 02:11:27 EST

  • Next message: Johan Björk: "Re: RFC Speeding up graphics"

    > As a further follow-up, I think that it would probably
    > be good if *all* of our drawing operations happened
    > through this class. That is, all of the drawing
    > routines inside of GR_Graphics became protected, and
    > only called from either:
    >
    > 1) A subclass
    > 2) This "lock" class
    >
    > This would be beneficial so that no drawing operations
    > could ever happen outside of the "lock".
    >
    > Another, less-clean alternative could include a
    > "locked()" check inside of every drawing operation. I
    > think that the former option is infinitely preferable
    > to the latter one.
    >
    > If there are no objectsions, I will implement this
    > over the weekend.
    >

    I was thinking more about this and I can see that there will be a lot of
    benefits and while it is real work it shouldn't be too hard.

    I just want to make sure we're thinking about the same thing.

    1. We have the the ability to record XP graphics operations in some sort
    of FIFO buffer.

    2. If the beginGraphic() operation is called we increment a member
    variable in the graphics class to record the level of nesting. Call this
    m_iNest.

    3. If m_iNest > 0 when XP calls are made on the graphics class, the call
    and all it's parameters are recorded in the FIFO buffer.

    4. if endGraphic() is called m_iNest is decremented.
    If m_iNest == 0 after the decrement the FIFO buffer is executed and all
    the graphics operations are performed in the sequence they were recorded.

    This does give us the ability to glob many complex operations into one
    fast run. It will substantially reduce flicker.

    I can imagine placing beginGraphic()... endGraphic() calls around
    piecetable manipulations in the fv_View methods (and elsewhere) much like
    we do beginAtomicGlob() endAtomicGlob(). Then big complex operations are
    rolled into one set of manipulations.

    A potential problem is if we have several views of the one document open.
    The views that are not active will not get the globbing. I suspect we can
    live with this as it will just make other views flicker like they do now
    rather than have the flicker free operation of the globbed graphics
    operations.

    Another potential problem is if the graphics windows is scrolled in the
    middle of a set of globbed graphics operations.
    fv_View::_ensureInsertionPointIsOnScreen() could do this as could user
    manipulations of the scroll bar. I think we'll need to lock scrolling out
    while m_iNest > 0 and make sure this does not screw up other assumptions
    (like m_iYOffset, m_iXOffset in fv_View being different from the actual
    offset in the graphics classes.)

    Finally implementing the graphics FIFO will require something like a set
    of graphics changeRecords to remember what each requested operation was
    and what the parameters of the operation were. This will be a significant
    amount of work...

    OK, over to you Dom and Hub :-)

    Martin

    > Dom
    >
    > --- Dom Lachowicz <domlachowicz_at_yahoo.com> wrote:
    >> Hi Hub,
    >>
    >> I've suggested #1 before when talking with Phearbear
    >> on IRC. I think that he even started on some code
    >> too.
    >> IMO, we need something like:
    >>
    >> /* only invoked from a "helper class" described
    >> below
    >> */
    >> private void GR_Graphics::beginDraw();
    >> private void GR_Graphics::endDraw();
    >>
    >> /* implemented in platform-specific classes */
    >> virtual void GR_Graphics::_beginDraw() = 0;
    >> virtual void GR_Graphics::_endDraw() = 0;
    >>
    >> These should have an integer count so that they can
    >> be
    >> invoked "recursively", but the actual drawing won't
    >> happen until the last "endDraw()" which will commit
    >> the operation.
    >>
    >> Further, I think that we need a "GR_GraphicsLocker"
    >> class. Its purpose is to manage calling beginDraw()
    >> and endDraw() for us. For example:
    >>
    >> void FV_View::drawFoo ()
    >> {
    >> // beginDraw() implicitly called
    >> GR_GraphicsLocker lock (getGraphics());
    >>
    >> if (!needsToBeDrawn)
    >> return; // endDraw() implicitly called
    >> else {
    >> getGraphics()->drawLine ();
    >> ...
    >> }
    >>
    >> // endDraw() implicitly called
    >> }
    >>
    >> So yes, please do option #1. It will help us all out
    >> a
    >> lot.
    >>
    >> Best regards,
    >> Dom
    >>
    >> --- Hubert Figuiere <hfiguiere_at_teaser.fr> wrote:
    >> >
    >> > Hi,
    >> >
    >> > While porting AbiWord to MacOS X, I found out a
    >> few
    >> > performance
    >> > problems, mostly due to MacOS X Core Graphics
    >> layer,
    >> > but also to some
    >> > design issues in the GR_Graphics class and its
    >> use,
    >> > in the Abi
    >> > framework.
    >> >
    >> > The main problem is that for each graphics
    >> operation
    >> > we need:
    >> > -to setup a graphic context (costly)
    >> > -setup the graphic properties (line size, etc) and
    >> > clipping
    >> > -do our stuff
    >> > -reset everything
    >> > All of this, at least on MacOS X, but I'm sure
    >> that
    >> > it does too on
    >> > other platforms, it is *costly*. I actually found
    >> > myself some huge
    >> > bottleneck elsewhere to reduce the overhead, but
    >> > there is still too
    >> > much IMHO.
    >> >
    >> > I thought about a solution and found actually 2
    >> that
    >> > would work for
    >> > any platform, with both pros and cons.
    >> >
    >> > Solution 1, probably the preferred one:
    >> > -Surround any drawing with startDraw()/endDraw()
    >> > calls (everywhere in
    >> > XP code)
    >> > -implement these 2 methods to do the setup pre and
    >> > post draw.
    >> > (GR_Graphics subclass)
    >> >
    >> > Pro:
    >> > -simple and efficient
    >> > -minimum platform work (initial can be empty
    >> > implementations)
    >> > Cons:
    >> > -need to track any drawing
    >> >
    >> > Solution 2, the smarter but more complex:
    >> > -Implement all the drawing operation in XP land
    >> > (GR_Graphics) to stack
    >> > them up in a graphic pipeline
    >> > -Implement in GR_Graphics::sync() culling of the
    >> > whole graphic pipeline
    >> > -Make sure we call sync() after each drawing (not
    >> > each operations)
    >> >
    >> > Pro:
    >> > -much smarter and elegant
    >> > -can be really efficient
    >> > Cons
    >> > -large platform rework effort
    >> > -complex and probably harder to debug
    >> >
    >> > What are your opinions ? If no one object, I'm
    >> going
    >> > to spend time on
    >> > solution 1 as I really need to speed up graphics.
    >> >
    >> >
    >> > Hub
    >> > --
    >> > AbiWord maintainer - Lille, France
    >> > http://www.figuiere.net/hub/
    >> > GPG fingerprint: 6C44 DB3E 0BF3 EAF5 B433 239A
    >> 5FEE
    >> > 05E6 A56E 15A3
    >>
    >>
    >> __________________________________
    >> Do you Yahoo!?
    >> Protect your identity with Yahoo! Mail AddressGuard
    >> http://antispam.yahoo.com/whatsnewfree
    >
    >
    > __________________________________
    > Do you Yahoo!?
    > Protect your identity with Yahoo! Mail AddressGuard
    > http://antispam.yahoo.com/whatsnewfree
    >



    This archive was generated by hypermail 2.1.4 : Sat Dec 13 2003 - 02:10:46 EST