0
Files
android_webview
apps
ash
base
build
build_overrides
buildtools
cc
chrome
chromecast
chromeos
clank
codelabs
components
content
courgette
crypto
dbus
device
docs
accessibility
autofill
chromeos
design
enterprise
experiments
fuchsia
gpu
debugging_gpu_related_code.md
gpu_expectation_files.md
gpu_pixel_testing_with_gold.md
gpu_testing.md
gpu_testing_bot_details.md
pixel_wrangling.md
profiling_chromium_with_Intel_GPA.md
server-side-headless-linux-chrome-with-gpus.md
swiftshader.md
sync_token_internals.md
vaapi.md
webgl_bug_triage.md
webgpu_cts_harness_message_protocol.md
images
infra
intl
ios
lacros
linux
login
mac
media
memory
memory-infra
patterns
privacy
privacy_budget
process
security
speed
speed_metrics
standards
telemetry_extension
testing
transcripts
ui
updater
webapps
website
workflow
DIR_METADATA
OWNERS
README.md
accessibility.md
ad_tagging.md
adding_to_third_party.md
android_accessing_cpp_enums_in_java.md
android_accessing_cpp_features_in_java.md
android_accessing_cpp_switches_in_java.md
android_build_instructions.md
android_cast_build_instructions.md
android_debugging_instructions.md
android_dynamic_feature_modules.md
android_emulator.md
android_isolated_splits.md
android_jni_ownership_best_practices.md
android_logging.md
android_native_libraries.md
android_studio.md
angle_in_chromium.md
api_keys.md
asan.md
atom.md
benchmark_performance_regressions.md
bitmap_pipeline.md
branch_gardener.md
building_old_revisions.md
callback.md
ccache_mac.md
chrome_os_logging.md
chrome_settings.md
chrome_untrusted.md
chromedriver_status.md
chromeos_build_instructions.md
chromeos_glossary.md
chromium_browser_vs_google_chrome.md
cipd_and_3pp.md
cl_respect.md
cl_tips.md
clang.md
clang_code_coverage_wrapper.md
clang_format.md
clang_gardening.md
clang_sheriffing.md
clang_static_analyzer.md
clang_tidy.md
clang_tool_refactoring.md
clangd.md
clion.md
closure_compilation.md
cocoa_tips_and_tricks.md
code_review_owners.md
code_reviews.md
commit_checklist.md
component_build.md
configuration.md
contributing.md
cq_fault_attribution.md
cr_respect.md
cr_user_manual.md
cross_platform_ui.md
cygwin_dll_remapping_failure.md
dangling_ptr.md
dangling_ptr_guide.md
dbus_mojo_connection_service.md
debugging_with_crash_keys.md
dependencies.md
deterministic_builds.md
disassemble_code.md
documentation_best_practices.md
documentation_guidelines.md
early-hints.md
eclipse.md
emacs.md
erc_irc.md
flag_expiry.md
flag_guarding_guidelines.md
flag_ownership.md
frame_trees.md
gardener.md
gdbinit.md
get_the_code.md
git_cookbook.md
git_submodules.md
git_tips.md
google_chrome_branded_builds.md
google_play_services.md
graphical_debugging_aid_chromium_views.md
gwp_asan.md
history_manipulation_intervention.md
how_cc_works.md
how_to_add_your_feature_flag.md
how_to_extend_web_test_framework.md
idn.md
initialize_blink_features.md
inlined_stack_traces.md
installation_at_vmware.md
ios_build_instructions.md
ios_infra.md
ios_voiceover.md
kiosk_mode.md
lacros.md
life_of_a_frame.md
lldbinit.md
mac_arm64.md
mac_build_instructions.md
mac_lld.md
modifying_session_history_serialization.md
mojo_and_services.md
mojo_ipc_conversion.md
mojo_testing.md
native_relocations.md
navbar.md
navigation-request-navigation-state.gv
navigation-request-navigation-state.png
navigation.md
navigation_concepts.md
network_traffic_annotations.md
no_sources_assignment_filter.md
optimizing_web_uis.md
origin_trials_integration.md
ozone_overview.md
parsing_test_results.md
pgo.md
piranha_plant.md
process_model_and_site_isolation.md
profiling.md
profiling_content_shell_on_android.md
proxy_auto_config.md
qtcreator.md
release_branch_guidance.md
render-frame-host-lifecycle-state.gv
render-frame-host-lifecycle-state.png
render_document.md
rust.md
seccomp_sandbox_crash_dumping.md
servicification.md
session_history.md
sheriff.md
shutdown.md
special_case_urls.md
static_initializers.md
sublime_ide.md
system_hardening_features.md
tab_helpers.md
testing_webui.md
threading_and_tasks.md
threading_and_tasks_faq.md
threading_and_tasks_testing.md
toolchain_support.md
tour_of_luci_ui.md
tpm_quick_ref.md
translation_screenshots.md
trusted_types_on_webui.md
updating_clang.md
updating_clang_format_binaries.md
use_counter_wiki.md
useful_urls.md
user_data_dir.md
user_data_storage.md
user_handle_mapping.md
vanilla_msysgit_workflow.md
vscode.md
vscode_python.md
webui_build_configuration.md
webui_explainer.md
webui_in_chrome.md
webui_in_components.md
webview_policies.md
win_cross.md
win_order_files.md
windows_build_instructions.md
windows_native_window_occlusion_tracking.md
windows_pwa_integration.md
windows_shortcut_and_taskbar_handling.md
windows_split_dll.md
windows_virtual_desktop_handling.md
wmax_tokens.md
working_remotely_with_android.md
writing_clang_plugins.md
extensions
fuchsia_web
gin
google_apis
google_update
gpu
headless
infra
internal
ios
ios_internal
ipc
media
mojo
native_client
native_client_sdk
net
pdf
ppapi
printing
remoting
rlz
sandbox
services
signing_keys
skia
sql
storage
styleguide
testing
third_party
tools
ui
url
v8
webkit
.clang-format
.clang-tidy
.clangd
.eslintrc.js
.git-blame-ignore-revs
.gitallowed
.gitattributes
.gitignore
.gitmodules
.gn
.mailmap
.rustfmt.toml
.vpython3
.yapfignore
ATL_OWNERS
AUTHORS
BUILD.gn
CODE_OF_CONDUCT.md
DEPS
DIR_METADATA
LICENSE
LICENSE.chromium_os
OWNERS
PRESUBMIT.py
PRESUBMIT_test.py
PRESUBMIT_test_mocks.py
README.md
WATCHLISTS
codereview.settings
src/docs/gpu/sync_token_internals.md
kylechar 7fbb9e9abd Last cleanup pass for GLRenderer/SkiaRenderer
Remove references to GLRenderer that are no longer relevant and remove some last bits of dead code.

Bug: 1247756
Change-Id: I9511c27c0ce6ac9e095c0f23cef127506152b6e1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3703316
Reviewed-by: Scott Violet <sky@chromium.org>
Reviewed-by: Peng Huang <penghuang@chromium.org>
Commit-Queue: Kyle Charbonneau <kylechar@chromium.org>
Reviewed-by: Alexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1020715}
2022-07-05 03:07:39 +00:00

6.5 KiB

CHROMIUM Sync Token Internals

Chrome uses a mechanism known as "sync tokens" to synchronize different command buffers in the GPU process. This document discusses the internals of the sync token system.

[TOC]

Rationale

In Chrome, multiple processes, for example browser and renderer, submit work to the GPU process asynchronously in command buffer. However, there are dependencies between the work submitted by different processes, such as SkiaRenderer in the display compositor in the GPU process rendering a tile produced by the raster worker in the renderer process.

Sync tokens are used to synchronize the work contained in command buffers without waiting for the work to complete. This improves pipelining, and with the introduction of GPU scheduling, allows prioritization of work. Although originally built for synchronizing command buffers, they can be used for other work in the GPU process.

Generation

Sync tokens are represented by a namespace, identifier, and the fence release count. CommandBufferId is a 64-bit unsigned integer which is unique within a CommandBufferNamespace. For example IPC command buffers are in the GPU_IO CommandBufferNamespace, and are identified by CommandBufferId with process id as the MSB and IPC route id as the LSB.

The fence release count marks completion of some work in a command buffer. Note: this is CPU side work done that includes command decoding, validation, issuing GL calls to the driver, etc. and not GPU side work. See gpu_synchronication.md for more information about synchronizing GPU work.

Fences are typically generated or inserted on the client using a sequential counter. The corresponding GL API is GenSyncTokenCHROMIUM which generates the fence using CommandBufferProxyImpl::GenerateFenceSyncRelease(), and also adds the fence to the command buffer using the internal InsertFenceSync command.

Verification

Different client processes communicate with the GPU process using channels. A channel wraps around a message pipe which doesn't provide ordering guarantees with respect to other pipes. For example, a message from the browser process containing a sync token wait can arrive before the message from the renderer process that releases or fulfills the sync token promise.

To prevent the above problem, client processes must verify sync tokens before sending to another process. Verification involves a synchronous nop IPC message, GpuChannelMsg_Nop, to the GPU process which ensures that the GPU process has read previous messages from the pipe.

Sync tokens used within a process do not need to be verified, and the GenSyncTokenUnverifiedCHROMIUM GL API serves this common case. These sync tokens need to be verified using VerifySyncTokensCHROMIUM. Sync tokens generated using GenSyncTokenCHROMIUM are already verified. SyncToken has a verified_flush bit that guards against accidentally sending unverified sync tokens over IPC.

Streams

In the GPU process, command buffers are organized into logical streams of execution that are called sequences. Within a sequence tasks are ordered, but are asynchronous with respect to tasks in other sequences. Dependencies between tasks are specified as sync tokens. For IPC command buffers, this implies flush ordering within a sequence.

A sequence can be created by Scheduler::CreateSequence which returns a SequenceId. Tasks are posted to a sequence using Scheduler::ScheduleTask. Typically there is one sequence per channel, but sometimes there are more like raster, compositor, and media streams in renderer's channel.

The scheduler also provides a means for co-operative scheduling through Scheduler::ShouldYield and Scheduler::ContinueTask. These allow a task to yield and continue once higher priority work is complete. Together with the GPU scheduler, multiple sequences provide the means for prioritization of UI work over raster prepaint work.

Waiting and Completion

Sync tokens are managed in the GPU process by SyncPointManager, and its helper classes SyncPointOrderData and SyncPointClientState. SyncPointOrderData holds state for a logical stream of execution, typically containing work of multiple command buffers from one process. SyncPointClientState holds sync token state for a client which generated sync tokens, typically an IPC command buffer.

GPU scheduler maintains a SyncPointOrderData per sequence. Clients must create SyncPointClientState using SyncPointManager::CreateSyncPointClientState and identify their namespace, id, and sequence.

Waiting on a sync token is done by calling SyncPointManager::Wait() with a sync token, order number for the wait, and a callback. The callbacks are enqueued with the SyncPointClientState of the target with the release count of the sync token. The scheduler does this internally for sync token dependencies for scheduled tasks, but the wait can also be performed when running the WaitSyncTokenCHROMIUM GL command.

Sync tokens are completed when the fence is released in the GPU process by calling SyncPointClientState::ReleaseFenceSync(). For GL command buffers, the InsertFenceSync command, which contains the release count generated in the client, calls this when executed in the service. This issues callbacks and allows waiting command buffers to resume their work.

Correctness

Correctness of waits and releases basically amounts to checking that there are no indefinite waits because of broken promises or circular wait chains. This is ensured by associating an order number with each wait and release and maintaining the invariant that the order number of release is less than or equal to the order number of wait.

Each task is assigned a global sequential order number generated by SyncPointOrderData::GenerateUnprocessedOrderNumber which are stored in a queue of unprocessed order numbers. In SyncPointManager::Wait(), the callbacks are also enqueued with the order number of the waiting task in SyncPointOrderData in a queue called OrderFenceQueue.

SyncPointOrderData maintains the invariant that all waiting callbacks must have an order number greater than the sequence's next unprocessed order number. This invariant is checked when enqueuing a new callback in SyncPointOrderData::ValidateReleaseOrderNumber, and after completing a task in SyncPointOrderData::FinishProcessingOrderNumber.

See Also

CHROMIUM_sync_point gpu_synchronication.md Lightweight GPU Sync Points