How Chromium Construct Layer Tree Again
How cc Works
Original google physician
Chinese | Korean
tl;dr
cc/ is historically just inaccurately called the Chrome Compositor. Information technology'south neither "the" chrome compositor (of course we have many), nor a compositor at all any more. danakj suggests "content collator" as an alternative name.
cc is embedded via ui/compositor or Android code in the browser procedure, as well as ui/compositor in mus utility processes. It is also embedded in the renderer process via Blink / RenderWidget. cc is responsible for taking painted inputs from its embedder, figuring out where and if they appear on screen, rasterizing and decoding and animating images from the painted input into gpu textures, and finally forwarding those textures on to the display compositor in the form of a compositor frame. cc also handles input forwarded from the browser procedure to handle pinch and coil gestures responsively without involving Blink.
Procedure / thread architecture
cc can be embedded in both single-threaded and multi-threaded incarnations. The single-threaded version has less overhead. The multi-threaded version incurs a latency cost, but allows for input and animations to be responsively handled on i thread while the other thread is busy. In general, the browser uses the unmarried-threaded version as its main thread is cheap and light, whereas the renderer uses the multi-threaded version as its main thread (Glimmer) can be quite decorated on some pages.
Both single and multi-threaded versions drive themselves using the cc::Scheduler, which determines when to submit frames. The i exception (a 3rd style that is but used in one identify) is Blink layout tests and sim tests, which exercise not (always) use a scheduler and tell cc when to composite synchronously, via LayerTreeHost::Blended. This is for historical reasons, and too to have more control during testing.
Content Data Flow Overview
The primary interface to cc by embedders is a LayerTreeHost (created with diverse LayerTreeSettings) and a tree of Layers. A Layer is a rectangle of content, with various properties describing how that content should appear on screen. cc is responsible for turning a painted representation of that content (due east.g. a PaintRecord) into a rasterized representation (a software bitmap or a gpu texture) and figuring out where that rectangle appears on screen.
cc turns this layer tree input into a set of holding trees via a PropertyTreeBuilder and simplifies the layer tree downward to an ordered list of visible layers. Every bit a function of the slimming paint project, Blink volition set property trees and layer list direct instead of going through the more than historical layer tree interface and avoid the work of this part of the pipeline.
During the commit procedure, cc forrad all of the inputs from the chief thread data structures to compositor thread data structures. At this point, cc determines which parts of each Layer are visible and proceeds to decode images and raster content. Once all the content is gear up to appear on screen, cc activates the committed tree and can then "describe" from it.
cc unfortunately yet uses the language of "draw" and "bandy" in a number of places, despite the fact that it no longer does either of these things. "Describe" in cc means amalgam a compositor frame full of quads and render passes for eventual drawing on screen. "Bandy" in cc means submitting that frame to the display compositor via a CompositorFrameSink. These frames get sent to the viz SurfaceAggregator where compositor frames from all frame producers are aggregated together.
Input Data Flow Overview
The other main piece of input to cc is user input, such as mouse clicks, mouse wheels, and affect gestures. In the renderer procedure, input is forwarded from the browser procedure. Information technology is processed by ui::InputHandlerProxy (a cc::InputHandlerClient).
Some of this input is forwarded to the LayerTreeHostImpl (a cc::InputHandler) at specific times. This allows it to modify the active layer's property tree and scroll or compression as needed. Some input tin can't be handled past the compositor thread (e.g. there's a synchronous Javascript impact or bike handler) and so that input is forwarded along to Blink to handle directly. This input flow follows the opposite path of the content data flow in the section above.
Commit Menstruation
Commit is a method of getting data atomically from the main thread to the compositor thread. (Even when running in single threaded mode, this operation occurs to move data into the right data structures.) Rather than sending an ipc, commit is done past blocking the main thread and copying data over.
The primary thread tin can request a commit in several ways. Virtually webpages request one via requestAnimationFrame, which eventually calls SetNeedsAnimate on LayerTreeHost. Additionally, modifying any of cc's inputs (e.m. a layer property, such every bit its transform or a modify to the layer's content), will call either SetNeedsAnimate, SetNeedsUpdate, or SetNeedsCommit on LayerTreeHost. The unlike SetNeeds functions let for dissimilar levels of early-out aborts of the commit if no piece of work is determined to be needed. (For example, if the requestAnimationFrame callback does no work, and so in that location'due south no need to exercise the commit or even update layers.) All of these functions request a BeginMainFrame from the scheduler, if non currently in the center of servicing one.
At some point, the scheduler will respond with a ScheduledActionBeginMainFrame. This sends BeginFrameArgs from the compositor thread to the main thread to kickoff a BeginMainFrame. BeginFrameArgs contain a time (for animation purposes) as well equally any scroll deltas that take been applied on the compositor thread (mainly every bit a result of handling user ringlet gestures) that Glimmer doesn't know well-nigh. When Glimmer is embedding cc, a BeginMainFrame applies any compositor curl deltas to Glimmer, kicks off requestAnimationFrame logic, and finishes the Blink half of the rendering lifecycle.
Once this is done, cc updates all layers. If at any point in this update pipeline, cc determines that no work left is required (e.one thousand. a compositor thread ringlet updates Glimmer, simply Glimmer makes no changes to the page in response to that scroll), then it may abort the commit early on. (Single-threaded cc never aborts commits, currently.) Once the embedder has finished its BeginMainFrame work and if the commit has not been aborted, then ProxyMain sends a synchronous NotifyReadyToCommit and blocks by forwarding a mutex to the compositor thread.
When the scheduler is set to commit, it will reply with a ScheduledActionCommit. The ProxyImpl on the compositor thread then does all the piece of work of copying the data from the main thread (while it is blocked) to compositor thread data structures. It then releases the mutex so that the main thread can continue.
ProxyImpl is the simply class that accesses data structures on both the main thread and the compositor thread. It simply accesses the LayerTreeHost and Layers on the main thread when the main thread is blocked and enforces this through accessor DCHECKs. ProxyMain is its counterpart that exists on the main thread and is owned by the LayerTreeHost. For the unmarried threaded example, SingleThreadProxy encompasses the tasks of both ProxyMain and ProxyImpl.
Layers
A layer is a second rectangle of content with integer premises. It has some transform, clip, and effects on it that describe how it should look on screen.
In that location are two divide class hierarchies of Layers, 1 for the master thread layer tree (deriving from cc::Layer) and one for the compositor thread awaiting, agile, and recycle layer trees (deriving from cc::LayerImpl). There is roughly a 1:1 correspondence, such that there exists SurfaceLayer and SurfaceLayerImpl or PictureLayer and PictureLayerImpl, so this section will mostly talk nearly these pairs synonymously.
On the master thread, Layers are refcounted. LayerTreeHost owns the root layer, and each layer recursively owns its children. Some other parts of Blink also provide layers (e.one thousand. the media organization creating surface or video layers, plugins), which is why this is ref-counted. On the compositor thread, layers are unique_ptrs, owned by their parents.
Property Trees
At that place are 2 ways of specifying hierarchical properties in cc. The historical mode (and the way that ui/ manages this) is to provide a tree of Layers. If a parent layer has a transform (due east.m. a translation, calibration, or perspective), a prune, or an effect (e.k. a mistiness filter, or a mask, or an opacity) and then this applies recursively to its children. This abstraction has a lot of corner cases (fixed position layers, scroll parents, scroll children) likewise as non being performant (requires traversing a very large tree and calculating all properties at all steps).
Holding trees are a style around this. Instead, cc is provided with separate trees of properties: a transform tree, a clip tree, an effect tree. Each layer and then has a node id for which transform, clip, and effect node that the layer is using. In this way, the update is O(interesting nodes) instead of O(layers). When in that location are property trees, there is also no longer a need for a tree of layers, and instead an ordered listing of layers tin be used.
PictureLayer
A layer containing painted content. This content comes in the class of a cc::PaintRecord. PictureLayer is responsible for figuring out which calibration(s) the content should exist rastered at. Each calibration is represented past a PictureLayerTiling, which is a sparse 2nd regular tiling of the content at a particular scale.
Each tile in this tiling is a cc::Tile, which represents potential content and their rasterization is organized by the TileManager. If you lot plow on composited layer borders in the DevTools rendering settings, you lot tin see the tile borders. There are a number of heuristics that make up one's mind tile sizes, merely for software raster tiles are roughly 256x256 px and for gpu raster tiles are roughly viewport width x 1 quarter viewport acme.
In that location are a number of heuristics to determine when and how to change rasterization scales. These aren't perfect, just change them at your own peril. 🐉🐉🐉
Straight composited images
A specialized raster mode of PictureLayerImpl. If a PictureLayer'southward DisplayItemList consists of a unmarried drawImageRect DrawOp, nosotros use different logic to determine what the raster scale of the epitome should stop up being. The layer is rastered at stock-still scales such that scaling this image is performant. The default raster calibration is called such that the image will raster at its intrinsic side, so that scale is adapted, based on how close information technology is to the ideal scale. See PictureLayerImpl::ShouldAdjustRasterScale and RecalculateRasterScales for more details.
TextureLayer
Used for plugins, canvas when information technology does its own raster, and WebGL. The "texture" here refers to a reference to a gpu texture, though nether software compositing it would be a shared memory bitmap.
SolidColorLayer
If a layer is known to be merely a solid colour, then there is no demand to spend raster work or gpu retentivity on information technology. This is an optimization for when a layer's content is known to be simple.
VideoLayer
Deprecated as a function of the surfaces for video projection. Should somewhen be deleted.
SurfaceLayer
A surface layer has a surface id, which refers to some other stream of compositor frames in the system. This is a way of having an indirection to other compositor frame producers. Run across too: surface documentation. For example, Glimmer embeds references to out of procedure iframes via SurfaceLayer.
SolidColorScrollbarLayer
Android scrollbars are "solid colour" scrollbar layers. They are unproblematic boxes that tin be drawn on the compositor without creating texture resource for them. Both solid color and painted scrollbar layers exist and so that scrolling on the compositor thread tin can update the scrollbar responsively without going back to the principal thread. Without this, the folio would scroll smoothly simply the scrollbar would jump around jankily.
Painted(Overlay)ScrollbarLayer
Desktop (non-Android) scrollbars are painted scrollbars. Because theme lawmaking is not thread safe, the thumb and rail are painted and rastered into bitmaps on the primary thread. So, those bitmaps are emitted as quads on the compositor thread. ChromeOS uses PaintedOverlayScrollbarLayer, which is a nine-patch bitmap version.
HeadsUpDisplayLayer
This layer supports devtools rendering settings. It draws an Frame Rendering Stats, equally well every bit overlays for paint invalidation or damage. This layer is special because information technology must be updated last because its inputs depend on all of the other layers' damage calculations.
UIResourceLayer / NinePatchLayer
UIResourceLayer is the software bitmap equivalent of TextureLayer. Information technology handles uploading bitmaps and recreating them every bit needed when contexts are lost. NinePatchLayer is a derived UIResourceLayer class that dices up a UIResource into stretchable pieces.
Trees: commit / activation
There are four types of layer trees, although at that place always exists 2-3 at whatsoever given time:
-
Chief thread tree (cc::Layers, main thread, ever exists)
-
Awaiting tree (cc::LayerImpl, compositor thread, staging for rasterization, optional)
-
Active tree (cc::LayerImpl, compositor thread, staging for cartoon, always exists)
-
Recycle tree (cc::LayerImpl, compositor thread, mutually sectional with awaiting tree)
These are chosen "trees" as historically they have been trees and they exist in cc/copse/, but they are all lists and not trees (deplorable). The main thread tree of Layers is owned by LayerTreeHost. The pending, active, and recycle trees of LayerImpls are all LayerTreeImpl instances owned by LayerTreeHostImpl.
Commit is the procedure of pushing layer trees and properties from the chief thread layer listing to the pending tree. Activation is the process of pushing layer trees and properties from the pending tree to the active tree. During each of these processes, a duplicate layer construction is created (with the same layer ids, layer types, and properties). Layer ids are used to find the corresponding layer on each tree. A layer with id 5 on the main thread tree will push to layer id 5 on the pending tree. That awaiting layer will push to a layer with id 5 on the active tree. If that layer doesn't exist, during the push information technology will be created. Similarly layers that no longer exist in the source tree are removed from the destination tree. This is all washed via the tree synchronization process.
Considering allocation of Layer(Impl)due south is expensive and virtually layer tree structures do not change from frame to frame, once a pending tree activates, it becomes the "recycle tree". This tree is never used for annihilation except for a enshroud of the last pending tree. This avoids allocation and property pushing work from master thread to pending tree. This is merely an optimization.
The reason the pending tree exists is that if in that location are multiple changes to webpage content in a single Javascript callstack (e.g. an html sail has a line fatigued on it, while a div moves, and some background-colour changes to bluish), these all must exist presented to the user atomically. Commit takes a snapshot of these changes and pushes them to the pending tree, so that Glimmer can continue to update the main thread tree for a hereafter commit. After commit, these changes need to be rastered, and all of that rasterization must be consummate earlier any of those new tiles can be presented to the user. The pending tree is the staging area to await until all of the asynchronous rasterization work is complete. While the pending tree is staging all the rasterization piece of work, the active tree can be updated with animations and scrolling to still be responsive to the user.
Unmarried-threaded versions of cc do non have a pending tree and commit direct to the active tree. (The recycle tree is unused in this mode.) This is an optimization to avoid extra work and copies. To work around this, the active tree is unable to be fatigued until its tiles are all set to draw. However, given that this is a single-threaded version of cc, at that place are no compositor thread animations or scrolling, and so in that location is little reason to demand to draw.
Raster and tile management
TileManager is responsible for rasterizing the world of tiles. Each PictureLayer provides a set of Tiles to rasterize, where each Tile is a subrectangle of painted content at a detail scale.
The TileManager finds all the tiles that are required to draw on the active tree, all the tiles that are required to actuate on the pending tree, less important tiles that are shut to the viewport only are not visible, and too offscreen images to decode.
There are currently three modes of raster in cc:
-
software raster: generate software bitmaps in the raster worker
-
gpu raster: generate gpu textures by sending gl commands over the control buffer
-
oop raster: generate gpu textures past sending paint commands over the command buffer
The TileManager is instructed to do software vs hardware raster based on whether the LayerTreeFrameSink that it uses to submit compositor frames on has a context provider or not. Information technology is e'er in one mode or the other. Switching modes destroys all resources. GPU raster is likewise currently deprecated and volition be replaced past OOP (out-of-process) raster in all cases eventually. A common reason for switching modes is that the gpu process has crashed too much and all of Chrome switches from gpu to software raster and compositing modes.
Once the TileManager decides the gear up of work to exercise, it generates a TaskGraph with dependencies and schedules that work across worker threads. TaskGraphs are not updated dynamically, but instead rescheduled every bit a whole graph. Tasks cannot be cancelled once they accept started running. Scheduled tasks that have not still started are cancelled by submitting some other graph that does not include them.
Prototype Decoding
Image decoding receives a lot of special intendance in the TileManager, as they are the most expensive part of raster, especially relative to comparatively speedy gpu raster. Each decode receives its own dependent task in the job graph. There is a separate decode cache for software raster vs gpu raster. The SoftwareImageDecodeCache manages decode, scale, and color correction, whereas the GpuImageDecodeCache too uploads those textures to the gpu procedure, storing them in gpu discardable memory.
cc also handles all animation of animated gifs in Chrome. When gifs breathing, they generate a new pending tree (initiated past the compositor thread instead of the main thread) with some raster invalidations and then re-raster tiles that are covered by that gif.
Raster Buffer Providers
Autonomously from software vs hardware raster modes, Chrome can also run in software vs hardware display compositing modes. Chrome never mixes software compositing with hardware raster, but the other three combinations of raster way x compositing manner are valid.
The compositing fashion affects the pick of RasterBufferProvider that cc provides, which manages the raster process and resource direction on the raster worker threads:
-
BitmapRasterBufferProvider: rasters software bitmaps for software compositing
-
OneCopyRasterBufferProvider: rasters software bitmaps for gpu compositing into shared memory, which are then uploaded in the gpu process
-
ZeroCopyRasterBufferProvider: rasters software bitmaps for gpu compositing directly into a GpuMemoryBuffer (east.g. IOSurface), which tin immediately be used by the brandish compositor
-
GpuRasterBufferProvider: rasters gpu textures for gpu compositing over a command buffer via gl (for gpu raster) or via paint commands (for oop raster)
Note, due to locks on the context, gpu and oop raster are limited to i worker thread at a time, although image decoding can proceed in parallel on other threads. This unmarried thread limitation is solved with a lock and not with thread affinity.
Blitheness
This directory implements an animation framework (used by LayerTreeHost(Impl) through the cc::MutatorHost interface). The framework supports keyframe based animations of transform lists, opacity, and filter lists which directly manipulate those values on the relevant TransformNode / EffectNode in the property tree (identified by ElementId).
An animation is represented by an instance of Animation which has i (or more in the futurity) KeyframeEffects, each of which has multiple KeyframeModels. Animation manages the play state, outset time, etc of an blitheness, KeyframeEffect represents a target chemical element of the blitheness, and each KeyframeModel describes the blitheness of a particular property (due east.one thousand. transform / opacity / filter) on that chemical element. An animation may either represent an embedder animation (due east.grand., a Blink animation of a transform property) or it can be an animation from cc itself (eastward.chiliad., a ringlet blitheness for polish scrolling).
LayerTreeHostImpl informs AnimationHost of new and removed elements, which in turn will update the state of animations which depend on those elements. It calls NeedsTickAnimations to know if more animation frames should be scheduled, and TickAnimations every frame to update animation timing, state, generate animation events, and update the bodily output value of holding tree nodes based on the animation.
cc/paint/
This directory stores a number of classes that represent painted content. They are extremely similar to Skia information structures, only are mutable, introspectable, and serializable in all cases. They too handle security concerns (e.thousand. TOCTOU problems serializing out of shared memory that a malicious renderer could exist manipulating every bit it is read by the gpu process) that Skia does not want to think about.
PaintRecord (aka PaintOpBuffer) is the SkPicture equivalent that stores a number of PaintOps. A PaintRecord tin can either be rasterized by a raster buffer provider into a bitmap or a gpu texture (when using software or gpu raster), or it can be serialized (when using oop raster).
PaintCanvas is the abstract grade to record paint commands. Information technology tin be backed by either a SkiaPaintCanvas (to go from paint ops to SkCanvas) or a PaintRecordCanvas (to plow paint ops into a recorded PaintRecord).
Scheduling
cc'southward actions are driven by a cc::Scheduler. This is one of many schedulers in Chrome, including the Blink scheduler, the viz::DisplayScheduler, the browser UI job scheduler, and the gpu scheduler.
The cc::Scheduler is owned by ProxyImpl (or SingleThreadProxy). It takes diverse inputs (visibility, brainstorm frame messages, needs redraw, set to draw, fix to activate, etc). These inputs drive the cc::SchedulerStateMachine, which then determines deportment for the SchedulerClient (LayerTreeHostImpl) to take, such every bit "Commit" or "ActivateSyncTree" or "PrepareTiles". These actions are generally expensive parts of the pipeline that we want to carefully rate limit or that have state-related dependencies.
cc::Scheduler lawmaking differentiates begin frames from the display compositor every bit BeginImplFrame (i.east. should cc produce a compositor frame) and a begin frame for its embedder every bit BeginMainFrame (i.e. should cc tell Blink to run requestAnimationFrame and produce a commit, or in the browser if should cc tell ui to exercise something like). The BeginImplFrame is driven by a viz::BeginFrameSource which in turn is driven the the brandish compositor.
In a full pipeline update with low latency and fast rasterization, the full general scheduling menses is BeginImplFrame -> BeginMainFrame -> Commit -> ReadyToActivate -> Activate -> ReadyToDraw -> Depict.
Additionally, if rasterization is slow, a second BeginMainFrame tin can be sent before activation, and it will cake in NotifyReadyToCommit until the activation completes, every bit the SchedulingStateMachine volition prevent the commit from starting while there is a pending tree that hasn't activated nevertheless. This allows the main thread to work on the side by side frame in parallel instead of sitting idle at the expense of latency. One hypothetical ordering of events with slow raster could be:
BeginImplFrame1 -> BeginMainFrame1 -> Commit1 -> (wearisome raster) -> BeginImplFrame2 -> BeginMainFrame2 -> ReadyToActivate1 -> Activate1 -> Commit2 -> ReadyToDraw1 -> Draw1.
The cc::Scheduler maintains a borderline past which it expects its embedder to answer. If the chief thread is tedious to respond, then the Scheduler may describe without waiting for a commit. If this happens, then Scheduler is considered to exist in high latency mode. If futurity frames start condign faster again, the scheduler tin endeavour to skip a BeginMainFrame in lodge to "catch up" and re-enter low latency mode. Loftier latency style trades off latency for throughput by increasing pipelining. Information technology maintains this distinction by keeping a history of times and trying to adjust with heuristics.
Compositor frames, render passes, quads
The output of cc is a compositor frame. A compositor frame consists of metadata (device scale, color space, size) and an ordered set of return passes. A render pass contains an ordered set of quads that take references to resource (eastward.g. gpu textures) and data about how to draw those resources (sizes, scales, texture coordinates, etc). A quad is a single rectangle on screen, and is what you see when composited layer borders are visualized. Layers themselves produce quads via derived AppendQuads function. This produces a set of quads that fill up (without overlapping or intersecting) the visible rect of the layer.
There are various types of quads that roughly correspond to different layer types (ContentDrawQuad, TextureDrawQuad, SolidColorDrawQuad). Because layers that produce many quads (i.e. PictureLayerImpl) produce many quads with the aforementioned info, SharedQuadState is an optimization that collects this shared information so that each private quad is slimmer. RenderSurfaceImpls are 1:one with return passes and exist mostly to provide the aforementioned AppendQuads logic that Layers do for their quads, in that RenderSurfaceImpl produces RenderPassDrawQuads.
A render pass exists to support composited effects (see: consequence tree). These can be cases where compositing is required to perform an issue. Information technology can besides be cases where doing compositing commencement can brand the effect easier to implement (because then it applies to a single render pass texture, instead of an arbitrary set of quads produced by some subtree of layers). Common cases for render passes are: masks, filters (e.1000. blur), clipping rotated layers, or opacity practical to a subtree of content.
Inside a compositor frame, render passes and the quads within a render pass are ordered. The render passes are a flattened listing that represent that dependency tree of return passes. If render pass 1 depends on render pass 9 (because information technology contains a RenderPassDrawQuad referencing the output of nine), so 9 will appear in the list before 1. Therefore, the root return laissez passer is ever last in the list. Inside a single render pass, the quads are ordered dorsum to forepart (Painter's algorithm).
In full general, quads are non considered to live in a 3d space (even if transformed by 3d transforms) and are yet drawn in order, on top of annihilation drawn before it. However, there is a mode where a set of quads tin be in a 3d context (caused past css transform-style: preserve-3d). A BSP tree is used to sort and intersect these against each other in the same 3d context.
Glossary
See: cc/README.md
Other Resources
For a listing of presentations, videos, and design docs, see: https://www.chromium.org/developers/pattern-documents/chromium-graphics
Miscellaneous Corner Cases That Don't Fit Anywhere Else, Sorry
Damage
Chrome has different notions of invalidation throughout the organisation. "Pigment invalidation" is portions of the document that demand to be repainted in Blink. "Raster invalidation" is parts of a layer that have changed and demand to exist re-rastered (possibly due to paint invalidation, just likewise synthetic invalidations such as the get-go fourth dimension a layer is rastered or when textures are thrown abroad and and then needed once again). Finally, damage is another discussion for "draw invalidation". It'south the office of the screen that needs to be redrawn.
At that place's two types of damage: invalidation harm and expose damage. Invalidation damage is due to raster invalidation, where a role of a texture has changed and the screen needs to exist updated. Expose damage is when a layer goes away, gets added for the first time, or gets reordered. There'due south no raster invalidation in these cases, just the screen even so needs to be updated.
cc calculates harm in the DamageTracker and forwards it along with a CompositorFrame. One reason impairment is needed in the brandish compositor is to do partial swap (where merely a portion of the screen is updated), which saves power. Another reason is when using hardware overlays, such that the display compositor can know that merely an overlay was damaged and not have to re-composite the residuum of the scene.
Mask Layers
Mask layers are layers used to implement a masking effect. They sit exterior the layer tree, without parents. They're owned past the layer the mask is applied to. They can be any type of layer bracket (e.g. PictureLayer or SolidColorLayer). Any time layers are iterated over, they are a special case that needs to be considered because they aren't role of the normal parent/kid tree. They get treated the same as other layers in terms of rasterization and tile management, although their AppendQuads function goes through RenderSurfaceImpl instead of in the pinnacle level iteration, because they are part of an effect and non a layer drawn on its own.
"Impl"
cc uses the "impl" suffix ...differently than the residuum of Chrome or other software engineers. In cc, "impl" ways that the form is used on the compositor thread and not on the main thread.
The historical reason for this is that at 1 point we had Layer on the master thread and nosotros needed an equivalent class to run on the compositor thread. jamesr@ consulted with nduca@ who made the very logical argument that things on the compositor thread were internal to the compositor and would really exist the implementation of the main thread version, and hence LayerImpl. Encounter: https://bugs.webkit.org/show_bug.cgi?id=55013#c5
Then if y'all need a tree of LayerImpls, you have LayerTreeImpl, and a identify to hang those trees is LayerTreeHostImpl. Suddenly, and then the "impl thread" was the thread where all the "impl classes" lived. If y'all're moving rasterization to the compositor thread, then suddenly that's called "impl-side painting".
Source: https://chromium.googlesource.com/chromium/src/+/master/docs/how_cc_works.md
0 Response to "How Chromium Construct Layer Tree Again"
Postar um comentário