chromium/components/viz/README.md

# //components/viz

Viz - short for visuals - is the client library and service implementations for
compositing and gpu presentation.

See [//services/viz](../../services/viz/README.md) for more information about
Viz overall.

For understanding compositing related terminology, check out
[//cc](../../cc/README.md). For understanding display compositor's position in
the graphics stack, check out
[Compositor Stack slides](https://docs.google.com/presentation/d/1ou3qdnFhKdjR6gKZgDwx3YHDwVUF7y8eoqM3rhErMMQ/edit?usp=sharing).
For more comprehensive list of design docs relating to Viz, check out
[WIP list of design doc](https://crbug.com/821901).

**Table of Contents**
1. [Terminology](#terminology)
2. [Directory structure](#directory-structure)
    1. [common](#directory-structure-common)
    2. [client](#directory-structure-client)
    3. [host](#directory-structure-host)
    4. [service](#directory-structure-service)
3. [Runtime Features](#runtime-features)
4. [Naming guidelines with Mojo](#naming-guidelines)

## Terminology

**Mojo Interface**: The interface definition, found in a .mojom file. This is
an abstract interface and can be thought of as a process/thread-independent C++
abstract class.

**Mojo Implementation**: The default implementation of a mojom interface for
production. Many interfaces will only have a single implementation that we
ship.

**Alternate Mojo Implementations**: Secondary implementations of a mojom
interface for platform-specific details, for tests, etc.

**Service**: Where Mojo implementations live and run.

**Host**: A privileged process that provides access to viz Mojo interfaces for
Clients. Most services in Chrome don’t have these, and Clients find the service
directly, but they are more common in Viz. Currently the Host is in the browser
process. In a fully-realized mus+ash, the Host moves outside of Chrome to the
window server.

**Client**: All users of a Mojo interface who are not the Host. They will
usually need to go through the Host to gain access to the Mojo interface.

**Host-side Wrapper**: A C++ wrapper around a Mojo interface for use in Hosts,
that often also exposes or uses some privileged interfaces that Clients don’t
have. Generally prefer to use the Mojo interfaces directly, but sometimes we
need another C++ helper around it.

**Client-side Wrapper**: A C++ wrapper around a Mojo interface for use in
Clients. Generally prefer to use the Mojo interface directly, but sometimes we
need another C++ helper around it.

**Host/Client-side Abstraction**: A C++ wrapper around a Mojo interface that is
also a subclass of a C++ interface. Generally prefer to use the Mojo interfaces
directly, but sometimes we need a higher-level C++ abstraction, usually because
other subclasses cannot use the Mojo interface.


## Directory Structure <a name="directory-structure"></a>
To keep dependencies clear into the Viz source tree, all source code files
should appear in leaf directories.

### common <a name="directory-structure-common"></a>
Data types and simple helpers that are used by the client library, or by
clients directly, and by service implementations.

### client <a name="directory-structure-client"></a>
Client library for accessing Viz services. May be used from privileged (eg
browser) or unprivileged (eg renderer) processes. The client library should
remain agnostic about *how* to communicate with viz (in other words should not
use mojo bindings), as some viz clients use mojo but others use it in-process
or via other IPC mechanisms.

| Can depend on: |
|:---------------|
| viz/common/    |

### host <a name="directory-structure-host"></a>
Privileged client library for owning and controlling Viz services. May only be
used from privileged (eg browser) processes.

This should not depend on other parts of Viz, as they are core data types and
helpers only, and can be used from anywhere else in Viz.

| Can depend on: |
|:---------------|
| viz/common/    |

### service <a name="directory-structure-service"></a>
Service-side implementations of Viz Mojo interfaces, which are found in
[//services/viz](https://cs.chromium.org/chromium/src/services/viz/). Each
component of the service-side implementation is located in its own
sub-directory.

As of this writing, these service components may be instantiated and used
directly from the browser process. But these services are intended to be
abstracted away through Mojo interfaces so that they are able to live entirely
outside the browser process, and gain in-process access to the Gpu.

#### service/display
**Display compositor**: The display compositor uses Gpu or software to composite
a set of frames, from multiple clients, into a single backing store for display
to the user. Also deals in getting screenshots of content by drawing to
offscreen buffers.

The top-level scheduler that coordinates when the compositor should draw, along
with when clients should be submitting frames.

This component is platform-agnostic, with any platform-specific details
abstracted away from it. It accesses Gpu services through the command buffer as
a client even though it is in the same process as the Gpu service in order to
be scheduled as a peer among other clients.

| Can depend on:        |
|:----------------------|
| viz/common/*          |
| viz/service/surfaces/ |

#### service/display_embedder
**Platform details for display compositor**: While the display compositor is
platform-agnostic, this component provides implementations of platform-specific
behaviour needed for the display compositor, and injected into it.

Code here supports presentation of the backing store drawn by the display
compositor (typically thought of as SwapBuffers), as well as the use of
overlays.

| Can depend on:                        |
|:--------------------------------------|
| viz/common/*                          |
| viz/service/display/<some_interfaces> |

Dependencies onto viz/service/display should generally only be for interfaces
that the embedder must provide to the display.

#### service/frame_sinks
**Frame sinks**: This component implements the Mojo interfaces to send frames,
resources, and other data types from ``viz/common/`` for display to the
compositing service. It receives and organizes relationships between what should
be composited.

| Can depend on:                |
|:------------------------------|
| viz/common/*                  |
| viz/service/display/          |
| viz/service/display_embedder/ |
| viz/service/hit_test/         |
| viz/service/surfaces/         |
| viz/service/transitions/      |

#### service/frame_sinks/video_capture
**FrameSinkVideoCaptureImpl**: This component implements the [Mojo
interfaces](../../services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom)
to capture frames that are sent to the compositing service, producing a stream
of video frames. It provides a capture pipeline where asynchronous GPU readback
is executed (via [CopyOutputRequests](common/frame_sinks/README.md), and then
CopyOutputResults are applied to a pool of shared memory buffers backing video
frames that are sent to privileged consumers.

A capturer instance is created via [FrameSinkManager's
CreateVideoCapturer()](../../services/viz/privileged/mojom/compositing/frame_sink_manager.mojom)
method.

| Can depend on:                |
|:------------------------------|
| media/base/*                  |
| media/capture/*               |
| media/mojo/*                  |
| viz/common/*                  |
| viz/service/frame_sinks/*     |

#### service/gl
**GL**: This component implements the Mojo interfaces for allocating (and
deallocating) gpu memory buffers, setting up a channel for the command buffer,
etc.

| Can depend on:        |
|:----------------------|
| viz/common/*          |

#### service/hit_test
**Hit testing**: Service-side code to resolve input events to individual
clients.

| Can depend on:        |
|:----------------------|
| viz/common/*          |
| viz/service/surfaces/ |

#### service/main
**Main**: TODO(fsamuel): This will hold implementation of the root interface
from which other service interfaces are accessed.

As the root of the service/ code structure, it instantiates and connects all
other parts of Viz.

| Can depend on: |
|:---------------|
| viz/common/*   |
| viz/service/*  |

#### service/surfaces
**Surfaces**: This component acts like the data model for the compositing service.
It holds data received from frame sinks, and provides access to them for the
display compositor.

| Can depend on: |
|:---------------|
| viz/common/*   |

#### service/transitions
**Transitions**: This directory is in support of the view transitions
project. See //third\_party/blink/rendering/core/document\_transition/README.md

| Can depend on:        |
|:----------------------|
| viz/common/           |
| viz/service/surfaces/ |

## Runtime Features

Viz related runtime feature flags, aka `base::Feature`s, should go in
[components/viz/common/features.h](https://cs.chromium.org/chromium/src/components/viz/common/features.h).

When adding a new feature `kMyFeature`, it's recommended that you add a helper
function `IsMyFeatureEnabled()` to check if the feature is enabled. Code should
then use `IsMyFeatureEnabled()` instead of checking
base::FeatureList::IsEnabled(kMyFeature)`.

Preconditions can be platform or hardware specific checks to determine if a
feature is supported on a given device. These preconditions should be validated
before checking the `base::FeatureList`, as once the list is consulted the
session will be reflected in any ongoing Finch trial. If we were to disable the
implementation due to preconditions after registering with Finch, then we will
be providing incorrect data to the study.

### Runtime Feature Checks

`base::FeatureList::IsEnabled()` caches the feature's value internally on the
first lookup, making all subsequent lookups cheap. Thus, it is acceptable for it
to be called in a hot code path.

Note `base::ScopedFeatureList` resets/invalidates the feature's internal cache
on initialization so that the feature's value may be controlled across test
cases as desired. This does not hold, however, if the calling code itself
chooses to cache the feature's value in a variable with static storage duration.
This pattern is discouraged:

```cpp
bool IsMyFeatureEnabled() {
  static bool enabled = base::FeatureList::IsEnabled(kMyFeature);  // NO!
  return enabled;
}
```

The first time `IsMyFeatureEnabled()` is called from the test runner process the
feature state is cached within the static `enabled` variable. If a later test
uses `base::ScopedFeatureList` to change the feature state, that change will not
be reflected in `IsMyFeatureEnabled()` and the test will (most likely) fail.

### Testing Viz Features

Ensure that features are enabled/disabled for testing before any viz code is
initialized. As a general rule `base::ScopedFeatureList` should be the first
thing initialized in a test fixture to avoid data races and incorrect feature
values.

## Naming guidelines with Mojo <a name="naming-guidelines"></a>

Viz makes extensive use of Mojo, and there are conflicting patterns with
regard to naming types around Mojo interfaces in the codebase today. This aims
to provide a standard to adhere to for future naming to increase our
consistency within the team.

For a given mojo service called `TimeTraveller`, we would use the following.

**Mojo Interface**: `mojom::TimeTraveller`
* This is the abstract interface definition. It comes with no prefix or suffix,
and lives in a (sometimes nested) mojom namespace.

**Mojo Implementation**: `TimeTravellerImpl`
* This is the implementation of the interface. For other C++ interfaces we
commonly use the Impl suffix, and we will repeat this here, as it’s already
commonly used and is well understood.
* If there will be multiple implementations, see below.

**Alternative Mojo Implementation**: `DescriptivePrefixTimeTravellerImpl`
* This is a non-default implementation of the interface. It follows the same
rules as a default implementation, but is used for tests, or cases where we
don’t have a simple default production implementation.
* The descriptive prefix should describe what makes this implementation
different from others, as such why it exists.

**Host-side Wrapper**: `HostTimeTraveller`
* This wraps the Mojo interface, providing a higher-level abstraction and
utilities for using the Mojo interface. It only is meant to exist and be
accessed in the privileged Host process. We prefix with Host to explain what
makes this interface special and when it can be used. We do not suffix to be
consistent with Clients.

**Client-side Wrapper**: `ClientTimeTraveller`
* This wraps the Mojo interface, providing a higher-level abstraction and
utilities for using the Mojo interface. It may exist and be used in any Client
in place of the Mojo interface. Prefer to use the Mojo interface directly when
possible. We prefix with Client to explain in what situations it can be used.
We do not suffix to avoid a TimeTravellerClientClient in the case where this
class has itself a C++ client, as ClientTimeTravellerClient appeared to be a
better option of the two.

**Host/Client-side Abstraction**: `OtherAbstractionName`
* This is a case of an object implementing a C++ interface, which it should be
named after. A prefix describing what makes this implementation special can
refer to its use of the Mojo interface.