我们知道,在childcompositor里,implthread里,pendingtree被raster之后,才会被activate成activetree. 而且raster任务由一些rasterthread执行,那么这些raster操作干了什么?
看看这篇chromium的官方英文文章:
https://www.chromium.org/developers/design-documents/impl-side-painting
引入了impl-sidepainting之后,raster操作从webcore线程挪到了impl线程,impl线程安排rastertask让rasterthread去真正执行。webcore线程绘制到skpicture里面。里面都是displaylist. 并且划分了picturepile,针对一个layer,划分成多个tile,每个tile有不同的位置,优先级,还有不同的resolution.impl线程针对tile排序,产生rastertask让raster线程去操作。
绘制的结果产生texture,通过sharedmemory供给gpumemory.
impl 线程合成时,根据resourceid, (textureid)来检查该tile对应texture是否已经在gpu中了,而后可以合成。
1.30.1 Multithreaded Rasterization
crbug.com/169282,andhttps://code.google.com/p/chromium/issues/list?q=label:Cr-Internals-Compositing-Rasterization Thisfeature is referred to as "multithreaded painting" and"impl-side painting" in some forums. Background& Problem Statement
TheExcessive Checkerboarding Problem A lot of our unwanted checkerboarding comes from invalidatesgetting intermixed with "requests" from the implthread to fill in missing tiles. In the current architecture, wecan only rasterize tiles on the main thread, using webkit'srendering data structures. If webkit's rendering tree iscompletely unchanged, then the page scrolls, all therasterization requests that go to the main thread are easilysatisifed by webkit. However, any time javascript changes the rendering tree, we havethe following problem: we have some "newly exposed tiles"that the compositor thread needs to prevent checkerboarding.But, annoyingly, any of the previously-painted tiles that webkitsays were invalidated. We can only paint the new rendering tree-- the old rendering tree is gone. So, we have two options atthis point: 1.Draw the new tiles with the new rendering tree, and redraw theold tiles with the new rendering tree 2.Draw only the new tiles, and let the old tiles stick around.
#2doesn't work well at all, of course: if you have a page thattoggles between green and blue constantly, what you'd see is arandom mix of green and blue page at any given moment. We wantto preserve the "atomicity of rendering" --- meaningthat the complete state of a web page at rAF time is what getsput on the screen.
Thereis a variant on 2 where we draw the new tiles, as well as anyold tiles that are *onscreen*. If a tile is offscreen, then wemake a note that is is invalid, but dont repaint it. In thegreen-blue scenario, this causes the screen to be green or blue,but never both, as long as you dont scroll. We ship thison Chrome Android m18. Even so, this is undesirable: if youscroll, you'll see a mix of content. This is expedientperformance wise, but makes us all feel dirty.
Our other source of heavy checkerboarding is latency related.The work we do on the main thread is based on as scroll positionupdate message that comes from the impl thread. This message isitself not very latent, arriving on the main thread millisecondsafter it is sent. However, paints for a new set of tiles cantake 300ms + to complete, even with the relaxed atomicityapproach described above. By the time we have painted all 300msworth of work, the page has scrolled way past the originalscroll position, and half of the tiles we worked hard to prepareare irrelevant. We have discussed a variety of solutions here,but the real core problem is that the main thread cannot beupdated fast enough with the new scroll positions to really everkeep up properly.
Displaylists. Namely, SkPictures,modified a bit to support partial updating. We call this aPicturepile,a name borrowed from the awesome folks behind Android Browser.Theidea is to only capture a display list of the webkit renderingtree on the main thread. Then, do rasterization on the implthread, which is much more responsive. Onmain thread, web content is turned into PictureLayers. Picturelayers make a recording of the layer into a PicturePile.We track invalidations in SkRegions and during the display listcapture process, decide between re-capturing the entire layer orjust grabbing the invalidated area and drawing it on-top of thepreviously recorded base layer. Duringcommit, we pass these PicturePiles to aPictureLayerImpl. Recall,layers can change in scale over time, under animation, pinchzoom, etc. To handle this, a PictureLayerImpl manages one ormore PictureLayerTiling objects (via a PictureLayerTilingSet),which is a decomposition of the layer's entire contents intotiles at a picture screenspace resolution. So for example, a512x512 layer might have a tiling into 4 256x256 tiles for a 1:1ratio of screenspace pixels to content pixels, but also 1256x256 tile for a 1:2 ratio of screenspace to conten space.We manage these tilings dyanmically. 一个layer可能被分成不同scale级别的tile.
A tiling itself takes thelayers entire size, not just the visible part, and breaks it upinto Tiles. Each tile represents a rectangle of the PicturePilepainted into a Resource ID [think, GL texture], at a givenresolution and quality setting. Everytile is given a set of TilePriority values by thePictureLayerImpl based on its screen space position, animationand scroll velocity, and picture contents. Thesedifferent priorities encode how soon, in time units, the tilecould be visually useful onscreen. Key metrics are things like"how soon will it be visible" and "how soon willit be crisp" and "is this a tile we'd use if a crispone wasn't available?"
TheseTiles are registered to the TileManager, which keeps these tilessorted based on their priority and some global priority states.Tiles are binned in orders of urgency (needed now, needed in thenext second, needed eventually, never going to be needed) andthen sorted within their bin.The total GPU Memory budget is then assigned in decreasingpriority order to these tiles. Tiles that are given permissionto use memory are then added to a rasterization queue if needed. tile都有优先级排序,根据优先级决定是否给一个tile分配gpumemory.
Theraster thread scheduler is a very simple solution: on the implthread, we simply pop from the |