Scene graph (aka canvas) proposal



Hi,

Have posted some notes over the last couple years discussing a canvas
widget, based on working on HippoCanvas, and looking over GooCanvas.
Recently I've also been hacking on Clutter, and prototyping a
specialized compositing manager based on Clutter.

I think there's a practical, attainable, and useful path forward for
GTK+ that would give us a mainstream solution for the core problems
these canvas APIs are addressing, and rationalize the relationship
between them and GTK+.

Before the hackfest I thought I'd write up how I think this could be
done. It has implications for GDK, Cairo, etc. in addition to GTK+.

I did the writeup in slide form, these are text-heavy and intended to
be read not presented:

   http://docs.google.com/Presentation?id=dgn6j4pg_50dw7wh6vt

(note: you do not have to create a Google account to read these. Click
"open in new window" and it will just show the document to you.)

I'll also attach the presentation document exported as a text doc, but
it is not formatted well.

It looks like I can't be at the hackfest though I made a last-minute
effort to figure out how to be there. I am hoping some of the relevant
people will talk about this scene graph idea, though.

Appreciate any feedback or discussion on the list as well. If there's
some good discussion at the hackfest hopefully someone will take some
notes to post.

Havoc
GTK+ Graphics

The Future! Or some ideas anyway
Very rough draft notes

Where do people seek GTK+ alternatives?

Custom visual design of desktop applications (or parts of them)

WebKit

GtkDrawingArea

HippoCanvas

Devices with custom UI (phones, etc.)

Hacked-up GTK+ (theming, other patches)

Clutter

Compositing Manager

Compiz object system

Clutter

Stuff GTK+ makes hard

Pixel-precise control of visual design

Animations and transitions

3D effects: shader effects, rotate in/out, etc.

Nonrectangular or overlapping elements

Embedding in a nonstandard context (GTK+ insists all widgets are inside a GtkWindow, not some other canvas or composite overlay window, for example)

Goals

Allow custom visual design, whether for desktop apps or embedded devices; trust people to use tool responsibly

Support convenient retained-mode graphics, classic example is "Fifteen Game"

Support smooth animated transitions and effects, including fast transform of images and windows

3D effects including shaders and rotation

Support hardware acceleration for both 2D and 3D in the same layout

Cleanly make use of existing widgets (Entry, Button, TextView, TreeView, etc.) and don't create a need to reinvent these

Non-goals

API should support basic 3D effects and use of 3D APIs, but in a somewhat 2D-centric context; not designed for "virtual reality" type of UI

Model-view should be for special cases (GtkTextBuffer, GtkTreeModel) but generic model-view support is not needed

Not necessary to support "untrusted" API users (as with X server or Compiz objects); too hard/specialized, GtkWidget does not support this anyhow

Canvas APIs also add some conveniences and cleanups such as border/padding/alignment for all items, height-for-width, IF_FITS packing, etc.; table these features for later work and focus on more fundamental reasons people are using a canvas rather than GTK

Proposal

Create a new "scene graph" API. Make widgets one kind of scene graph object.

"Scene graph" seems like a less confusing way to describe this than "canvas" ?

For this presentation, let's call the scene graph objects "actors" for short, rather than "canvas item"

"Scene graph" and "actors" intended to emphasize that the new API will have graphics primitives, not interactive UI primitives - GTK+ will continue to provide widgets

What's in the scene graph API?

An Actor interface

paint() method which can use either 2D or 3D operations

allocate() method allocates a 2D area

Per-actor transform

Includes scale, rotate, translate

Includes z-axis transformation

Transform is post-allocate/layout but pre-paint

Event picking and bubbling

A Container interface defining the tree of Actor

Layout-and-paint operation: Request, Allocate, Apply Transforms, Paint to Buffer, Wait for VSync, Swap Buffer

Replacement for GdkWindow - clipping, scrolling, events

Fixed-position layout manager and interface to get min and natural size request

Effect on GDK

What stays

Toplevel GdkWindow and related operations

Event queue and dispatch of same

Display and Screen objects

What becomes obsolete, replaced by scene graph

Child GdkWindows

Double-buffer approach used by GTK+ may change

What remains obsolete

X11 leakage (colormaps, etc.)

non-Cairo drawing API

Effect on GtkWidget

Implements the Actor interface

GtkContainer becomes somewhat obsolete; walking hierarchy with GtkContainer "skips" all non-widget actors, as it does in HippoCanvas

GtkContainer modified to implement the scene graph's Container interface as well

child GdkWindow deprecated; back compat is complicated, but ideally there's some way for stock widgets to use scene graph equivalent instead (alternatively, some hack with composite redirection?)

redraw/repaint idles and double-buffering unified with scene graph

Widgets can be "composite" (be made up of child actors), or can just paint; maybe all widgets are containers as in Hippo?

Defining GTK+ vs. Scene Graph Layer

GTK+ contains what we'd normally consider a widget

Entry, TextView, TreeView, Button

Widgets are rectangular and themed by standard desktop theme

GTK+ defines input methods since those assume a lot about desktop environment

GTK+ defines printing, file selector, color picker, etc.

GTK+ defines toplevel window handling (GtkWindow)

GTK+ defines keyboard navigation (but scene graph has to do focus, so non-widget actors can be focused)

GTK+ does not contain the "graphics primitive" actors (image, line, rectangle, etc.), those are in scene graph

Themes are a property of GTK+ widgets only, not actor in general, so e.g. a Line or Rectangle actor has no theme

What gets passed to paint()?

Want to be able to draw with Cairo, but also GL

GL does not support a clean paint() method since there's no equivalent of the Cairo context with a transform stack; lots of GL state is flat-out global - glEnable(FOO) - and where it has a stack, it's a global stack with limited size (glPushMatrix())

Suggest that some possibly-thin new API defines a paint context that includes both Cairo context and GL state

GL could also use abstraction for regular vs. ES, and for presence or absence of various extensions

COGL does some abstraction of GL details but does not provide a context object, uses global state like plain GL

Need a single double buffer for entire toplevel window and all drawing APIs

Actors should deal only with their own coordinate system, not global ("window") or parent-actor-relative coordinates

Practicalities

Evolve the scene graph API as an add-on library, a la Clutter and HippoCanvas

The add-on should not depend on GTK since it will be a GTK dependency

The add-on should potentially depend on GDK, though... using GdkEvent would be nice... though both Clutter and HippoCanvas chose to avoid this maybe for good reason

There should be a "canvas widget" to embed a scene graph

Allow a scene graph to embed widgets. Maybe just add the Actor interface to GTK_TYPE_WIDGET from the outside library? Otherwise do a HippoCanvasWidget kind of approach (actor containing a widget).

Clutter - where it stands

Clutter is roughly along the same lines as scene graph API described here; having GL (or other hardware-oriented API) at core seems correct, with Cairo layered in

Needs request/allocation split apart; patch in bugzilla

Need to solve problem of what to pass to paint()

Has ClutterEntry, etc. - should just use GtkEntry

Currently supports "GDK-free" operation; GTK's scene graph should perhaps depend on GDK, but Clutter would not want to afaik

Does not support multiple scene graphs in a single process, inherits single global state from GL, but should be simple to fix this

No child GdkWindow replacement

No damage region, always repaints everything

Needs a pass to improve API naming, consistency

Path forward

Get some consensus on overall approach

Become familiar with Clutter; decide whether to start with it, if so lay out a roadmap for Clutter changes and seek approval from Clutter maintainers

Overall if using Clutter, large and incompatible Clutter changes would be expected. Be sure this is acceptable to all.

Begin or continue work on a Cairo backend that can draw to same double buffer as OpenGL and can employ hardware accel

Begin work on some kind of context object to pass to paint()

... do all the other work

Compositing Manager Footnote

Have been talking about apps (inside a toplevel) so far

How should effects and features spanning toplevels work?

xsnow type hacks

dashboard widget type things

window manager features (transitions, drop shadows)

X server model: object graph with untrusted clients

Web browser model: clients provide javascript

Would be an advantage to share scene graph API and widgets with normal apps; could have GtkEntry, etc. in CM

What about a stack of fullscreen scene graphs as children of composite overlay; each fullscreen overlay hosts a scene graph scripted by JavaScript from some client; when a client exits, destroy JS context and its scene graph

Proof-of-concept CM with Clutter seems to work nicely



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]