2015년 3월 23일 월요일

How to Draw

As you know a drawing process is so complicated and huge.
So I will explain a drawing with 2 parts. A front would be a related constructing main classes, how to work them and a layout process.
And a behind would be a related compositing, tile managing and gl working.

=== Class Construction ===

When I began to investigate the Chromium, I mistaken that the Blink is the Render Process. Although they are not same, I thought most parts in the Render Process is the Blink. But it is not.
In the Render Process has many graphic codes related a rendering. They are not in the Blink. They are the Chromium side.
At first, I will explain the Chromium side. Because they are handle most realm in drawing parts. A start point is a RenderViewImpl creating. A RenderViewImpl is the Chromium side. It become one of confused element. Because in the Blink it has RenderView. But these the RenderView and the RenderViewImpl is totally different. In the blink the RenderView`s filename is "renderview.cpp" and in the Chromium is "render_view_impl.cc". And there behavior is also different. There differences would be explained later. When the RenderViewimpl is created, all related classes are created. Below picture shows a result.



In fact, the RenderView`s ancestor class is the RenderWidget. The RenderWidget create the RenderWidgetCompositor. From the RenderWidgetCompositor to the LayerTreeHostImpl each class have important roles.
The RenderWidgetCompositor handle between the LayerTreeHost and the LayerTreeHostImpl. The LayerTreeHost is more closed to the Blink. It handle a layout and software rendering. But the LayerTreeHostImpl is more close to the GL behavior. It handle the outersurface and gl calls. The Thread Proxy is look like a bridge between the LayerTreeHost and the LayerTreeHostImpl. It has the Scheduler. From the Shceduler`s scheduling, rendering processes are triggered. The Scheduler has several steps. They will be explained more detailed in next section. The LayerTreeHostImpl is closed to a hardware rendering. Green boxes in upper picture`s LayerTreeHostImpl  are initialized after special scheduling queue. It is explained next chapter. In conclusion, if you understand classes construction, it would be good for understanding whole a rendering process.

=== Scheduler ===

All rendering related jobs are trigger by the Scheduler. The Scheduler has own state machine and work by schedule state. When some action change schedule state condition, the Scheduler triggers target action. For example, if all layers are ready to show, the Scheduler receives "ACTION_DRAW_AND_SWAP_IF_POSSIBLE" state and calls "swapbuffer" to a outputsurface. This step is described in "Scheduler::ProcessScheduledActions()". You can see how it works. Below picture shows a state looping sequence.


* ACTION_BEGIN_OUTPUT_SURFACE_CREATION
In this step, the Layer Tree Host Impl create the CompositorOutputSurface. It is inherited class from the MailboxOutputSurface. In here tile jobs have work with a tile manager.. And call to the BrowserProcess to show buffers.
* ACTION_SEND_BEGIN_MAIN_FRAME
In this step, a layout task is performed. This step is more detailed in next section.
* ACTION_COMMIT
From the RenderLayerCompositor tree, the Layer Tree Impl create a layerimpl tree. It ready to draw.
* ACTION_PREPARE_TILES
In this step, needed tiles are created. If changed area is small, only matched coordinated tiles are destroyed and created.
* ACTION_ACTIVATE_SYNC_TREE
If partial update is needed, only parts of tree would be updated. This step sync it.
* ACTION_DRAW_AND_SWAP_IF_POSSIBLE
This step is an outputsurface job. Shortly a "swapBuffer" command is called in this step. This step will be explained in a next document.


=== Layout ===
A layout process is divided as 3 big parts. First creating RenderLayers. Second layout. Finally creating compositing information.
A layout job is triggered by "ACTION_SEND_BEGIN_MAIN_FRAME" state. Then FrameView start to layout process.
In the "FrameView::updateLayoutAndStyleForPainting" all layout tasks are done.




Upper picture shows a route path from the Scheduler to FrameView. In FrameView we can focus big 4 steps. But 4th path is just simple path, so I will skip it.
* creating RenderLayers
At first process, check document updating through "updateRenderTree". It check a dom tree recursive and check style updating. If some node is updated, then create the RenderLayer tree.
* layout
After creating RenderLayers, the FrameView call the layout. This task works in a RenderObject class family. In fact it works in the RenderBlock.
* updating compositing info
After layout, for accelerated compositing, many informations are needed to calcualte. It works in the RenderLayerCompositing. As we know if the Blink uses a compositing, it needs to create some special layers. "GraphicsLayer". The GraphicsLayer is metrial for root layer and other form layers of screen. A created root layer is registered in the RenderLayerCompositing and WebViewImpl. It is need to composite.
In contrasted with previous the "webkit", calculating compositing works in util class. Those are "CompositingInputsUpdater" and "CompositingRequirementsUpdater".


After upper three tasks, the GraphicsLayer calls setNeedsDisplayInRect. And the Scheduler trigger next step ACTION_COMMIT.
After this will explain next document.



An Upper picture shows all needed classes for rendering. Left side is more closed to the Layout, a right side of the RenderWidget is more closed to the Painting and the Drawing. The Painting is worked with sync trees and tiles. It also works with the Skia. The LayerTreeHostImpl is important class in the painting and the drawing. It handles all task related with the painting and drawing. 


=== Painting ===
The painting is began with "UpdateLayers" in the LayerTreeHost. With below picture, a painting is triggered in the PicturePile. In the PicturePile it calculates clip rect, set tiles and record pictures. The PictureLayer is a surface layer for painting. There are tiles on the PictureLayer, there are pictures on tiles.If you want to skip root layer painting, you can modify code in PictureLayer "update". The Painting logic is so complicated. I do not still understand totally.





=== Drawing ===
When a painting is finished, the Scheduler trigger a draw and a swap. As below picture shows that in the ThreadProxy::DrawSwapInternal, a drawing and a swapping are worked in same turn. At first, through DrawLayers in LayerTreeHostImpl, it draw texture on an outputSurface. This output surface has preserved when the Render Process created. At each drawing turn, output surface prepare again. But the MailboxOutputSurface preserve unique size textures and return pre-created texture when it needed. After returning backbuffer, renderer draw with render pass and quads on an output surface.




When a drawing on output surface is finished, a swap buffer is triggered. A swap buffer sequence is very simple. When an output surface`s texture created, it is delivered to the Browser Process. And EvasGL copies that texture to EvasGL texture.
It refreshing on user screen. This is a full sequence to draw.
In fact, some layout, painting`s detailed process is skipped. Because it is a very complicated, and need more investigation. I will update this article in more detailed.



댓글 없음:

댓글 쓰기