aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClay Murphy <claym@google.com>2014-09-02 17:30:57 -0700
committerClay Murphy <claym@google.com>2014-10-09 14:09:52 -0700
commite3ae3969a1c6fbdeddb70f0fc27c957a88ad42c8 (patch)
treec762e0be83f7f664138919d97192319cadd506ea
parente6fbcf143930c61e18fbebe0b007aa61e9160b08 (diff)
downloadsource.android.com-e3ae3969a1c6fbdeddb70f0fc27c957a88ad42c8.tar.gz
Docs: Revising Graphics page and adding related images.
Bug: 13785467 Change-Id: I52878af8823a322e4311c3d1b6e3279d824e39d5
-rw-r--r--src/devices/devices_toc.cs3
-rw-r--r--src/devices/graphics.jd548
-rw-r--r--src/devices/graphics/architecture.jd2
-rw-r--r--src/devices/graphics/images/bufferqueue.pngbin0 -> 28570 bytes
-rw-r--r--src/devices/graphics/images/dispsync.pngbin0 -> 45122 bytes
-rw-r--r--src/devices/graphics/images/graphics_pipeline.pngbin0 -> 67046 bytes
-rw-r--r--src/devices/graphics/images/graphics_surface.pngbin0 -> 73152 bytes
-rw-r--r--src/devices/graphics/implement.jd605
-rw-r--r--src/devices/images/graphics_surface.pngbin62127 -> 0 bytes
-rw-r--r--src/index.jd17
10 files changed, 816 insertions, 359 deletions
diff --git a/src/devices/devices_toc.cs b/src/devices/devices_toc.cs
index 1eb43aad..85dcae46 100644
--- a/src/devices/devices_toc.cs
+++ b/src/devices/devices_toc.cs
@@ -88,7 +88,8 @@
</a>
</div>
<ul>
- <li><a href="<?cs var:toroot ?>devices/graphics/architecture.html">System-Level Architecture</a></li>
+ <li><a href="<?cs var:toroot ?>devices/graphics/architecture.html">Architecture</a></li>
+ <li><a href="<?cs var:toroot ?>devices/graphics/implement.html">Implementation</a></li>
</ul>
</li>
<li class="nav-section">
diff --git a/src/devices/graphics.jd b/src/devices/graphics.jd
index 45ebfae5..c8f11e84 100644
--- a/src/devices/graphics.jd
+++ b/src/devices/graphics.jd
@@ -2,7 +2,7 @@ page.title=Graphics
@jd:body
<!--
- Copyright 2013 The Android Open Source Project
+ Copyright 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ page.title=Graphics
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
@@ -24,354 +25,203 @@ page.title=Graphics
</div>
</div>
-<p>
- The Android framework has a variety of graphics rendering APIs for 2D and 3D that interact with
- your HAL implementations and graphics drivers, so it is important to have a good understanding of
- how they work at a higher level. There are two general ways that app developers can draw things
- to the screen: with Canvas or OpenGL.
-</p>
-<p>
- <a href="http://developer.android.com/reference/android/graphics/Canvas.html">android.graphics.Canvas</a>
- is a 2D graphics API and is the most widely used graphics API by
- developers. Canvas operations draw all the stock <a href="http://developer.android.com/reference/android/view/View.html">android.view.View</a>s
- and custom <a href="http://developer.android.com/reference/android/view/View.html">android.view.View</a>s in Android. Prior to Android 3.0, Canvas always
- used the non-hardware accelerated Skia 2D drawing library to draw.
-</p>
-<p>
- Introduced in Android 3.0, hardware acceleration for Canvas APIs uses a new drawing library
- called OpenGLRenderer that translates Canvas operations to OpenGL operations so that they can
- execute on the GPU. Developers had to opt-in to this feature previously, but beginning in Android
- 4.0, hardware-accelerated Canvas is enabled by default. Consequently, a hardware GPU that
- supports OpenGL ES 2.0 is mandatory for Android 4.0 devices.
-</p>
-<p>
- Additionally, the <a href="https://developer.android.com/guide/topics/graphics/hardware-accel.html">Hardware Acceleration guide</a>
- explains how the hardware-accelerated drawing path works and identifies the differences in behavior from the software drawing path.
-</p>
-<p>
- The other main way that developers render graphics is by using OpenGL ES 1.x or 2.0 to directly
- render to a surface. Android provides OpenGL ES interfaces in the
- <a href="http://developer.android.com/reference/android/opengl/package-summary.html">android.opengl</a> package
- that a developer can use to call into your GL implementation with the SDK or with native APIs
- provided in the Android NDK.
-
- <p class="note"><strong>Note:</strong>A third option, Renderscript, was introduced in Android 3.0 to
- serve as a platform-agnostic graphics rendering API (it used OpenGL ES 2.0 under the hood), but
- will be deprecated starting in the Android 4.1 release.
-</p>
-<h2 id="render">
- How Android Renders Graphics
-</h2>
-<p>
- No matter what rendering API developers use, everything is rendered onto a buffer of pixel data
- called a "surface." Every window that is created on the Android platform is backed by a surface.
- All of the visible surfaces that are rendered to are composited onto the display
- by the SurfaceFlinger, Android's system service that manages composition of surfaces.
- Of course, there are more components that are involved in graphics rendering, and the
- main ones are described below:
-</p>
-
-<dl>
- <dt>
- <strong>Image Stream Producers</strong>
- </dt>
- <dd>Image stream producers can be things such as an OpenGL ES game, video buffers from the media server,
- a Canvas 2D application, or basically anything that produces graphic buffers for consumption.
- </dd>
-
- <dt>
- <strong>Image Stream Consumers</strong>
- </dt>
- <dd>The most common consumer of image streams is SurfaceFlinger, the system service that consumes
- the currently visible surfaces and composites them onto the display using
- information provided by the Window Manager. SurfaceFlinger is the only service that can
- modify the content of the display. SurfaceFlinger uses OpenGL and the
- hardware composer to compose a group of surfaces. Other OpenGL ES apps can consume image
- streams as well, such as the camera app consuming a camera preview image stream.
- </dd>
- <dt>
- <strong>SurfaceTexture</strong>
- </dt>
- <dd>SurfaceTexture contains the logic that ties image stream producers and image stream consumers together
- and is made of three parts: <code>SurfaceTextureClient</code>, <code>ISurfaceTexture</code>, and
- <code>SurfaceTexture</code> (in this case, <code>SurfaceTexture</code> is the actual C++ class and not
- the name of the overall component). These three parts facilitate the producer (<code>SurfaceTextureClient</code>),
- binder (<code>ISurfaceTexture</code>), and consumer (<code>SurfaceTexture</code>)
- components of SurfaceTexture in processes such as requesting memory from Gralloc,
- sharing memory across process boundaries, synchronizing access to buffers, and pairing the appropriate consumer with the producer.
- SurfaceTexture can operate in both asynchronous (producer never blocks waiting for consumer and drops frames) and
- synchronous (producer waits for consumer to process textures) modes. Some examples of image
- producers are the camera preview produced by the camera HAL or an OpenGL ES game. Some examples
- of image consumers are SurfaceFlinger or another app that wants to display an OpenGL ES stream
- such as the camera app displaying the camera viewfinder.
- </dd>
-
- <dt>
- <strong>Window Manager</strong>
- </dt>
- <dd>
- The Android system service that controls window lifecycles, input and focus events, screen
- orientation, transitions, animations, position, transforms, z-order, and many other aspects of
- a window (a container for views). A window is always backed by a surface. The Window Manager
- sends all of the window metadata to SurfaceFlinger, so SurfaceFlinger can use that data
- to figure out how to composite surfaces on the display.
- </dd>
-
- <dt>
- <strong>Hardware Composer</strong>
- </dt>
- <dd>
- The hardware abstraction for the display subsystem. SurfaceFlinger can delegate certain
- composition work to the hardware composer to offload work from the OpenGL and the GPU. This makes
- compositing faster than having SurfaceFlinger do all the work. Starting with Jellybean MR1,
- new versions of the hardware composer have been introduced. See the <code>hardware/libhardware/include/hardware/gralloc.h</code> <a href="#hwc">Hardware composer</a> section
- for more information.
- </dd>
-
- <dt>
- <strong>Gralloc</strong>
- </dt>
- <dd>Allocates memory for graphics buffers. See the If you
- are using version 1.1 or later of the <a href="#hwc">hardware composer</a>, this HAL is no longer needed.</dd>
-
-
-</dl>
-<p>
- The following diagram shows how these components work together:
-</p><img src="images/graphics_surface.png">
-<p class="img-caption">
- <strong>Figure 1.</strong> How surfaces are rendered
-</p>
-
-</p>
-<h2 id="provide">
- What You Need to Provide
-</h2>
-<p>
- The following list and sections describe what you need to provide to support graphics in your product:
-</p>
-<ul>
- <li>OpenGL ES 1.x Driver
- </li>
- <li>OpenGL ES 2.0 Driver
- </li>
- <li>EGL Driver
- </li>
- <li>Gralloc HAL implementation
- </li>
- <li>Hardware Composer HAL implementation
- </li>
- <li>Framebuffer HAL implementation
- </li>
-</ul>
-<h3 id="gl">
- OpenGL and EGL drivers
-</h3>
-<p>
- You must provide drivers for OpenGL ES 1.x, OpenGL ES 2.0, and EGL. Some key things to keep in
- mind are:
-</p>
-<ul>
- <li>The GL driver needs to be robust and conformant to OpenGL ES standards.
- </li>
- <li>Do not limit the number of GL contexts. Because Android allows apps in the background and
- tries to keep GL contexts alive, you should not limit the number of contexts in your driver. It
- is not uncommon to have 20-30 active GL contexts at once, so you should also be careful with the
- amount of memory allocated for each context.
- </li>
- <li>Support the YV12 image format and any other YUV image formats that come from other
- components in the system such as media codecs or the camera.
- </li>
- <li>Support the mandatory extensions: <code>GL_OES_texture_external</code>,
- <code>EGL_ANDROID_image_native_buffer</code>, and <code>EGL_ANDROID_recordable</code>. We highly
- recommend supporting <code>EGL_ANDROID_blob_cache</code> and <code>EGL_KHR_fence_sync</code> as
- well.</li>
-</ul>
-
-<p>
- Note that the OpenGL API exposed to app developers is different from the OpenGL interface that
- you are implementing. Apps do not have access to the GL driver layer, and must go through the
- interface provided by the APIs.
-</p>
-<h4>
- Pre-rotation
-</h4>
-<p>Many times, hardware overlays do not support rotation, so the solution is to pre-transform the buffer before
- it reaches SurfaceFlinger. A query hint in ANativeWindow was added (<code>NATIVE_WINDOW_TRANSFORM_HINT</code>)
- that represents the most likely transform to be be applied to the buffer by SurfaceFlinger.
-
- Your GL driver can use this hint to pre-transform the buffer before it reaches SurfaceFlinger, so when the buffer
- actually reaches SurfaceFlinger, it is correctly transformed. See the ANativeWindow
- interface defined in <code>system/core/include/system/window.h</code> for more details. The following
- is some pseudo-code that implements this in the hardware composer:
-</p>
-
-<pre>
-ANativeWindow->query(ANativeWindow, NATIVE_WINDOW_DEFAULT_WIDTH, &w);
-ANativeWindow->query(ANativeWindow, NATIVE_WINDOW_DEFAULT_HEIGHT, &h);
-ANativeWindow->query(ANativeWindow, NATIVE_WINDOW_TRANSFORM_HINT, &hintTransform);
-if (hintTransform & HAL_TRANSFORM_ROT_90)
-swap(w, h);
-
-native_window_set_buffers_dimensions(anw, w, h);
-ANativeWindow->dequeueBuffer(...);
-
-// here GL driver renders content transformed by " hintTransform "
-
-int inverseTransform;
-inverseTransform = hintTransform;
-if (hintTransform & HAL_TRANSFORM_ROT_90)
- inverseTransform ^= HAL_TRANSFORM_ROT_180;
-
-native_window_set_buffers_transform(anw, inverseTransform);
-
-ANativeWindow->queueBuffer(...);
-</pre>
-
-<h3 id="gralloc">
- Gralloc HAL
-</h3>
-<p>
- The graphics memory allocator is needed to allocate memory that is requested by
- SurfaceTextureClient in image producers. You can find a stub implementation of the HAL at
- <code>hardware/libhardware/modules/gralloc.h</code>
-</p>
-<h4>
- Protected buffers
-</h4>
-<p>
- There is a gralloc usage flag <code>GRALLOC_USAGE_PROTECTED</code> that allows
- the graphics buffer to be displayed only through a hardware protected path.
-</p>
-<h3 id="hwc">
- Hardware Composer HAL
-</h3>
-<p>
- The hardware composer is used by SurfaceFlinger to composite surfaces to the screen. The hardware
- composer abstracts things like overlays and 2D blitters and helps offload some things that would
- normally be done with OpenGL.
-</p>
-
-<p>Jellybean MR1 introduces a new version of the HAL. We recommend that you start using version 1.1 of the hardware
- composer HAL as it will provide support for the newest features (explicit synchronization, external displays, etc).
- Keep in mind that in addition to 1.1 version, there is also a 1.0 version of the HAL that we used for internal
- compatibility reasons and a 1.2 draft mode of the hardware composer HAL. We recommend that you implement
- version 1.1 until 1.2 is out of draft mode.
-</p>
-
- <p>Because the physical display hardware behind the hardware composer
- abstraction layer can vary from device to device, it is difficult to define recommended features, but
- here is some guidance:</p>
-
-<ul>
- <li>The hardware composer should support at least 4 overlays (status bar, system bar, application,
- and live wallpaper) for phones and 3 overlays for tablets (no status bar).</li>
- <li>Layers can be bigger than the screen, so the hardware composer should be able to handle layers
- that are larger than the display (For example, a wallpaper).</li>
- <li>Pre-multiplied per-pixel alpha blending and per-plane alpha blending should be supported at the same time.</li>
- <li>The hardware composer should be able to consume the same buffers that the GPU, camera, video decoder, and Skia buffers are producing,
- so supporting some of the following properties is helpful:
- <ul>
- <li>RGBA packing order</li>
- <li>YUV formats</li>
- <li>Tiling, swizzling, and stride properties</li>
- </ul>
- </li>
- <li>A hardware path for protected video playback must be present if you want to support protected content.</li>
-</ul>
-<p>
- The general recommendation when implementing your hardware composer is to implement a no-op
- hardware composer first. Once you have the structure done, implement a simple algorithm to
- delegate composition to the hardware composer. For example, just delegate the first three or four
- surfaces to the overlay hardware of the hardware composer. After that focus on common use cases,
- such as:
-</p>
-<ul>
- <li>Full-screen games in portrait and landscape mode
- </li>
- <li>Full-screen video with closed captioning and playback control
- </li>
- <li>The home screen (compositing the status bar, system bar, application window, and live
- wallpapers)
- </li>
- <li>Protected video playback
- </li>
- <li>Multiple display support
- </li>
-</ul>
-<p>
- After implementing the common use cases, you can focus on optimizations such as intelligently
- selecting the surfaces to send to the overlay hardware that maximizes the load taken off of the
- GPU. Another optimization is to detect whether the screen is updating. If not, delegate composition
- to OpenGL instead of the hardware composer to save power. When the screen updates again, contin`ue to
- offload composition to the hardware composer.
-</p>
-
-<p>
- You can find the HAL for the hardware composer in the
- <code>hardware/libhardware/include/hardware/hwcomposer.h</code> and <code>hardware/libhardware/include/hardware/hwcomposer_defs.h</code>
- files. A stub implementation is available in the <code>hardware/libhardware/modules/hwcomposer</code> directory.
-</p>
-
-<h4>
- VSYNC
-</h4>
-<p>
- VSYNC synchronizes certain events to the refresh cycle of the display. Applications always
- start drawing on a VSYNC boundary and SurfaceFlinger always composites on a VSYNC boundary.
- This eliminates stutters and improves visual performance of graphics.
- The hardware composer has a function pointer</p>
-
- <pre>int (waitForVsync*) (int64_t *timestamp)</pre>
-
- <p>that points to a function you must implement for VSYNC. This function blocks until
- a VSYNC happens and returns the timestamp of the actual VSYNC.
- A client can receive a VSYNC timestamps once, at specified intervals, or continously (interval of 1).
- You must implement VSYNC to have no more than a 1ms lag at the maximum (1/2ms or less is recommended), and
- the timestamps returned must be extremely accurate.
-</p>
-
-<h4>Explicit synchronization</h4>
-<p>Explicit synchronization is required in Jellybean MR1 and later and provides a mechanism
-for Gralloc buffers to be acquired and released in a synchronized way.
-Explicit synchronization allows producers and consumers of graphics buffers to signal when
-they are done with a buffer. This allows the Android system to asynchronously queue buffers
-to be read or written with the certainty that another consumer or producer does not currently need them.</p>
-<p>
-This communication is facilitated with the use of synchronization fences, which are now required when requesting
-a buffer for consuming or producing. The
- synchronization framework consists of three main parts:</p>
-<ul>
- <li><code>sync_timeline</code>: a monotonically increasing timeline that should be implemented
- for each driver instance. This basically is a counter of jobs submitted to the kernel for a particular piece of hardware.</li>
- <li><code>sync_pt</code>: a single value or point on a <code>sync_timeline</code>. A point
- has three states: active, signaled, and error. Points start in the active state and transition
- to the signaled or error states. For instance, when a buffer is no longer needed by an image
- consumer, this <code>sync_point</code> is signaled so that image producers
- know that it is okay to write into the buffer again.</li>
- <li><code>sync_fence</code>: a collection of <code>sync_pt</code>s that often have different
- <code>sync_timeline</code> parents (such as for the display controller and GPU). This allows
- multiple consumers or producers to signal that
- they are using a buffer and to allow this information to be communicated with one function parameter.
- Fences are backed by a file descriptor and can be passed from kernel-space to user-space.
- For instance, a fence can contain two <code>sync_point</code>s that signify when two separate
- image consumers are done reading a buffer. When the fence is signaled,
- the image producers now know that both consumers are done consuming.</li>
- </ul>
-
-<p>To implement explicit synchronization, you need to do provide the following:
-
-<ul>
- <li>A kernel-space driver that implements a synchronization timeline for a particular piece of hardware. Drivers that
- need to be fence-aware are generally anything that accesses or communicates with the hardware composer.
- See the <code>system/core/include/sync/sync.h</code> file for more implementation details. The
- <code>system/core/libsync</code> directory includes a library to communicate with the kernel-space </li>
- <li>A hardware composer HAL module (version 1.1 or later) that supports the new synchronization functionality. You will need to provide
- the appropriate synchronization fences as parameters to the <code>set()</code> and <code>prepare()</code> functions in the HAL. As a last resort,
-you can pass in -1 for the file descriptor parameters if you cannot support explicit synchronization for some reason. This
-is not recommended, however.</li>
- <li>Two GL specific extensions related to fences, <code>EGL_ANDROID_native_fence_sync</code> and <code>EGL_ANDROID_wait_sync</code>,
- along with incorporating fence support into your graphics drivers.</ul>
+<p>The Android framework offers a variety of graphics rendering APIs for 2D and
+3D that interact with manufacturer implementations of graphics drivers, so it
+is important to have a good understanding of how those APIs work at a higher
+level. This page introduces the graphics hardware abstraction layer (HAL) upon
+which those drivers are built.</p>
+
+<p>Application developers draw images to the screen in two ways: with Canvas or
+OpenGL. See <a
+href="{@docRoot}devices/graphics/architecture.html">System-level graphics
+architecture</a> for a detailed description of Android graphics
+components.</p>
+
+<p><a
+href="http://developer.android.com/reference/android/graphics/Canvas.html">android.graphics.Canvas</a>
+is a 2D graphics API and is the most popular graphics API among developers.
+Canvas operations draw all the stock and custom <a
+href="http://developer.android.com/reference/android/view/View.html">android.view.View</a>s
+in Android. In Android, hardware acceleration for Canvas APIs is accomplished
+with a drawing library called OpenGLRenderer that translates Canvas operations
+to OpenGL operations so they can execute on the GPU.</p>
+
+<p>Beginning in Android 4.0, hardware-accelerated Canvas is enabled by default.
+Consequently, a hardware GPU that supports OpenGL ES 2.0 is mandatory for
+Android 4.0 and later devices. See the <a
+href="https://developer.android.com/guide/topics/graphics/hardware-accel.html">Hardware
+Acceleration guide</a> for an explanation of how the hardware-accelerated
+drawing path works and the differences in its behavior from that of the
+software drawing path.</p>
+
+<p>In addition to Canvas, the other main way that developers render graphics is
+by using OpenGL ES to directly render to a surface. Android provides OpenGL ES
+interfaces in the <a
+href="http://developer.android.com/reference/android/opengl/package-summary.html">android.opengl</a>
+package that developers can use to call into their GL implementations with the
+SDK or with native APIs provided in the <a
+href="https://developer.android.com/tools/sdk/ndk/index.html">Android
+NDK</a>.</p>
+
+<h2 id=android_graphics_components>Android graphics components</h2>
+
+<p>No matter what rendering API developers use, everything is rendered onto a
+"surface." The surface represents the producer side of a buffer queue that is
+often consumed by SurfaceFlinger. Every window that is created on the Android
+platform is backed by a surface. All of the visible surfaces rendered are
+composited onto the display by SurfaceFlinger.</p>
+
+<p>The following diagram shows how the key components work together:</p>
+
+<img src="graphics/images/graphics_surface.png" alt="image-rendering components">
+
+<p class="img-caption"><strong>Figure 1.</strong> How surfaces are rendered</p>
+
+<p>The main components are described below:</p>
+
+<h3 id=image_stream_producers>Image Stream Producers</h3>
+
+<p>An image stream producer can be anything that produces graphic buffers for
+consumption. Examples include OpenGL ES, Canvas 2D, and mediaserver video
+decoders.</p>
+
+<h3 id=image_stream_consumers>Image Stream Consumers</h3>
+
+<p>The most common consumer of image streams is SurfaceFlinger, the system
+service that consumes the currently visible surfaces and composites them onto
+the display using information provided by the Window Manager. SurfaceFlinger is
+the only service that can modify the content of the display. SurfaceFlinger
+uses OpenGL and the Hardware Composer to compose a group of surfaces.</p>
+
+<p>Other OpenGL ES apps can consume image streams as well, such as the camera
+app consuming a camera preview image stream. Non-GL applications can be
+consumers too, for example the ImageReader class.</p>
+
+<h3 id=window_manager>Window Manager</h3>
+
+<p>The Android system service that controls a window, which is a container for
+views. A window is always backed by a surface. This service oversees
+lifecycles, input and focus events, screen orientation, transitions,
+animations, position, transforms, z-order, and many other aspects of a window.
+The Window Manager sends all of the window metadata to SurfaceFlinger so
+SurfaceFlinger can use that data to composite surfaces on the display.</p>
+
+<h3 id=hardware_composer>Hardware Composer</h3>
+
+<p>The hardware abstraction for the display subsystem. SurfaceFlinger can
+delegate certain composition work to the Hardware Composer to offload work from
+OpenGL and the GPU. SurfaceFlinger acts as just another OpenGL ES client. So
+when SurfaceFlinger is actively compositing one buffer or two into a third, for
+instance, it is using OpenGL ES. This makes compositing lower power than having
+the GPU conduct all computation.</p>
+
+<p>The Hardware Composer HAL conducts the other half of the work. This HAL is
+the central point for all Android graphics rendering. Hardware Composer must
+support events, one of which is VSYNC. Another is hotplug for plug-and-play
+HDMI support.</p>
+
+<p>See the <a href="{@docRoot}devices/graphics.html#hardware_composer_hal">Hardware Composer
+HAL</a> section for more information.</p>
+
+<h3 id=gralloc>Gralloc</h3>
+
+<p>The graphics memory allocator is needed to allocate memory that is requested
+by image producers. See the <a
+href="{@docRoot}devices/graphics.html#gralloc">Gralloc HAL</a> section for more
+information.</p>
+
+<h2 id=data_flow>Data flow</h2>
+
+<p>See the following diagram for a depiction of the Android graphics
+pipeline:</p>
+
+<img src="graphics/images/graphics_pipeline.png" alt="graphics data flow">
+
+<p class="img-caption"><strong>Figure 2.</strong> How graphic data flow through
+Android</p>
+
+<p>The objects on the left are renderers producing graphics buffers, such as
+the home screen, status bar, and system UI. SurfaceFlinger is the compositor
+and Hardware Composer is the composer.</p>
+
+<h3 id=bufferqueue>BufferQueue</h3>
+
+<p>BufferQueues provide the glue between the Android graphics components. These
+are a pair of queues that mediate the constant cycle of buffers from the
+producer to the consumer. Once the producers hand off their buffers,
+SurfaceFlinger is responsible for compositing everything onto the display.</p>
+
+<p>See the following diagram for the BufferQueue communication process.</p>
+
+<img src="graphics/images/bufferqueue.png" alt="BufferQueue communication process">
+
+<p class="img-caption"><strong>Figure 3.</strong> BufferQueue communication
+process</p>
+
+<p>BufferQueue contains the logic that ties image stream producers and image
+stream consumers together. Some examples of image producers are the camera
+previews produced by the camera HAL or OpenGL ES games. Some examples of image
+consumers are SurfaceFlinger or another app that displays an OpenGL ES stream,
+such as the camera app displaying the camera viewfinder.</p>
+<p>BufferQueue is a data structure that combines a buffer pool with a queue and
+uses Binder IPC to pass buffers between processes. The producer interface, or
+what you pass to somebody who wants to generate graphic buffers, is
+IGraphicBufferProducer (part of <a
+href="http://developer.android.com/reference/android/graphics/SurfaceTexture.html">SurfaceTexture</a>).
+BufferQueue is often used to render to a Surface and consume with a GL
+Consumer, among other tasks.
+BufferQueue can operate in three different modes:</p>
+<p><em>Synchronous-like mode</em> - BufferQueue by default operates in a
+synchronous-like mode, in which every buffer that comes in from the producer
+goes out at the consumer. No buffer is ever discarded in this mode. And if the
+producer is too fast and creates buffers faster than they are being drained, it
+will block and wait for free buffers.</p>
+
+<p><em>Non-blocking mode</em> - BufferQueue can also operate in a non-blocking
+mode where it generates an error rather than waiting for a buffer in those
+cases. No buffer is ever discarded in this mode either. This is useful for
+avoiding potential deadlocks in application software that may not understand
+the complex dependencies of the graphics framework.</p>
+
+<p><em>Discard mode</em> - Finally, BufferQueue may be configured to discard
+old buffers rather than generate errors or wait. For instance, if conducting GL
+rendering to a texture view and drawing as quickly as possible, buffers must be
+dropped.</p>
+
+<p>To conduct most of this work, SurfaceFlinger acts as just another OpenGL ES
+client. So when SurfaceFlinger is actively compositing one buffer or two into a
+third, for instance, it is using OpenGL ES.</p>
+
+<p>The Hardware Composer HAL conducts the other half of the work. This HAL acts
+as the central point for all Android graphics rendering.</p>
+
+<h3 id=synchronization_framework>Synchronization framework</h3>
+
+<p>Since Android graphics offer no explicit parallelism, vendors have long
+implemented their own implicit synchronization within their own drivers. This
+is no longer required with the Android graphics synchronization framework. See
+the <a href="#explicit_synchronization">Explicit synchronization</a> section
+for implementation instructions.</p>
+
+<p>The synchronization framework explicitly describes dependencies between
+different asynchronous operations in the system. The framework provides a
+simple API that lets components signal when buffers are released. It also
+allows synchronization primitives to be passed between drivers from the kernel
+to userspace and between userspace processes themselves.</p>
+
+<p>For example, an application may queue up work to be carried out in the GPU.
+The GPU then starts drawing that image. Although the image hasn’t been drawn
+into memory yet, the buffer pointer can still be passed to the window
+compositor along with a fence that indicates when the GPU work will be
+finished. The window compositor may then start processing ahead of time and
+hand off the work to the display controller. In this manner, the CPU work can
+be done ahead of time. Once the GPU finishes, the display controller can
+immediately display the image.</p>
+
+<p>The synchronization framework also allows implementers to leverage
+synchronization resources in their own hardware components. Finally, the
+framework provides visibility into the graphics pipeline to aid in
+debugging.</p>
diff --git a/src/devices/graphics/architecture.jd b/src/devices/graphics/architecture.jd
index 6842dd75..75623cc6 100644
--- a/src/devices/graphics/architecture.jd
+++ b/src/devices/graphics/architecture.jd
@@ -1,4 +1,4 @@
-page.title=Architecture
+page.title=Graphics architecture
@jd:body
<!--
diff --git a/src/devices/graphics/images/bufferqueue.png b/src/devices/graphics/images/bufferqueue.png
new file mode 100644
index 00000000..1951f462
--- /dev/null
+++ b/src/devices/graphics/images/bufferqueue.png
Binary files differ
diff --git a/src/devices/graphics/images/dispsync.png b/src/devices/graphics/images/dispsync.png
new file mode 100644
index 00000000..d97765cd
--- /dev/null
+++ b/src/devices/graphics/images/dispsync.png
Binary files differ
diff --git a/src/devices/graphics/images/graphics_pipeline.png b/src/devices/graphics/images/graphics_pipeline.png
new file mode 100644
index 00000000..983a5177
--- /dev/null
+++ b/src/devices/graphics/images/graphics_pipeline.png
Binary files differ
diff --git a/src/devices/graphics/images/graphics_surface.png b/src/devices/graphics/images/graphics_surface.png
new file mode 100644
index 00000000..6cd86ef3
--- /dev/null
+++ b/src/devices/graphics/images/graphics_surface.png
Binary files differ
diff --git a/src/devices/graphics/implement.jd b/src/devices/graphics/implement.jd
new file mode 100644
index 00000000..59aca16d
--- /dev/null
+++ b/src/devices/graphics/implement.jd
@@ -0,0 +1,605 @@
+page.title=Implementing graphics
+@jd:body
+
+<!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol id="auto-toc">
+ </ol>
+ </div>
+</div>
+
+
+<p>Follow the instructions here to implement the Android graphics HAL.</p>
+
+<h2 id=requirements>Requirements</h2>
+
+<p>The following list and sections describe what you need to provide to support
+graphics in your product:</p>
+
+<ul> <li> OpenGL ES 1.x Driver <li> OpenGL ES 2.0 Driver <li> OpenGL ES 3.0
+Driver (optional) <li> EGL Driver <li> Gralloc HAL implementation <li> Hardware
+Composer HAL implementation <li> Framebuffer HAL implementation </ul>
+
+<h2 id=implementation>Implementation</h2>
+
+<h3 id=opengl_and_egl_drivers>OpenGL and EGL drivers</h3>
+
+<p>You must provide drivers for OpenGL ES 1.x, OpenGL ES 2.0, and EGL. Here are
+some key considerations:</p>
+
+<ul> <li> The GL driver needs to be robust and conformant to OpenGL ES
+standards. <li> Do not limit the number of GL contexts. Because Android allows
+apps in the background and tries to keep GL contexts alive, you should not
+limit the number of contexts in your driver. <li> It is not uncommon to have
+20-30 active GL contexts at once, so you should also be careful with the amount
+of memory allocated for each context. <li> Support the YV12 image format and
+any other YUV image formats that come from other components in the system such
+as media codecs or the camera. <li> Support the mandatory extensions:
+<code>GL_OES_texture_external</code>,
+<code>EGL_ANDROID_image_native_buffer</code>, and
+<code>EGL_ANDROID_recordable</code>. The
+<code>EGL_ANDROID_framebuffer_target</code> extension is required for Hardware
+Composer 1.1 and higher, as well. <li> We highly recommend also supporting
+<code>EGL_ANDROID_blob_cache</code>, <code>EGL_KHR_fence_sync</code>,
+<code>EGL_KHR_wait_sync</code>, and <code>EGL_ANDROID_native_fence_sync</code>.
+</ul>
+
+<p>Note the OpenGL API exposed to app developers is different from the OpenGL
+interface that you are implementing. Apps do not have access to the GL driver
+layer and must go through the interface provided by the APIs.</p>
+
+<h3 id=pre-rotation>Pre-rotation</h3>
+
+<p>Many hardware overlays do not support rotation, and even if they do it costs
+processing power. So the solution is to pre-transform the buffer before it
+reaches SurfaceFlinger. A query hint in <code>ANativeWindow</code> was added
+(<code>NATIVE_WINDOW_TRANSFORM_HINT</code>) that represents the most likely
+transform to be applied to the buffer by SurfaceFlinger. Your GL driver can use
+this hint to pre-transform the buffer before it reaches SurfaceFlinger so when
+the buffer arrives, it is correctly transformed.</p>
+
+<p>For example, you may receive a hint to rotate 90 degrees. You must generate
+a matrix and apply it to the buffer to prevent it from running off the end of
+the page. To save power, this should be done in pre-rotation. See the
+<code>ANativeWindow</code> interface defined in
+<code>system/core/include/system/window.h</code> for more details.</p>
+
+<h3 id=gralloc_hal>Gralloc HAL</h3>
+
+<p>The graphics memory allocator is needed to allocate memory that is requested
+by image producers. You can find the interface definition of the HAL at:
+<code>hardware/libhardware/modules/gralloc.h</code></p>
+
+<h3 id=protected_buffers>Protected buffers</h3>
+
+<p>The gralloc usage flag <code>GRALLOC_USAGE_PROTECTED</code> allows the
+graphics buffer to be displayed only through a hardware-protected path. These
+overlay planes are the only way to display DRM content. DRM-protected buffers
+cannot be accessed by SurfaceFlinger or the OpenGL ES driver.</p>
+
+<p>DRM-protected video can be presented only on an overlay plane. Video players
+that support protected content must be implemented with SurfaceView. Software
+running on unprotected hardware cannot read or write the buffer.
+Hardware-protected paths must appear on the Hardware Composer overlay. For
+instance, protected videos will disappear from the display if Hardware Composer
+switches to OpenGL ES composition.</p>
+
+<p>See the <a href="{@docRoot}devices/drm.html">DRM</a> page for a description
+of protected content.</p>
+
+<h3 id=hardware_composer_hal>Hardware Composer HAL</h3>
+
+<p>The Hardware Composer HAL is used by SurfaceFlinger to composite surfaces to
+the screen. The Hardware Composer abstracts objects like overlays and 2D
+blitters and helps offload some work that would normally be done with
+OpenGL.</p>
+
+<p>We recommend you start using version 1.3 of the Hardware Composer HAL as it
+will provide support for the newest features (explicit synchronization,
+external displays, and more). Because the physical display hardware behind the
+Hardware Composer abstraction layer can vary from device to device, it is
+difficult to define recommended features. But here is some guidance:</p>
+
+<ul> <li> The Hardware Composer should support at least four overlays (status
+bar, system bar, application, and wallpaper/background). <li> Layers can be
+bigger than the screen, so the Hardware Composer should be able to handle
+layers that are larger than the display (for example, a wallpaper). <li>
+Pre-multiplied per-pixel alpha blending and per-plane alpha blending should be
+supported at the same time. <li> The Hardware Composer should be able to
+consume the same buffers that the GPU, camera, video decoder, and Skia buffers
+are producing, so supporting some of the following properties is helpful: <ul>
+<li> RGBA packing order <li> YUV formats <li> Tiling, swizzling, and stride
+properties </ul> <li> A hardware path for protected video playback must be
+present if you want to support protected content. </ul>
+
+<p>The general recommendation when implementing your Hardware Composer is to
+implement a non-operational Hardware Composer first. Once you have the
+structure done, implement a simple algorithm to delegate composition to the
+Hardware Composer. For example, just delegate the first three or four surfaces
+to the overlay hardware of the Hardware Composer.</p>
+
+<p>Focus on optimization, such as intelligently selecting the surfaces to send
+to the overlay hardware that maximizes the load taken off of the GPU. Another
+optimization is to detect whether the screen is updating. If not, delegate
+composition to OpenGL instead of the Hardware Composer to save power. When the
+screen updates again, continue to offload composition to the Hardware
+Composer.</p>
+
+<p>Devices must report the display mode (or resolution). Android uses the first
+mode reported by the device. To support televisions, have the TV device report
+the mode selected for it by the manufacturer to Hardware Composer. See
+hwcomposer.h for more details.</p>
+
+<p>Prepare for common use cases, such as:</p>
+
+<ul> <li> Full-screen games in portrait and landscape mode <li> Full-screen
+video with closed captioning and playback control <li> The home screen
+(compositing the status bar, system bar, application window, and live
+wallpapers) <li> Protected video playback <li> Multiple display support </ul>
+
+<p>These use cases should address regular, predictable uses rather than edge
+cases that are rarely encountered. Otherwise, any optimization will have little
+benefit. Implementations must balance two competing goals: animation smoothness
+and interaction latency.</p>
+
+<p>Further, to make best use of Android graphics, you must develop a robust
+clocking strategy. Performance matters little if clocks have been turned down
+to make every operation slow. You need a clocking strategy that puts the clocks
+at high speed when needed, such as to make animations seamless, and then slows
+the clocks whenever the increased speed is no longer needed.</p>
+
+<p>Use the <code>adb shell dumpsys SurfaceFlinger</code> command to see
+precisely what SurfaceFlinger is doing. See the <a
+href="{@docRoot}devices/graphics/architecture.html#hwcomposer">Hardware
+Composer</a> section of the Architecture page for example output and a
+description of relevant fields.</p>
+
+<p>You can find the HAL for the Hardware Composer and additional documentation
+in: <code>hardware/libhardware/include/hardware/hwcomposer.h
+hardware/libhardware/include/hardware/hwcomposer_defs.h</code></p>
+
+<p>A stub implementation is available in the
+<code>hardware/libhardware/modules/hwcomposer</code> directory.</p>
+
+<h3 id=vsync>VSYNC</h3>
+
+<p>VSYNC synchronizes certain events to the refresh cycle of the display.
+Applications always start drawing on a VSYNC boundary, and SurfaceFlinger
+always composites on a VSYNC boundary. This eliminates stutters and improves
+visual performance of graphics. The Hardware Composer has a function
+pointer:</p>
+
+<pre class=prettyprint> int (waitForVsync*) (int64_t *timestamp) </pre>
+
+
+<p>This points to a function you must implement for VSYNC. This function blocks
+until a VSYNC occurs and returns the timestamp of the actual VSYNC. A message
+must be sent every time VSYNC occurs. A client can receive a VSYNC timestamp
+once, at specified intervals, or continuously (interval of 1). You must
+implement VSYNC to have no more than a 1ms lag at the maximum (0.5ms or less is
+recommended), and the timestamps returned must be extremely accurate.</p>
+
+<h4 id=explicit_synchronization>Explicit synchronization</h4>
+
+<p>Explicit synchronization is required and provides a mechanism for Gralloc
+buffers to be acquired and released in a synchronized way. Explicit
+synchronization allows producers and consumers of graphics buffers to signal
+when they are done with a buffer. This allows the Android system to
+asynchronously queue buffers to be read or written with the certainty that
+another consumer or producer does not currently need them. See the <a
+href="#synchronization_framework">Synchronization framework</a> section for an overview of
+this mechanism.</p>
+
+<p>The benefits of explicit synchronization include less behavior variation
+between devices, better debugging support, and improved testing metrics. For
+instance, the sync framework output readily identifies problem areas and root
+causes. And centralized SurfaceFlinger presentation timestamps show when events
+occur in the normal flow of the system.</p>
+
+<p>This communication is facilitated by the use of synchronization fences,
+which are now required when requesting a buffer for consuming or producing. The
+synchronization framework consists of three main building blocks:
+sync_timeline, sync_pt, and sync_fence.</p>
+
+<h5 id=sync_timeline>sync_timeline</h5>
+
+<p>A sync_timeline is a monotonically increasing timeline that should be
+implemented for each driver instance, such as a GL context, display controller,
+or 2D blitter. This is essentially a counter of jobs submitted to the kernel
+for a particular piece of hardware. It provides guarantees about the order of
+operations and allows hardware-specific implementations.</p>
+
+<p>Please note, the sync_timeline is offered as a CPU-only reference
+implementation called sw_sync (which stands for software sync). If possible,
+use sw_sync instead of a sync_timeline to save resources and avoid complexity.
+If you’re not employing a hardware resource, sw_sync should be sufficient.</p>
+
+<p>If you must implement a sync_timeline, use the sw_sync driver as a starting
+point. Follow these guidelines:</p>
+
+<ul> <li> Provide useful names for all drivers, timelines, and fences. This
+simplifies debugging. <li> Implement timeline_value str and pt_value_str
+operators in your timelines as they make debugging output much more readable.
+<li> If you want your userspace libraries (such as the GL library) to have
+access to the private data of your timelines, implement the fill driver_data
+operator. This lets you get information about the immutable sync_fence and
+sync_pts so you might build command lines based upon them. </ul>
+
+<p>When implementing a sync_timeline, <strong>don’t</strong>:</p>
+
+<ul> <li> Base it on any real view of time, such as when a wall clock or other
+piece of work might finish. It is better to create an abstract timeline that
+you can control. <li> Allow userspace to explicitly create or signal a fence.
+This can result in one piece of the user pipeline creating a denial-of-service
+attack that halts all functionality. This is because the userspace cannot make
+promises on behalf of the kernel. <li> Access sync_timeline, sync_pt, or
+sync_fence elements explicitly, as the API should provide all required
+functions. </ul>
+
+<h5 id=sync_pt>sync_pt</h5>
+
+<p>A sync_pt is a single value or point on a sync_timeline. A point has three
+states: active, signaled, and error. Points start in the active state and
+transition to the signaled or error states. For instance, when a buffer is no
+longer needed by an image consumer, this sync_point is signaled so that image
+producers know it is okay to write into the buffer again.</p>
+
+<h5 id=sync_fence>sync_fence</h5>
+
+<p>A sync_fence is a collection of sync_pts that often have different
+sync_timeline parents (such as for the display controller and GPU). These are
+the main primitives over which drivers and userspace communicate their
+dependencies. A fence is a promise from the kernel that it gives upon accepting
+work that has been queued and assures completion in a finite amount of
+time.</p>
+
+<p>This allows multiple consumers or producers to signal they are using a
+buffer and to allow this information to be communicated with one function
+parameter. Fences are backed by a file descriptor and can be passed from
+kernel-space to user-space. For instance, a fence can contain two sync_points
+that signify when two separate image consumers are done reading a buffer. When
+the fence is signaled, the image producers know both consumers are done
+consuming.
+
+Fences, like sync_pts, start active and then change state based upon the state
+of their points. If all sync_pts become signaled, the sync_fence becomes
+signaled. If one sync_pt falls into an error state, the entire sync_fence has
+an error state.
+
+Membership in the sync_fence is immutable once the fence is created. And since
+a sync_pt can be in only one fence, it is included as a copy. Even if two
+points have the same value, there will be two copies of the sync_pt in the
+fence.
+
+To get more than one point in a fence, a merge operation is conducted. In the
+merge, the points from two distinct fences are added to a third fence. If one
+of those points was signaled in the originating fence, and the other was not,
+the third fence will also not be in a signaled state.</p>
+
+<p>To implement explicit synchronization, you need to provide the
+following:</p>
+
+<ul> <li> A kernel-space driver that implements a synchronization timeline for
+a particular piece of hardware. Drivers that need to be fence-aware are
+generally anything that accesses or communicates with the Hardware Composer.
+Here are the key files (found in the android-3.4 kernel branch): <ul> <li> Core
+implementation: <ul> <li> <code>kernel/common/include/linux/sync.h</code> <li>
+<code>kernel/common/drivers/base/sync.c</code> </ul> <li> sw_sync: <ul> <li>
+<code>kernel/common/include/linux/sw_sync.h</code> <li>
+<code>kernel/common/drivers/base/sw_sync.c</code> </ul> <li> Documentation:
+<li> <code>kernel/common//Documentation/sync.txt</code> Finally, the
+<code>platform/system/core/libsync</code> directory includes a library to
+communicate with the kernel-space. </ul> <li> A Hardware Composer HAL module
+(version 1.3 or later) that supports the new synchronization functionality. You
+will need to provide the appropriate synchronization fences as parameters to
+the set() and prepare() functions in the HAL. <li> Two GL-specific extensions
+related to fences, <code>EGL_ANDROID_native_fence_sync</code> and
+<code>EGL_ANDROID_wait_sync</code>, along with incorporating fence support into
+your graphics drivers. </ul>
+
+<p>For example, to use the API supporting the synchronization function, you
+might develop a display driver that has a display buffer function. Before the
+synchronization framework existed, this function would receive dma-bufs, put
+those buffers on the display, and block while the buffer is visible, like
+so:</p>
+
+<pre class=prettyprint>
+/*
+ * assumes buf is ready to be displayed. returns when buffer is no longer on
+ * screen.
+ */
+void display_buffer(struct dma_buf *buf); </pre>
+
+
+<p>With the synchronization framework, the API call is slightly more complex.
+While putting a buffer on display, you associate it with a fence that says when
+the buffer will be ready. So you queue up the work, which you will initiate
+once the fence clears.</p>
+
+<p>In this manner, you are not blocking anything. You immediately return your
+own fence, which is a guarantee of when the buffer will be off of the display.
+As you queue up buffers, the kernel will list dependencies. With the
+synchronization framework:</p>
+
+<pre class=prettyprint>
+/*
+ * will display buf when fence is signaled. returns immediately with a fence
+ * that will signal when buf is no longer displayed.
+ */
+struct sync_fence* display_buffer(struct dma_buf *buf, struct sync_fence
+*fence); </pre>
+
+
+<h4 id=sync_integration>Sync integration</h4>
+
+<h5 id=integration_conventions>Integration conventions</h5>
+
+<p>This section explains how to integrate the low-level sync framework with
+different parts of the Android framework and the drivers that need to
+communicate with one another.</p>
+
+<p>The Android HAL interfaces for graphics follow consistent conventions so
+when file descriptors are passed across a HAL interface, ownership of the file
+descriptor is always transferred. This means:</p>
+
+<ul> <li> if you receive a fence file descriptor from the sync framework, you
+must close it. <li> if you return a fence file descriptor to the sync
+framework, the framework will close it. <li> if you want to continue using the
+fence file descriptor, you must duplicate the descriptor. </ul>
+
+<p>Every time a fence is passed through BufferQueue - such as for a window that
+passes a fence to BufferQueue saying when its new contents will be ready - the
+fence object is renamed. Since kernel fence support allows fences to have
+strings for names, the sync framework uses the window name and buffer index
+that is being queued to name the fence, for example:
+<code>SurfaceView:0</code></p>
+
+<p>This is helpful in debugging to identify the source of a deadlock. Those
+names appear in the output of <code>/d/sync</code> and bug reports when
+taken.</p>
+
+<h5 id=anativewindow_integration>ANativeWindow integration</h5>
+
+<p>ANativeWindow is fence aware. <code>dequeueBuffer</code>,
+<code>queueBuffer</code>, and <code>cancelBuffer</code> have fence
+parameters.</p>
+
+<h5 id=opengl_es_integration>OpenGL ES integration</h5>
+
+<p>OpenGL ES sync integration relies upon these two EGL extensions:</p>
+
+<ul> <li> <code>EGL_ANDROID_native_fence_sync</code> - provides a way to either
+wrap or create native Android fence file descriptors in EGLSyncKHR objects.
+<li> <code>EGL_ANDROID_wait_sync</code> - allows GPU-side stalls rather than in
+CPU, making the GPU wait for an EGLSyncKHR. This is essentially the same as the
+<code>EGL_KHR_wait_sync</code> extension. See the
+<code>EGL_KHR_wait_sync</code> specification for details. </ul>
+
+<p>These extensions can be used independently and are controlled by a compile
+flag in libgui. To use them, first implement the
+<code>EGL_ANDROID_native_fence_sync</code> extension along with the associated
+kernel support. Next add a ANativeWindow support for fences to your driver and
+then turn on support in libgui to make use of the
+<code>EGL_ANDROID_native_fence_sync</code> extension.</p>
+
+<p>Then, as a second pass, enable the <code>EGL_ANDROID_wait_sync</code>
+extension in your driver and turn it on separately. The
+<code>EGL_ANDROID_native_fence_sync</code> extension consists of a distinct
+native fence EGLSync object type so extensions that apply to existing EGLSync
+object types don’t necessarily apply to <code>EGL_ANDROID_native_fence</code>
+objects to avoid unwanted interactions.</p>
+
+<p>The EGL_ANDROID_native_fence_sync extension employs a corresponding native
+fence file descriptor attribute that can be set only at creation time and
+cannot be directly queried onward from an existing sync object. This attribute
+can be set to one of two modes:</p>
+
+<ul> <li> A valid fence file descriptor - wraps an existing native Android
+fence file descriptor in an EGLSyncKHR object. <li> -1 - creates a native
+Android fence file descriptor from an EGLSyncKHR object. </ul>
+
+<p>The DupNativeFenceFD function call is used to extract the EGLSyncKHR object
+from the native Android fence file descriptor. This has the same result as
+querying the attribute that was set but adheres to the convention that the
+recipient closes the fence (hence the duplicate operation). Finally, destroying
+the EGLSync object should close the internal fence attribute.</p>
+
+<h5 id=hardware_composer_integration>Hardware Composer integration</h5>
+
+<p>Hardware Composer handles three types of sync fences:</p>
+
+<ul> <li> <em>Acquire fence</em> - one per layer, this is set before calling
+HWC::set. It signals when Hardware Composer may read the buffer. <li>
+<em>Release fence</em> - one per layer, this is filled in by the driver in
+HWC::set. It signals when Hardware Composer is done reading the buffer so the
+framework can start using that buffer again for that particular layer. <li>
+<em>Retire fence</em> - one per the entire frame, this is filled in by the
+driver each time HWC::set is called. This covers all of the layers for the set
+operation. It signals to the framework when all of the effects of this set
+operation has completed. The retire fence signals when the next set operation
+takes place on the screen. </ul>
+
+<p>The retire fence can be used to determine how long each frame appears on the
+screen. This is useful in identifying the location and source of delays, such
+as a stuttering animation. </p>
+
+<h4 id=vsync_offset>VSYNC Offset</h4>
+
+<p>Application and SurfaceFlinger render loops should be synchronized to the
+hardware VSYNC. On a VSYNC event, the display begins showing frame N while
+SurfaceFlinger begins compositing windows for frame N+1. The app handles
+pending input and generates frame N+2.</p>
+
+<p>Synchronizing with VSYNC delivers consistent latency. It reduces errors in
+apps and SurfaceFlinger and the drifting of displays in and out of phase with
+each other. This, however, does assume application and SurfaceFlinger per-frame
+times don’t vary widely. Nevertheless, the latency is at least two frames.</p>
+
+<p>To remedy this, you may employ VSYNC offsets to reduce the input-to-display
+latency by making application and composition signal relative to hardware
+VSYNC. This is possible because application plus composition usually takes less
+than 33 ms.</p>
+
+<p>The result of VSYNC offset is three signals with same period, offset
+phase:</p>
+
+<ul> <li> <em>HW_VSYNC_0</em> - Display begins showing next frame <li>
+<em>VSYNC</em> - App reads input and generates next frame <li> <em>SF
+VSYNC</em> - SurfaceFlinger begins compositing for next frame </ul>
+
+<p>With VSYNC offset, SurfaceFlinger receives the buffer and composites the
+frame, while the application processes the input and renders the frame, all
+within a single frame of time.</p>
+
+<p>Please note, VSYNC offsets reduce the time available for app and composition
+and therefore provide a greater chance for error.</p>
+
+<h5 id=dispsync>DispSync</h5>
+
+<p>DispSync maintains a model of the periodic hardware-based VSYNC events of a
+display and uses that model to execute periodic callbacks at specific phase
+offsets from the hardware VSYNC events.</p>
+
+<p>DispSync is essentially a software phase lock loop (PLL) that generates the
+VSYNC and SF VSYNC signals used by Choreographer and SurfaceFlinger, even if
+not offset from hardware VSYNC.</p>
+
+<img src="images/dispsync.png" alt="DispSync flow">
+
+<p class="img-caption"><strong>Figure 4.</strong> DispSync flow</p>
+
+<p>DispSync has these qualities:</p>
+
+<ul> <li> <em>Reference</em> - HW_VSYNC_0 <li> <em>Output</em> - VSYNC and SF
+VSYNC <li> <em>Feedback</em> - Retire fence signal timestamps from Hardware
+Composer </ul>
+
+<h5 id=vsync_retire_offset>VSYNC/Retire Offset</h5>
+
+<p>The signal timestamp of retire fences must match HW VSYNC even on devices
+that don’t use the offset phase. Otherwise, errors appear to have greater
+severity than reality.</p>
+
+<p>“Smart” panels often have a delta. Retire fence is the end of direct memory
+access (DMA) to display memory. The actual display switch and HW VSYNC is some
+time later.</p>
+
+<p><code>PRESENT_TIME_OFFSET_FROM_VSYNC_NS</code> is set in the device’s
+BoardConfig.mk make file. It is based upon the display controller and panel
+characteristics. Time from retire fence timestamp to HW Vsync signal is
+measured in nanoseconds.</p>
+
+<h5 id=vsync_and_sf_vsync_offsets>VSYNC and SF_VSYNC Offsets</h5>
+
+<p>The <code>VSYNC_EVENT_PHASE_OFFSET_NS</code> and
+<code>SF_VSYNC_EVENT_PHASE_OFFSET_NS</code> are set conservatively based on
+high-load use cases, such as partial GPU composition during window transition
+or Chrome scrolling through a webpage containing animations. These offsets
+allow for long application render time and long GPU composition time.</p>
+
+<p>More than a millisecond or two of latency is noticeable. We recommend
+integrating thorough automated error testing to minimize latency without
+significantly increasing error counts.</p>
+
+<p>Note these offsets are also set in the device’s BoardConfig.mk make file.
+The default if not set is zero offset. Both settings are offset in nanoseconds
+after HW_VSYNC_0. Either can be negative.</p>
+
+<h3 id=virtual_displays>Virtual displays</h3>
+
+<p>Android added support for virtual displays to Hardware Composer in version
+1.3. This support was implemented in the Android platform and can be used by
+Miracast.</p>
+
+<p>The virtual display composition is similar to the physical display: Input
+layers are described in prepare(), SurfaceFlinger conducts GPU composition, and
+layers and GPU framebuffer are provided to Hardware Composer in set().</p>
+
+<p>Instead of the output going to the screen, it is sent to a gralloc buffer.
+Hardware Composer writes output to a buffer and provides the completion fence.
+The buffer is sent to an arbitrary consumer: video encoder, GPU, CPU, etc.
+Virtual displays can use 2D/blitter or overlays if the display pipeline can
+write to memory.</p>
+
+<h4 id=modes>Modes</h4>
+
+<p>Each frame is in one of three modes after prepare():</p>
+
+<ul> <li> <em>GLES</em> - All layers composited by GPU. GPU writes directly to
+the output buffer while Hardware Composer does nothing. This is equivalent to
+virtual display composition with Hardware Composer <1.3. <li> <em>MIXED</em> -
+GPU composites some layers to framebuffer, and Hardware Composer composites
+framebuffer and remaining layers. GPU writes to scratch buffer (framebuffer).
+Hardware Composer reads scratch buffer and writes to the output buffer. Buffers
+may have different formats, e.g. RGBA and YCbCr. <li> <em>HWC</em> - All
+layers composited by Hardware Composer. Hardware Composer writes directly to
+the output buffer. </ul>
+
+<h4 id=output_format>Output format</h4>
+
+<p><em>MIXED and HWC modes</em>: If the consumer needs CPU access, the consumer
+chooses the format. Otherwise, the format is IMPLEMENTATION_DEFINED. Gralloc
+can choose best format based on usage flags. For example, choose a YCbCr format
+if the consumer is video encoder, and Hardware Composer can write the format
+efficiently.</p>
+
+<p><em>GLES mode</em>: EGL driver chooses output buffer format in
+dequeueBuffer(), typically RGBA8888. The consumer must be able to accept this
+format.</p>
+
+<h4 id=egl_requirement>EGL requirement</h4>
+
+<p>Hardware Composer 1.3 virtual displays require that eglSwapBuffers() does
+not dequeue the next buffer immediately. Instead, it should defer dequeueing
+the buffer until rendering begins. Otherwise, EGL always owns the “next” output
+buffer. SurfaceFlinger can’t get the output buffer for Hardware Composer in
+MIXED/HWC mode. </p>
+
+<p>If Hardware Composer always sends all virtual display layers to GPU, all
+frames will be in GLES mode. Although it is not recommended, you may use this
+method if you need to support Hardware Composer 1.3 for some other reason but
+can’t conduct virtual display composition.</p>
+
+<h2 id=testing>Testing</h2>
+
+<p>For benchmarking, we suggest following this flow by phase:</p>
+
+<ul> <li> <em>Specification</em> - When initially specifying the device, such
+as when using immature drivers, you should use predefined (fixed) clocks and
+workloads to measure the frames per second rendered. This gives a clear view of
+what the hardware is capable of doing. <li> <em>Development</em> - In the
+development phase as drivers mature, you should use a fixed set of user actions
+to measure the number of visible stutters (janks) in animations. <li>
+<em>Production</em> - Once the device is ready for production and you want to
+compare against competitors, you should increase the workload until stutters
+increase. Determine if the current clock settings can keep up with the load.
+This can help you identify where you might be able to slow the clocks and
+reduce power use. </ul>
+
+<p>For the specification phase, Android offers the Flatland tool to help derive
+device capabilities. It can be found at:
+<code>platform/frameworks/native/cmds/flatland/</code></p>
+
+<p>Flatland relies upon fixed clocks and shows the throughput that can be
+achieved with composition-based workloads. It uses gralloc buffers to simulate
+multiple window scenarios, filling in the window with GL and then measuring the
+compositing. Please note, Flatland uses the synchronization framework to
+measure time. So you must support the synchronization framework to readily use
+Flatland.</p>
diff --git a/src/devices/images/graphics_surface.png b/src/devices/images/graphics_surface.png
deleted file mode 100644
index e32792df..00000000
--- a/src/devices/images/graphics_surface.png
+++ /dev/null
Binary files differ
diff --git a/src/index.jd b/src/index.jd
index c073127e..bcf28c35 100644
--- a/src/index.jd
+++ b/src/index.jd
@@ -42,14 +42,21 @@ header.hide=1
<div class="col-8">
<h3>What's New</h3>
+<a href="{@docRoot}devices/graphics.html">
+ <h4>Graphics introduction and implementation rewritten</h4></a>
+ <p>The <strong><a
+ href="{@docRoot}devices/graphics.html">Graphics introduction</a></strong> and <strong><a
+ href="{@docRoot}devices/graphics/implement.html">implementation
+ instructions</a></strong> have been revised in entirety.</p>
+
+<img border="0" src="images/Android_Robot_100.png" alt="Android Partner icon" style="display:inline;float:right;margin:5px 10px">
+
<a href="{@docRoot}devices/drm.html">
<h4>DRM page rewritten</h4></a>
<p>The description of the Android <strong><a
href="{@docRoot}devices/drm.html">DRM</a></strong> framework has been
completely rewritten and expanded.</p>
-<img border="0" src="images/Android_Robot_100.png" alt="Android Partner icon" style="display:inline;float:right;margin:5px 10px">
-
<a href="{@docRoot}devices/tuning.html">
<h4>Performance tuning property removed</h4></a>
<p>The <code>ro.hwui.fbo_cache_size</code> property has been removed
@@ -68,12 +75,6 @@ href="{@docRoot}devices/tuning.html">Performance tuning</a></strong> list.</p>
<p>The list of <strong><a
href="{@docRoot}source/known-issues.html">Known Issues</a></strong>
has been updated and split into categories.</p>
-
-<a href="{@docRoot}compatibility/4.4/versions.html">
- <h4>New version strings added for 4.4</h4></a>
- <p><strong><a
- href="{@docRoot}compatibility/4.4/versions.html">Permitted Version Strings for
- Android 4.4</a></strong> have been updated.</p>
</div>
<div class="col-8">