Closed Bug 297398 Opened 20 years ago Closed 3 years ago

cache backbuffer drawing surfaces for GTK

Categories

(Core :: Graphics, defect)

x86
Linux
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: vlad, Unassigned)

Details

Because it's no longer 2001, the circumstances that led to this caching being
disabled in bug 95952 largely do not apply, especially for Gtk.  If we have a
limited amount of video ram, then it would make sense to continue not caching,
but considering that even the lowliest of shared-memory graphics adapters these
days end up taking 16-32mb of RAM, that may not be that big of an issue.

Rerunning Owen's test code from that bug, the situation is pretty different
now.. Gecko is right now taking the approach that "many pixmaps" is as fast as
"one pixmap", which does not seem to be the case today:

1000 iters at 512x512
One pixmap:  243.276 (0.243276/iter)
Many pixmaps: 2118.388 (2.118388/iter)

1000 iters at 1100x1100
One pixmap:  1843.682 (1.843682/iter)
Many pixmaps: 12997.005 (12.997005/iter)

1000 iters at 1300x1300
One pixmap:  1846.009 (1.846009/iter)
Many pixmaps: 18594.491 (18.594491/iter)

1000 iters at 2500x2500
One pixmap:  1861.351 (1.861351/iter)
Many pixmaps: 71563.733 (71.563733/iter)

For reference, the original numbers given in bug 95952:

1000 iters at 512x512
One pixmap:  741.321 (0.741321/iter)
Many pixmaps: 718.056 (0.718056/iter)

1000 iters at 1100x1100
One pixmap:  2850.575 (2.850575/iter)
Many pixmaps: 3406.789 (3.406789/iter)

10 iters at 1300x1300  (note: only 10 iters here, 1000 iters in the current numbers)
One pixmap:  2085.611 (208.561100/iter)
Many pixmaps: 842.560 (84.256000/iter)

So, patch coming up, after I confirm that this is a real perf win in practice..
I would like to avoid keeping that large backbuffer around forver if we are
memory constrained, though, and implement some sort of intelligent scheme of
deciding when to shrink or free the buffer.  roc's suggestion of just shrinking
the buffer to the biggest size seen every N seconds seems reasonable.

There also seems to be pretty decent support for the DOUBlE-BUFFER extension
these days, but I have no idea how useful using it would be (or how it would
integrate with our gtk-only-not rendering)
Enabling caching, I'm seeing a *drastic* slowdown on some of the tinderbox DHTML
tests, most notably movingtext and scrolling, but also the layer moving
(layers1).  I'm having a pretty hard time coming up with an explanation why; the
only thing I can think of is that there's some state that's being set on the
GdkPixmap/X Pixmap that's more expensive to reset/change than it is to just
recreate.  Not caching and always allocating an aMaxSize pixmap doesn't affect
the numbers compared to allocating an aRequestSize pixmap, so the pixmap size
doesn't seem to affect things.  Doesn't seem to be clipping, nor the cached
XftDraw object on the drawing surface (I've tried explicitly destroying it every
time the backbuffer is released to no change).

Note that the goal of doing this wasn't to really speed up gtk rendering, though
I'd hoped that would be a side-effect; instead I'm trying to speed up canvas on
linux, which greatly benefits from being able to cache a Picture for the target
surface instead of having to recreate it each time.
>  greatly benefits from being able to cache a Picture for the target
> surface instead of having to recreate it each time.

Why's that?
(In reply to comment #2)
> >  greatly benefits from being able to cache a Picture for the target
> > surface instead of having to recreate it each time.
> 
> Why's that?

When doing any kind of animation, the canvas is constantly calling Invalidate()
on its frame (in my tree also only on the bounds that were actually modified,
via the extents methods).  So the Paint() method of the canvas is always being
passed a new Pixmap to render into (GdkPixmap, via the RenderingContext). 
Canvas creates a Picture for it so that it can blend correctly onto the
background via XRenderComposite.  Then both get destroyed and it starts over.

Since there's a fixed cost to allocating a new drawing surface/picture, quick
rendering ops (such as a single Composite) suffer the most by having to
constantly recreate the target surface.  I didn't really see any speedups in any
of the DHTML timings, so for normal repaints, the costs of the
allocation/deallocation are dwarfed by the actual rendering.

My rough timings of how long a single Paint() takes on average with my test at
file:///home/vladimir/proj/mozilla-cvs/tests/ctest1.html are:

~0.010 ms/frame - one pixmap one picture
~0.035 ms/frame - one pixmap many pictures
~0.040 ms/frame - many pixmaps many pictures

(I'm also seeing an odd "spike" in the animation every second or so in the last
case, and it becomes much worse if I create a cairo_xlib_surface for the target
drawable instead of creating a Picture and using XRender directly... not sure
what that's about yet either.)
I see. Perhaps we could have a new nsIWidget::Invalidate variant that requests
caching for the repaint? Other Invalidate calls would override it.

Another option would be to create views for canvas frames and have a new view
flag that says "I'm simple; if I'm the only view in the display list, please
cache more aggressively" (although that won't actually work since canvases are
transparent so there will always be other views rendered).
Timing-wise many pixmaps/many pictures isn't really that bad, from the mozilla
side; I'm only timing the amount of time to actually make the various calls, I'm
not doing an XSync there.  However, that jerk every 1s is happening somewhere,
and I'm afraid it may be in the X server (I guess I should check out and see if
other animation in a separate window also has the pause).
I'm wondering about case of cached backbuffer - do all tabs in same window used single/shared one in that case? And different windows?
Product: Core → Core Graveyard
I'm not sure whether this is still relevant.  Bouncing to Core:Graphics for triage.
Assignee: vladimir → nobody
Status: NEW → UNCONFIRMED
Component: GFX: Gtk → Graphics
Ever confirmed: false
Product: Core Graveyard → Core
QA Contact: gtk → thebes
Maybe this bug should be closed?
Status: UNCONFIRMED → RESOLVED
Closed: 3 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.