$30 off During Our Annual Pro Sale. View Details »

Rendercontext & Double-Buffering

Rendercontext & Double-Buffering

Presentation about what had to be done to achieve double-buffered rendering in LibreOffice.

Jan Holesovsky

September 24, 2015
Tweet

More Decks by Jan Holesovsky

Other Decks in Programming

Transcript

  1. Rendercontext & Double-Buffering
    By Jan Holesovsky
    @JHolesovsky
    @CollaboraOffice www.CollaboraOffice.com

    View Slide

  2. 2 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    VCL changes...

    VCL (Visual Class Library)

    LibreOffice's graphics toolkit

    ~20 year history

    Undergoing a major upgrade to allow
    modern features like OpenGL support

    Attend the Michael's VCL talk

    The rendercontext is just part of the entire
    picture

    View Slide

  3. 3 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    When do we draw?

    Before the RenderContext rework
    started, Paint() methods were called just
    at any time

    When painting (that's OK of course)

    But also in event handlers (key press,
    mouse over effect, …)

    Triggered by timer

    Any other random time (eg. in Writer – the
    debug rectangle at the top left when layout
    finishes)

    View Slide

  4. 4 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    Ideal state

    Painting triggered in a controlled way

    Only the Paint() methods paint

    Only VCL triggers the paint
    – Consequently it can control the conditions of
    the paint – various setups / tear downs etc.

    Everything else only invalidates the area
    – And VCL decides when to paint, and what

    Painting de-coupled from vcl::Window

    vcl::Window becomes more abstract

    View Slide

  5. 5 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    RenderContext – what's that?

    RenderContext: class that implements the
    drawing

    At the moment, vcl::Window inherits from
    OutputDevice which allows all the painting at
    random points of time
    – That's what we want to avoid

    Instead, RenderContext is an
    implementation of the OutputDevice

    And is passed as a param of the Paint() method

    vcl::Window paints only in Paint()

    View Slide

  6. 6 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    Problems with direct paints

    Direct paints are problematic, because
    the render context is not available

    The code that previously called Paint()
    directly now has to use Invalidate()

    Invalidate()s are fast now – thanks to the
    Idle work

    Rework to use Invalidate() has to be
    done carefully though

    Danger of Invalidate() loops

    View Slide

  7. 7 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    Double-buffering

    Easy once RenderContext is used
    everywhere

    vcl/source/window/paint.cxx responsible
    for the rendering in the right order

    For double-buffering, additionally:
    – Buffer set up before calling paint
    (VirtualDevice)
    – Then call the Paint()s (as before)
    – Copy the buffer to the screen when done

    View Slide

  8. 8 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    Rendercontext rework

    Easy parts

    Adding the RenderContext parameter (via
    clang plugin)

    Hard parts

    Everything else :-)

    Implemented by Tomaž Vajngerl and
    Miklos Vajna

    Laszlo Nemeth and others nailed down
    many bugs – thank you!

    View Slide

  9. 9 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    Hard parts of the work

    Direct paints stateful in many cases

    Background set once in a constructor, instead of
    the Paint method

    OutputDevice cached

    Many places just try to remember the
    OutputDevice, and paint to it later

    Blinking cursor

    Currently it just inverts what is on the screen

    Size of the window vs. size of the
    rendercontext confusion

    View Slide

  10. 10 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    Current status

    Currently

    Most of the classes modified to paint only
    in the Paint() methods

    StartCenter completely double-buffered

    Writer mostly double-buffered
    – Except text cursor – needs inverting still – and
    some deep pieces

    Try yourself:

    export VCL_DOUBLEBUFFERING_FORCE_ENABLE=1

    View Slide

  11. DEMO

    View Slide

  12. 12 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    TODO

    Text cursor

    Inverting not convenient; should we have it
    as a flat rectangle? [as in Firefox etc.]

    Switch it on for StartCenter and Writer

    Cleanup

    Get rid of the code paths that are not
    needed for double-buffering

    Implement it for Calc, Impress and Base

    View Slide

  13. 13 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    And further...

    Switch all the drawing to tiled rendering

    Paint methods would not paint the entire
    screen, but only 256x256 'tiles'

    Currently used on Android & LibreOffice
    On-Line

    Adding Desktop would make it one code
    path again

    Would allow extremely fast OpenGL
    scrolling / panning / zoom

    View Slide

  14. 14 / 14
    LibreOffice Conference 2015, Aarhus | Jan Holesovsky
    Questions?
    Thanks for listening!

    View Slide