Android WebView Rendering
*
What is Android WebView?
Web content in a box:
The secret 6th Blink platform
- Same compile-time flags as Chrome for Android, but lots of runtime differences:
WebView version history
Android <= J: custom WebKit-based “classic” WebView
Android K: Chromium 30/33-based WebView
Android L: Unbundled evergreen WebView, autoupdated via Play Services
Use cases
When we started looking at how apps were actually using the WebView, we had some surprises...
Three Google email apps
GMail: All the emails in a thread are concatenated into a viewport-sized hardware WebView, with whitespace where the blue headers are. WebView handles scrolling and the app reads the scroll offset every frame to translate the headers.
<- Android View
<- Android View
WebView sized to screen
Three Google email apps
“Email”: document-sized hardware WebView. App handles scrolling by applying a hardware matrix to both WebView and blue headers.
WebView sized to size of document (entire thread of emails)
<- Android View
Three Google email apps
Inbox: One WebView per email. Custom RecycleView equivalent to avoid having more than ~3 active. No overlap between headers and WebView.
WebView 1
WebView 2
Pagination with three WebViews
Common pattern across news apps: one WebView per page, handles touch events in Java and applies View translation matrix to side-swipe. WebView itself mostly passive (may vertically scroll in “tab”-style use cases).
Page 1 Page 2 Page 3 Page 4 Page 5 Page 6 Page 7 ...
WebView WebView WebView
Pagination using software screenshots
Google Books: Each chapter is one giant WebView. Uses WebView.onDraw() with translation matrices to render individual pages into software bitmaps. Then uploads those into textures and does fancy page-turning using its own GL.
Page 1 Page 2 Page 3 Page 4 Page 5 Page 6 Page 7 ...
Screenshot
WebView (entirely offscreen)
Fun legacy WebView APIs
WebView.capturePicture(): Return a “Picture” object (Java wrapper around SkPicture) for the entire document.
WebView.setPictureListener(): Call this callback, providing a Picture object for the entire document, every time it changes.
APIs in View base class
View.onDraw(Canvas): Synchronously draw the view into an Java-wrapped SkCanvas. SkCanvas usually backed by a software bitmap. Cannot checkerboard, and an arbitrary matrix can be applied.
View.get/setScrollX/Y(): Synchronously set or read scroll offset.
View matrix setters: Synchronously translate/scale.
Android assumes all Views are quick and easy to redraw from scratch
Other types of Android Views tend to simple enough to regenerate from scratch on a single thread at 60fps.
Web content is complex enough that we have an async pipeline generating a tile cache instead.
An Android View is a bit like a RenderObject in Blink
Implication #1: Android decides our scroll offset and tells us at the last minute
Implication #2: Nothing can be async
If anything is async in the input or graphics pipeline, it would no longer work to write a Java method that synchronously:
1. Hands WebView a touch event
2. Reads the WebView’s scroll offset
3. Applies a matrix to another View relative to it
Implication #3: Always be ready for software draws
The implementation
(TLDR: clone classic Android WebView architecture by reshuffling Chromium components)
Threading model summary
Chrome
Multi-process
WebView
Single-process
Threading model summary
Android UI thread + Chrome renderer compositor thread
Android RenderThread
Renderer GL thread (WebGL/canvas/GPU raster)
Software raster thread
Blink main thread
Tiles
GL
EGL sharing
GL
DelegatedFrameData
Layer tree of SkPictures
System graphics components
Chrome
WebView
Merge CC impl thread and UI thread
Single-process
Android RenderThread + GPU thread
Canvas/WebGL thread
Blink and raster threads still separate
“Draw functor”
WebView software rendering
Scheduling differences
Where’s the code
android_webview/ : Upstream Chromium directory with most of the WebView code.
frameworks/webview: Android tree with WebView “glue” code for private APIs like draw functor.
content/browser/android/in_process/synchronous_compositor_output_surface.h : main interface between CC and android_webview/
The future of WebView?
Questions?
Contact the team at android-webview-dev@chromium.org
Extra slides
“Gralloc” zero-copy buffers
Hardware rendering initialization
Viewport model differences