зеркало из https://github.com/mozilla/gecko-dev.git
160 строки
6.8 KiB
ReStructuredText
160 строки
6.8 KiB
ReStructuredText
Graphics Overview
|
||
=========================
|
||
|
||
Work in progress. Possibly incorrect or incomplete.
|
||
---------------------------------------------------
|
||
|
||
Jargon
|
||
------
|
||
|
||
There's a lot of jargon in the graphics stack. We try to maintain a list
|
||
of common words and acronyms `here <https://wiki.mozilla.org/Platform/GFX/Jargon>`__.
|
||
|
||
Overview
|
||
--------
|
||
|
||
The graphics systems is responsible for rendering (painting, drawing)
|
||
the frame tree (rendering tree) elements as created by the layout
|
||
system. Each leaf in the tree has content, either bounded by a rectangle
|
||
(or perhaps another shape, in the case of SVG.)
|
||
|
||
The simple approach for producing the result would thus involve
|
||
traversing the frame tree, in a correct order, drawing each frame into
|
||
the resulting buffer and displaying (printing non-withstanding) that
|
||
buffer when the traversal is done. It is worth spending some time on the
|
||
“correct order” note above. If there are no overlapping frames, this is
|
||
fairly simple - any order will do, as long as there is no background. If
|
||
there is background, we just have to worry about drawing that first.
|
||
Since we do not control the content, chances are the page is more
|
||
complicated. There are overlapping frames, likely with transparency, so
|
||
we need to make sure the elements are draw “back to front”, in layers,
|
||
so to speak. Layers are an important concept, and we will revisit them
|
||
shortly, as they are central to fixing a major issue with the above
|
||
simple approach.
|
||
|
||
While the above simple approach will work, the performance will suffer.
|
||
Each time anything changes in any of the frames, the complete process
|
||
needs to be repeated, everything needs to be redrawn. Further, there is
|
||
very little space to take advantage of the modern graphics (GPU)
|
||
hardware, or multi-core computers. If you recall from the previous
|
||
sections, the frame tree is only accessible from the UI thread, so while
|
||
we’re doing all this work, the UI is basically blocked.
|
||
|
||
(Retained) Layers
|
||
~~~~~~~~~~~~~~~~~
|
||
|
||
Layers framework was introduced to address the above performance issues,
|
||
by having a part of the design address each item. At the high level:
|
||
|
||
1. We create a layer tree. The leaf elements of the tree contain all
|
||
frames (possibly multiple frames per leaf).
|
||
2. We render each layer tree element and cache (retain) the result.
|
||
3. We composite (combine) all the leaf elements into the final result.
|
||
|
||
Let’s examine each of these steps, in reverse order.
|
||
|
||
Compositing
|
||
~~~~~~~~~~~
|
||
|
||
We use the term composite as it implies that the order is important. If
|
||
the elements being composited overlap, whether there is transparency
|
||
involved or not, the order in which they are combined will effect the
|
||
result. Compositing is where we can use some of the power of the modern
|
||
graphics hardware. It is optimal for doing this job. In the scenarios
|
||
where only the position of individual frames changes, without the
|
||
content inside them changing, we see why caching each layer would be
|
||
advantageous - we only need to repeat the final compositing step,
|
||
completely skipping the layer tree creation and the rendering of each
|
||
leaf, thus speeding up the process considerably.
|
||
|
||
Another benefit is equally apparent in the context of the stated
|
||
deficiencies of the simple approach. We can use the available graphics
|
||
hardware accelerated APIs to do the compositing step. Direct3D, OpenGL
|
||
can be used on different platforms and are well suited to accelerate
|
||
this step.
|
||
|
||
Finally, we can now envision performing the compositing step on a
|
||
separate thread, unblocking the UI thread for other work, and doing more
|
||
work in parallel. More on this below.
|
||
|
||
It is important to note that the number of operations in this step is
|
||
proportional to the number of layer tree (leaf) elements, so there is
|
||
additional work and complexity involved, when the layer tree is large.
|
||
|
||
Render and retain layer elements
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
As we saw, the compositing step benefits from caching the intermediate
|
||
result. This does result in the extra memory usage, so needs to be
|
||
considered during the layer tree creation. Beyond the caching, we can
|
||
accelerate the rendering of each element by (indirectly) using the
|
||
available platform APIs (e.g., Direct2D, CoreGraphics, even some of the
|
||
3D APIs like OpenGL or Direct3D) as available. This is actually done
|
||
through a platform independent API (see Moz2D) below, but is important
|
||
to realize it does get accelerated appropriately.
|
||
|
||
Creating the layer tree
|
||
~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
We need to create a layer tree (from the frames tree), which will give
|
||
us the correct result while striking the right balance between a layer
|
||
per frame element and a single layer for the complete frames tree. As
|
||
was mentioned above, there is an overhead in traversing the whole tree
|
||
and caching each of the elements, balanced by the performance
|
||
improvements. Some of the performance improvements are only noticed when
|
||
something changes (e.g., one element is moving, we only need to redo the
|
||
compositing step).
|
||
|
||
Refresh Driver
|
||
~~~~~~~~~~~~~~
|
||
|
||
Layers
|
||
~~~~~~
|
||
|
||
Rendering each layer
|
||
~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Tiling vs. Buffer Rotation vs. Full paint
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Compositing for the final result
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Graphics API
|
||
~~~~~~~~~~~~
|
||
|
||
Moz2D
|
||
~~~~~
|
||
|
||
- The Moz2D graphics API, part of the Azure project, is a
|
||
cross-platform interface onto the various graphics backends that
|
||
Gecko uses for rendering such as Direct2D (1.0 and 1.1), Skia, Cairo,
|
||
Quartz, and NV Path. Adding a new graphics platform to Gecko is
|
||
accomplished by adding a backend to Moz2D.
|
||
See `Moz2D documentation on wiki <https://wiki.mozilla.org/Platform/GFX/Moz2D>`__.
|
||
|
||
Compositing
|
||
~~~~~~~~~~~
|
||
|
||
Image Decoding
|
||
~~~~~~~~~~~~~~
|
||
|
||
Image Animation
|
||
~~~~~~~~~~~~~~~
|
||
|
||
`Historical Documents <http://www.youtube.com/watch?v=lLZQz26-kms>`__
|
||
---------------------------------------------------------------------
|
||
|
||
A number of posts and blogs that will give you more details or more
|
||
background, or reasoning that led to different solutions and approaches.
|
||
|
||
- 2010-01 `Layers: Cross Platform Acceleration <http://www.basschouten.com/blog1.php/layers-cross-platform-acceleration>`__
|
||
- 2010-04 `Layers <http://robert.ocallahan.org/2010/04/layers_01.html>`__
|
||
- 2010-07 `Retained Layers <http://robert.ocallahan.org/2010/07/retained-layers_16.html>`__
|
||
- 2011-04 `Introduction <https://blog.mozilla.org/joe/2011/04/26/introducing-the-azure-project/%20Moz2D>`__
|
||
- 2011-07 `Layers <http://chrislord.net/index.php/2011/07/25/shadow-layers-and-learning-by-failing/%20Shadow>`__
|
||
- 2011-09 `Graphics API Design <http://robert.ocallahan.org/2011/09/graphics-api-design.html>`__
|
||
- 2012-04 `Moz2D Canvas on OSX <http://muizelaar.blogspot.ca/2012/04/azure-canvas-on-os-x.html>`__
|
||
- 2012-05 `Mask Layers <http://featherweightmusings.blogspot.co.uk/2012/05/mask-layers_26.html>`__
|
||
- 2013-07 `Graphics related <http://www.basschouten.com/blog1.php>`__
|