Webview chromium v35 2dcanvas implementation process details, webviewchromium

Source: Internet
Author: User

Webview chromium v35 2dcanvas implementation process details, webviewchromium
Webview version chromium (same as android4.4webview chromium architecture) 2dcanvas implementation
It is very different from the native chromium (surfaceview solution. Below we will write down in detail in webview chromium
2dcanvas implementation scheme and a performance bottleneck on individual GPUs.
When creating a webkit, 2dcanvas will create a separate RenderLayer for it. When hardware rendering is enabled,
The backend storage corresponding to the RenderLayer of 2dcanvas is the TextureLayer in the cc module.
The TextureLayer corresponding to 2dcanvas is associated with the cc Layer Tree.
The specific painting operations that js calls through canvas. getContext ("2d") on the webpage are
It is not actually executed in DeferredPipeController of SkDeferredDevice.
The render thread starts the ThreadProxy: BeginMainFrame () process and calls the update of each Layer in the Layer Tree of cc in sequence.
For 2dcanvas, the update of texturelayer is called.
TextureLayer: Update () triggers Canvas2DLayerBridge: prepareMailbox ();
Canvas2DLayerBridge: prepareMailbox () completes all the key steps for drawing and synchronizing 2dcanvas.
In the webview version, chromium has only one merging thread on the screen. This merging thread uses the message_loop of the browser thread,
So the merging thread and the browser thread are actually the same.
The most fundamental difference between the rendering process of chromium and the native chromium version in webview is that
First, the webpage content is synthesized into the texture of off-screen, and then the texture of off-screen is synthesized into the framebuffer of on-screen.
The only merging thread in the webview version only performs merging on the screen. That is, the ThreadProxy: BeginMainFrame () process of the render thread is completed,
ThreadProxy: ScheduledActionDrawAndSwapIfPossible process starting from the merging thread (browser thread,
Directly render the webpage content to the on-screen framebuffer.
This is the previous rendering method. To be exact, it is only the solution used by android4.4. Android L is fundamentally different.
L's rendering mechanism is already very similar to native chromium.
Here we only talk about the implementation of 2dcanvas in the android4.4 solution.
For hard painting of 2dcanvas, there is a problem of texture synchronization between the render thread and the merging thread (browser thread.
This texture is first drawn in the render thread, stored in the rendering results, and then rendered to the on-screen framebuffer in the browser thread.
The render thread and the browser thread need to synchronize the cpu and gpu layers to coordinate the use of the shared resource texure.
Cpu-level synchronization is completed through SyncPoint.
Gpu-level synchronization is completed through GLFence.
First look at the cpu-level synchronization:
Canvas2DLayerBridge: prepareMailbox () after Canvas2DLayerBridge: flush () is called (),
Make all texture draw commands reach WebGraphicsContext3DInProcessCommandBufferImpl.
Note that it is not actually executed on the gpu yet.
Call m_canvas-> newImageSnapshot () to obtain the information of the drawn target texture and save it in the SkImage variable.
Canvas2DLayerBridge: prepareMailbox () then call webContext-> produceTextureCHROMIUM (). (This process does not know what the role is)
Canvas2DLayerBridge: prepareMailbox () then calls webContext-> insertSyncPoint () to synchronize the render thread and browser thread at the cpu level.
Check the wait Status of the browser thread on SyncPoint:
TextureLayer: Update () is used to encapsulate the mailbox that draws the texture information.
TextureLayer: PushPropertiesTo () passed the mailbox to TextureLayerImpl.
Call in TextureLayerImpl: WillDraw ()
ResourceProvider: CreateResourceFromTextureMailbox (). Save mailbox in
Resource created by ResourceProvider.
Called when the Browser thread is merged
GLRenderer: DrawRenderPassQuad ()
ScopedReadLockGL: ScopedReadLockGL () call
ResourceProvider: LockForRead ()
ResourceProvider: LockForRead () will call
Gl-> WaitSyncPointCHROMIUM (). At this point, we can see the synchronization between the render thread and the browser thread at the cpu level.
After the SyncPoint is signal in the render thread, the browser thread ResourceProvider: LockForRead () will execute
ConsumeTextureCHROMIUM (). Start to consume texture.
Next, let's look at gpu-level synchronization:
In the render thread, a texture may execute gl drawing commands for multiple times. Ensure that these gl drawing commands are
This texture is actually executed on the gpu before being used by the browser thread.
Gpu provides two Synchronization Methods: explicit glflush and implicit GLFence.
Therefore, when the render thread executes the texture painting operation, it changes the texture every time.
Insert a GLFence. browser thread where the texture location needs to be read and written will be wait
The GLFence created in the render thread. This achieves synchronization between the render thread and the browser thread on the gpu layer to a texture.
Location of glfence created in the browser thread wait render thread:
GLES2DecoderImpl: DoDrawElements ();
GLES2DecoderImpl: PrepareTexturesForRender ();
GLImageSync: WillUseTexImage ();
NativeImageBuffer: WillRead ();
In the render thread, draw the glfence created by texture:
GLES2DecoderImpl: DoDrawElements ();
ScopedRenderTo ::~ ScopedRenderTo ();
Framebuffer: OnDidRenderTo ();
TextureAttachment: OnDidRenderTo ();
Texture: OnDidModifyPixels ();
GLImageSync: DidModifyTexImage ();
NativeImageBuffer: DidWrite (gfx: GLImage * client );
Write_fence _. reset (gfx: GLFence: CreateWithoutFlush ());

There is a problem in the way the render thread and browser thread Synchronize on the gpu, which leads to a performance bottleneck in 2dcanvas on some GPUs.

The render thread may call the gl draw command multiple times for the same texture. In the 35 implementation scheme, after each gl draw command that changes texture,

Glfence. In fact, you only need to insert a glfence after the gl draw command of the last texture that changes the texture content. If

After changing the gl drawing command of texture, A glfence is inserted. On some GPUs, the process of creating and inserting glfence affects the next gldrawelement of the render thread.

The execution of this command takes too long, leading to the performance bottleneck of 2dcanvas. I think the idea of solving this bottleneck is how to create only one glfence at the right time of the render thread.

The difficulty lies in how to identify which of the draw commands called for a texture is the last to change the texture content. Or which of the following gods have ideas.

PS 1:

Canvas2DLayerBridge: prepareMailbox () calls Canvas2DLayerBridge: flush () to trigger

The draw command is transferred to the process in WebGraphicsContext3DInProcessCommandBufferImpl.
Canvas2DLayerBridge: prepareMailbox ();
Canvas2DLayerBridge: flush ();
SkCanvas: flush ();
SkDeferredDevice: flush ();

Void SkDeferredDevice: flush (){
This-> flushPendingCommands (kNormal_PlaybackMode );
FImmediateCanvas-> flush ();
}
1. the pending draw command in DeferredPipeController of SkDeferredDevice can be used
Run (drawBitmap ).
SkDeferredDevice: flushPendingCommands ();
DeferredPipeController: playback ()
SkGPipeReader: playback ()
SkGPipeRead. cpp: drawBitmapRect_rp ();
SkCanvas: drawBitmapRectToRect ();
SkCanvas: internalDrawBitmapRect ();
SkGpuDevice: drawBitmapRect ();
SkGpuDevice: drawBitmapCommon ();
SkGpuDevice: internalDrawBitmap ();
GrContext: drawRectToRect ();
GrDrawTarget: drawRect ();
GrInOrderDrawBuffer: onDrawRect ();
2. Run the draw command on texture to go to the process in WebGraphicsContext3DInProcessCommandBufferImpl.
SkDeferredDevice: flush ()
SkCanvas: flush ()
SkGpuDevice: flush ()
GrContext: resolveRenderTarget ()
GrContext: flush ()
GrInOrderDrawBuffer: flush ()
GrGpu: onDraw ()
GrGpuGL: onGpuDraw ()


PS 2:

The texture used by 2dcanvas uses the mailbox_synchronize mechanism for transmission in the browser thread and render thread.
Write down:
AwBrowserMainParts: PreMainMessageLoopRun ()
Initialize gpu: gles2: MailboxSynchronizer: Initialize (). If initialization fails, hardware rendering of 2dcanvas is disabled.
MailboxManager: MailboxManager () uses MailboxSynchronizer.
Class MailboxSynchronizer includes
Typedef std: map <Texture *, TextureVersion> TextureMap;
TextureMap textures _;
TextureVersion contains pai_ptr <TextureGroup> group;
Struct TextureGroup contains
TextureDefinition definition;
Std: set <TargetName> mailboxes;
TextureDefinition includes
Scoped_refptr <NativeImageBuffer> image_buffer _;
NativeImageBuffer inclusion
Struct ClientInfo {
ClientInfo (gfx: GLImage * client );
~ ClientInfo ();

Gfx: GLImage * client;
Bool needs_wait_before_read;
Performance_ptr <gfx: GLFence> read_fence;
};

Std: list <ClientInfo> client_infos _;
Scoped_ptr <gfx: GLFence> write_fence _;
Gfx: GLImage * write_client _;

Class GLImageSync: public gfx: GLImage;
GLImageSync contains scoped_refptr <NativeImageBuffer> buffer _;
All calls to GLImageSync are transferred to NativeImageBuffer.
In the constructor of TextureDefinition, NativeImageBuffer is created,
This NativeImageBuffer is subsequently set to GLImageSync.
This GLImageSync was subsequently set to Texture for building TextureDefinition.
GLImageSync registers with NativeImageBuffer through the AddClient of NativeImageBuffer.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.