Planet Chromium

July 21, 2014

Chromium Blog

Chrome 37 Beta: DirectWrite on Windows and the <dialog> element

Today’s Chrome Beta channel release includes a slew of new developer features to help you make richer, faster and more compelling web content and apps, especially for mobile devices. Unless otherwise noted, changes described below apply to Chrome for Android, Windows, Mac, Linux, and Chrome OS.

DirectWrite on Windows

Chrome 37 adds support for DirectWrite, an API on Windows for clear, high-quality text rendering even on high DPI displays. Before DirectWrite, Chrome used the Graphics Device Interface (GDI) to render text. GDI dates back to the mid-80's and reflects the engineering tradeoffs of that time, particularly for slower, lower-resolution machines. The switch to DirectWrite has been a top user request for years, and required extensive re-architecting and streamlining of Chrome's font rendering engine.

Some users should begin seeing better-looking fonts and increased rendering performance as we roll out DirectWrite, with no changes required by web developers. Assuming everything goes smoothly, all users will experience the improvements by the Chrome 37 stable release.

Compare the below screenshots, taken with and without DirectWrite enabled.



New HTML element: <dialog>

In this release we're also adding support for the <dialog> HTML5 element, which enables developers to create styled dialog boxes in their web applications and control them via a JavaScript API. For more details, check out some code samples and see <dialog> in action. The <dialog> element is a better-designed alternative to showModalDialog(), which is now disabled as we recently announced.

Other updates in this release

  • The Web Cryptography JavaScript API is enabled by default starting in Chrome 37, allowing developers to perform cryptographic operations such as hashing, signature generation/verification, and encryption.
  • Subpixel font scaling is now supported, which enables smooth animations of text between font sizes.  
  • TouchEvent co-ordinates are now doubles instead of longs, enabling higher-fidelity touch interactions on high-DPI displays.
  • CSS cursor values "zoom-in" and "zoom-out" are now unprefixed.
  • The number of cores on a physical machine can now be accessed by navigator.hardwareConcurrency.
  • The user's preferred languages are now accessible by navigator.languages, and the languagechange event is fired when this is updated.
  • The CSS Shapes Module allows developers to define non-rectangular text wrapping boundaries around floated elements.
  • NPAPI deprecation continues according to our previously-announced plan with a harder-to-bypass blocking UI
  • The default monospace font on Windows is now Consolas instead of Courier New.
As always, visit chromestatus.com/features for a complete overview of Chrome’s developer features,  and circle +Google Chrome Developers for more frequent updates!

Posted by Emil A Eklund, Software Engineer and Senior Blog DirectWriter



by Google Chrome Blog (noreply@blogger.com) at July 21, 2014 05:14 PM

Google Chrome Releases

Stable Channel Update for Chrome OS

The Stable channel has been updated to 36.0.1985.126 for the devices listed below:
  • 5841.73.0 for CR48, Acer AC700, Acer C7 C710, ASUS Chromebook C200, ASUS Chromebox, Lenovo N20 Chromebook, Lenovo Thinkpad 11e Chromebook, Lenovo X131e, LG Chromebase, Samsung Series 3 Chromebook, Samsung Series 5 Chromebook, Samsung Chromebook 2 (11"), Samsung Chromebook 2 (13"), and the New Samsung Chromebook
  • 5841.74.0 for the Acer C720, Dell Chromebook 11 for Education and the Toshiba Chromebook
  • 5841.76.0 for Google Pixel and the Samsung Series 5 550 Chromebook
. This build contains a number of bug fixes, security updates and feature enhancements. Systems will be receiving updates over the next several days.  Here is a list of Chromium changes.

Some highlights of these changes are:
  • Users can adjust time if their clock is out of sync and they have no network connection
  • The on-screen keyboard to support IMEs
  • We launched a touch-enabled window manager for Chrome OS available on select convertible devices
  • Supervised users: ability to import existing supervised users, and to set a new password from chrome.com/manage
  • If you have a touch-enabled device, you can now scale a webpage to zoom in on content via pinch to zoom

If you find new issues, please let us know by visiting our forum or filing a bug. Interested in switching channels? Find out how. You can submit feedback using ‘Report an issue...’ in the Chrome menu (3 horizontal bars in the upper right corner of the browser).

Ben Henry
Google Chrome

by Ben Henry (noreply@blogger.com) at July 21, 2014 03:52 PM

July 18, 2014

Google Chrome Releases

Beta Channel Update

The Chrome team is excited to announce the promotion of Chrome 37 to the beta channel with 37.0.2062.20 for Windows, Mac and Linux. (Chrome 64-bit for Windows will be coming to the beta channel shortly, stay tuned!)

This release contains many stability and developer improvements including:
  • DirectWrite support on Windows 
  • Redesigned "Save Password" UI
  • Automatic reload of unreachable pages when network becomes available 
  • Dropped Chrome sign-in requirement for Chrome Apps 
  • A number of new apps/extension APIs 
  • Lots of under the hood changes for stability and performance 

A full list of changes in this build is available in the SVN log. Interested in switching release channels? Find out how. If you find a new issue, please let us know by filing a bug.

Alex Mineer
Google Chrome

by Alex Mineer (noreply@blogger.com) at July 18, 2014 12:13 PM

July 17, 2014

Google Chrome Releases

Dev Channel Update

The dev channel has been updated to 38.0.2096.0 for Windows, Mac and Linux.

A full list of changes is available in the SVN log. Interested in switching release channels? Find out how. If you find a new issue, please let us know by filing a bug.

Matthew Yuan
Google Chrome

by matthewyuan@chromium.org (noreply@blogger.com) at July 17, 2014 06:58 PM

Beta Channel Update for Chrome OS

[EDIT: 7/17/2014]
The Beta channel has been updated to 36.0.1985.126 (Platform version: 5841.73.0) for all Chrome OS devices except the Google Pixel, the Samsung Series 5 550 Chromebook, the HP Chromebook 14, the Toshiba Chromebook, the Acer C720 and the Dell Chromebook 11 for Education.  The Google Pixel and the Samsung Series 5 550 Chromebook have been updated to 36.0.1985.126 (Platform: 5841.76.0) and the HP Chromebook 14, Toshiba Chromebook, Acer C720 and the Dell Chromebook 11 for Education have been updated to 36.0.1985.126 (Platform: 5841.74.0)

This build contains a number of bug fixes, security updates and feature enhancements. Here is a list of Chromium changes.

If you find new issues, please let us know by visiting our forum or filing a bug. Interested in switching channels? Find out how. You can submit feedback using ‘Report an issue...’ in the Chrome menu (3 horizontal bars in the upper right corner of the browser).

Ben Henry
Google Chrome

by Ben Henry (noreply@blogger.com) at July 17, 2014 06:03 PM

Chromium Blog

Chrome 36 Beta: element.animate(), HTML Imports, and Object.observe()

Today’s Chrome Beta channel release includes several new developer features to help you make richer, more compelling web content and apps, especially for mobile devices. Unless otherwise noted, changes described below apply to Chrome for Android, Windows, Mac, Linux, and Chrome OS.
element.animate()
The forthcoming Web Animations JavaScript API lets you animate web content from script. The element.animate() function included in today’s Beta is the first part of the API to ship in Chrome: it makes it possible to create simple CSS Animations using JavaScript. This means that animations can be dynamically generated without paying a CSS style recalculation cost. Animations created in this way are also cancelable and provide guaranteed end events (in contrast, CSS Transitions only generate events if they cause a style change). Here's an example of how you'd use it:
elem.animate([
{transform: 'translateX(0px)'},
{transform: 'translateX(100px)'}
], 3000);
HTML Imports
HTML Imports, part of the Web Components standards umbrella, offer a way to include HTML documents in other HTML documents using <link rel="import">:
<head>
<link rel="import" href="/path/to/imports/stuff.html">
</head>
An HTML Import can contain CSS, JavaScript, HTML, or anything else an .html file can include. This means they provide a convention for bundling related HTML/CSS/JS (even other HTML Imports) into a single package, making them a fantastic tool for delivering Web Components to users.
Data-binding with Object.observe()
Object.observe() lets you observe changes to JavaScript objects. You can define a callback that observes multiple objects and will receive all changes to any objects in a single asynchronous call. This is especially useful for framework authors implementing data-binding.
// Let's say we have a model with data
var model = {};

// Which we then observe
Object.observe(model, function(changes) {

// This asynchronous callback runs and aggregates changes
changes.forEach(function(change) {

// Letting us know what changed
console.log(change.type, change.name, change.oldValue);
});

});
Other updates in this release
  • Chrome no longer sends touchcancel on touch scroll, improving compatibility with other browsers and making it possible to add touch UI effects like pull-to-refresh without re-implementing scrolling and fling physics in JavaScript.
  • Some CSS properties such as scrollTop and offsetHeight will now return fractional values in browser-zoom situations.
  • The new WOFF 2.0 Web Font compression format offers a 30% average gain over WOFF 1.0 (up to 50%+ in some cases).
  • DevTools now faithfully emulates touch with mouse, allowing you to test touch interactions on Chrome for Android using the mobile emulation feature of DevTools.
  • Unprefixed CSS Transforms enables rich web content by allowing elements to be transformed in two-dimensional or three-dimensional space.
  • The will-change property allows developers to give a hint about which properties are about to change, which can help reduce delays at the beginning of animations in some cases.
As always, visit chromestatus.com/features for a complete overview of Chrome’s developer features, and circle +Google Chrome Developers for more frequent updates!
Posted by Shane Stephens and Doug Stockwell, Animated Software Engineers

by Google Chrome Blog (noreply@blogger.com) at July 17, 2014 09:55 AM

July 16, 2014

Google Chrome Releases

Stable Channel Update

The Chrome Team is excited to announce the promotion of Chrome 36 to the Stable channel for Windows, Mac and Linux. Chrome 36.0.1985.125 contains a number of fixes and improvements, including:
  • Rich Notifications Improvements 
  • An Updated Incognito / Guest NTP design
  • The addition of a Browser crash recovery bubble
  • Chrome App Launcher for Linux
  • Lots of under the hood changes for stability and performance

Security Fixes and Rewards

This update includes 26 security fixes. Below, we highlight fixes that were either contributed by external researchers or particularly interesting. Please see the Chromium security page for more information.

[$2000][380885] Medium CVE-2014-3160: Same-Origin-Policy bypass in SVG. Credit to Christian Schneider.

As usual, our ongoing internal security work responsible for a wide range of fixes:
  • [393765] CVE-2014-3162: Various fixes from internal audits, fuzzing and other initiatives.
Many of the above bugs were detected using AddressSanitizer.

Interested in switching release channels? Find out how. If you find a new issue, please let us know by filing a bug.

Matthew Yuan
Google Chrome

by matthewyuan@chromium.org (noreply@blogger.com) at July 16, 2014 04:41 PM

Chromium Blog

Disabling showModalDialog

The web platform has evolved organically over the past two decades, slowly growing new capabilities and APIs. Many features that are added are great ideas that enable web developers to make even better applications. But some APIs turn out, in retrospect, to be mistakes. Over time, the platform accretes more bad APIs, which makes it harder to add new browser features, confuses web developers, and even introduces security bugs. showModalDialog is a bad API that we deprecated earlier this year, and in Chrome 37 we will disable support for it by default.

showModalDialog was first introduced in Internet Explorer 4 and although it was never formally standardized, over time most other browsers added support for it. It allows applications to show a dialog of HTML content that freezes all other content while showing. showModalDialog is not a commonly used API: based on our usage counters, less than 0.006% of pages use it.

Unfortunately, showModalDialog's unique ability to freeze content is now widely regarded as a mis-feature in terms of user experience, code complexity, and security. From a usability perspective, showModalDialog rudely demands that you interact with it by freezing all of your other tabs—even ones from other sites. showModalDialog also requires complex and hard-to-maintain code scattered throughout the codebase. This complexity complicates the behavior of new web features like Mutation Observers, Object.observe, and Promises. It also makes showModalDialog a source of a disproportionate number of bugs, including serious security vulnerabilities. It is for these reasons that we decided to turn off showModalDialog by default in the next version of Chrome.

Although very few sites use showModalDialog, the small minority that do—disproportionately enterprise sites—have come to rely heavily on it. In order to give these sites more time to update, we have added a temporary Enterprise Policy setting to re-enable showModalDialog. In May 2015 this setting will be removed and showModalDialog will be completely removed from Chromium. Affected sites should begin work to update their sites as soon as possible.

Although it can be difficult, sometimes the only way to go forward is to leave the past behind. Removing bad APIs will help us make the web a more consistent and capable platform for both developers and users.

Posted by Adam Barth, Software Engineer

by Google Chrome Blog (noreply@blogger.com) at July 16, 2014 03:00 PM

Google Chrome Releases

Chrome for Android Update

The Chrome Team is excited to announce the stable release of Chrome 36 for Android. Chrome 36.0.1985.122 will be available in Google Play over the next few days. This release contains a number of new features including:
  • Improved text rendering on non-mobile optimized sites.
  • Doodles return to the new tab page.
  • Lots of bug fixes and performance improvements! 
Security fixes:
  • [$3000][352083] High CVE-2014-3159: Omnibox URL Spoofing (Android). Credit to Keita Haga.
  • [334204] Medium CVE-2014-3161: Same origin policy bypass (Android). Credit to Håvard Molland from Opera
A partial list of changes in this build is available in the SVN revision log. If you find a new issue, please let us know by filing a bug. More information about Chrome for Android is available on the Chrome site.

Jason Kersey
Google Chrome

by Jason Kersey (noreply@blogger.com) at July 16, 2014 02:08 PM

July 15, 2014

Google Chrome Releases

Beta Channel Update

The Beta Channel has been updated to 36.0.1985.125 for Windows and Linux

This release fixes a number of crashes and other bugs. A full list of changes is available in the SVN log. Interested in switching release channels? Find out how. If you find a new issue, please let us know by filing a bug.

*Update:  Mac has also been updated to 36.0.1985.125.

Matthew Yuan
Google Chrome

by matthewyuan@chromium.org (noreply@blogger.com) at July 15, 2014 05:04 PM

Dev Channel Update

The dev channel has been updated to 37.0.2062.20 for Windows, Mac and Linux.

A full list of changes is available in the SVN log. Interested in switching release channels? Find out how. If you find a new issue, please let us know by filing a bug.

Alex Mineer
Google Chrome

by Alex Mineer (noreply@blogger.com) at July 15, 2014 12:55 PM

Chrome for iOS Update

The Chrome team is excited to announce Chrome 36 for iPhone and iPad. Chrome 36.0.1985.49 contains a number of improvements including:
  • Allows mobile sites that have added Cast support to work with your Cast-enabled device. 
  • Stability improvements and bug fixes.
The update will be rolling out in the App Store over the next few hours. Known issues are available on the Chrome support site. If you find a new issue, please let us know by filing a bug.

Jason Kersey
Google Chrome

by Jason Kersey (noreply@blogger.com) at July 15, 2014 11:33 AM

July 09, 2014

Google Chrome Blog

Mirror Your Android Screen to the TV with Chromecast

Chromecast makes it easy for you to enjoy your favorite entertainment on the biggest screen in the house. Starting today, you can mirror your Android phone and tablet to the TV so you can see your favorite apps, photos or anything else, exactly as you see it on your mobile device—only bigger. To start mirroring, simply select “Cast Screen” from the navigation drawer in the Chromecast app and select your Chromecast device.  On Nexus devices, this feature is also available through the quick settings menu.

Now, anything on your Android device will appear on the TV. You can share photos stored on your phone with a group of friends, or scope out the scenery for your next family vacation together on the big screen using Google Earth.


This feature is currently in beta and will roll out on popular Android phones or tablets from Samsung, HTC, LG, and others over the next few days. Look out for the 1.7 update of the Chromecast app on Google Play store to use this new feature. 

Posted by Ambarish Kenghe, Chromecast Product Manager and Cast Master

by Google Chrome Blog (noreply@blogger.com) at July 09, 2014 01:00 PM

July 08, 2014

Google Chrome Releases

Flash Player Update

We are updating Flash Player to version 14.0.0.145 on Windows and Mac via our component update system (i.e. there will not be a Chrome update).

Release notes for the update can be found on Adobe's release notes page.

Karen Grunberg
Google Chrome

by Karen (noreply@blogger.com) at July 08, 2014 11:00 AM

July 04, 2014

Igalia Chromium

Eduardo Lima Mitev: A possibly faster approach to OpenGL rasterization of 2D Web content

Even thought it has been a while since my last entry on this blog, I have been quite busy. During most of last year I brought my modest contributions into an awesome startup that you have probably heard of by now, helping them integrate GNOME technologies into their products. I was lucky to join their team at an early stage of the development and participate in key discussions.

But more on that project on future entries.

Today I want to talk about things that keep me busy these days, and are of course related to Web engines. Specifically, I want to talk about 2D rasterization and the process of putting pixels on the screen as fast as possible (aka, the 60 frames-per-second holy grail). I want to discuss an idea that has the potential to significantly increase the performance of page rendering by utilizing modern GPU capabilities, OpenGL, and a bit of help from Web engines’ magic.

This is a technical article, so if you are not very familiar with 2D rasterization, OpenGL or how Web engines draw stuff, I recommended you to take some time off and read about it. It is truly a world of wonders (and sometimes pain).

Instanced rendering

The core of the idea is based on instanced rendering. It is a fairly well known technique introduced by OpenGL 3.1 and OpenGL-ES 3.0 as extension GL_EXT_draw_instanced.

To draw geometry with OpenGL, one normally submits a primitive to the rendering pipeline. The primitive consists of a collection of vertices, and a number of attributes per each vertex. Traditionally, you could only submit one primitive at a time.

With instanced rendering, it is possible to send several “instances” of the same primitive (the same collection of vertices and attributes) on a single call. This dramatically reduces the overhead of pipeline state changes and gives the GPU driver a better chance at optimizing rendering of instances of a particular geometry.

Hence, it is generally a common practice for OpenGL applications to group rendering of similar geometry into batches, and submit them to the pipeline all at once as instances. This technique is commonly known as batching and merging.

Skia, the 2D rasterizer used by the Chromium and Android projects, and Cairo, a popular 2D rasterizer backing many projects such as GNOME and previous versions of Mozilla Firefox; both to some extent have support for some sort of instanced rendering in their respective GL backends.

Telling instances apart

Ok, it is possible to draw a bunch of primitives at once, but how can we make them look different? A way of customizing individual instances is necessary, otherwise they will all render on top of the previous one. Not very useful.

There are two ways of submitting per-instance information: one is by adding a “divisor” to the buffers containing vertex or attribute information (VBOs), which will tell the pipeline to use the divided chunks as per-instance information instead of per-vertex. glVertexAttribDivisor is used in this case.

The other way is to upload the per-instance information to a buffer texture (or any texture for that matter) and fetch the information of the corresponding vertex by sampling, using a new variable gl_InstanceID available in shader code, as the key. This variable will increase for each instance of the geometry being rendered (as oppose to per vertex, for which you have gl_VertexID).

So, a quick recap so far. We are able to draw several instances of the same geometry at once, very efficiently, and are able to upload arbitrary data to customize each of these instances at will.

But wait, there are caveats.

The ordering problem

So, lets say we can now group together all drawing operations that involve the same primitive (rectangle, line, circle, etc). What happens if we draw (say) a filled rectangle, then a circle on top, and then another rectangle on top of the circle?

Following the simple grouping rule, what will happen is that the two rectangles will be grouped together and drawn first in one call, then the circle. This will not render the expected result, since the circle will end up laying on top of the rectangle that was drawn after it.

This problem is commonly known as “ordering”, and it clearly breaks our otherwise super-performing batching and merging case.

So, in scenes that involve lots of geometry overlapping, the grouping is limited to contents that do not overlap, if we wanted to preserve the right order of operations.

In practice, it means that we first need to separate the content in layers, then group the same primitives within a single layer, and finally submit the batches from each layer in the right order.

But guess what? Browser engines already do exactly that. Engines build a layer tree (among several other trees) with the information contained in the HTML and CSS content (layout, styling, transformations, etc), where the content is separated in render nodes whose content do not normally overlap. The actual process is much more complicated than that, but this simplification is enough to illustrate the idea.

Now, what if?

First, for the sake of presenting an idea, lets ignore the 2D context of a canvas element by now. More on that later. Lets focus on most of the web sites out there.

If we look at the number of primitives typically used by the rendering of a page, they boil down to a handful. Essentially, they are:

  • A rectangle: for almost all HTML elements, which are boxes. And character glyphs! which are normally rendered ahead of time and cached in a texture layout, then texture-mapped onto a rectangle. And images!, which are also texture-mapped onto rectangles.
  • A thin line: for thin (<=1 pixel) borders, inset/outset effect, hr, etc. Thicker borders can be drawn as thin rectangles.
  • A round corner: the quarter of a circle, filled or stroke, used to implement rounded rectangles (hello border-radius).
  • A circle: for bulleted listings, radio-buttons, etc. Argueably, these can be rendered using unicode characters, so no need for specific geometry.

Lets stay with these. There are other cases that I will purposely ignore, like one seen in a rounded rectangle with different thickness in two consecutive borders.

Then we have, for each of these primitives, an evolutionary-like variety of background styles (imaged, colored, repeated, gradient, etc); transformations (rotation, translation, scaling, etc); border styles (again imaged, colored, with different thickness, etc), shadow and blurring effects, and so on.

With a working texture cache, we have a potentially good chance at aggressively grouping together drawing of these primitives, like rectangles for example, for all text glyphs, boxes and images.

So, what if we could submit to a smart shader all the information that describes and tells apart these grouped instances? Is it possible to efficiently pack and then re-interpret in a shader all the styling and transformation complexities of today's CSS-styled HTML elements?

A new approach

Existing 2D rasterizers used in Web engines (at least Skia and Cairo, whose source code is available to me) are general purpose drawing libraries. That means they should render deterministically for any kind of application, not only Web engines. Specifically, they need to avoid the ordering problem explained above, where the result of a set of overlapped drawing operations is different if you change their order.

There are several reasons why modern Web engines use general purpose 2D rasterizers (as opposed to rasterizers written specifically for the needs of Web content rendering). One clear reason is that they existed before (in the case of Cairo at least) as a generic 2D graphics library, and was later used for Web rendering. Other reason is that the implementation of the Canvas 2D spec requires a general purpose 2D API, because that's what it is. And there is a clear benefit in reusing your beautifully optimized Canvas 2D implementation to draw the rest of the Web contents. Also, these libraries evolved from a pixmap (image) backed rendering target, into libraries exploiting the hardware-acceleration of GPU cards. Both libraries now feature an OpenGL(ES) backend that is somehow forced to comply with the previously existing API and behaviors.

But that is sub-optimal for Web engines that simply want to draw non-overlapping content into layers, then draw the layers in order. And even though batching and merging do occur in the GL backends today, it is apparently far from optimal as we will see later.


So, if we completely ignore the ordering problem for the case of Web engines drawing already layered nodes onto an OpenGL based render target, we might be able to aggressively group together potentially all the operations that share the same primitive.

This is of course if, as mentioned above, we are able to describe the particularities of each instance of these primitives, hand them down to a smart shader for rendering, then do all that efficiently so that the performance gained in batching is not lost by uploading tons of instance information to the GPU or running heavy shader code.

It is unclear (to me) whether this is at all possible. That's is why this approach is just an idea yet lacking validation for the real world. But it is a research that could potentially boost performance of Web content rendering.

It shares some similarities with (and was partially inspired by) the way Android does font rendering.

A proof of concept

So, I was set up to write a proof of concept trying to validate or discard the idea as quickly as possible. The purpose is to write the minimum code that would allow meaningful comparison between this approach and exiting rasterizers (Skia being my first target for this), for specific use cases that are relevant to generic Web content rendering (not Canvas 2D).

My proof of concept is being developed at: https://github.com/elima/glr

So far, it just provides a few primitives: rectangle and rounded corner, allowing for 3 basic drawing operations: rectangle (filled or stroked), rounded rectangle (only filled) and character glyph (not text, just single characters).

Then each element drawn can be transformed (scaled, rotated and/or translated), laid-out on the canvas (top, left, width and height), and has a color or texture.

Anti-aliasing is achieved by multisampling with 8 samples per pixel. Character glyphs are not anti-aliased, that was too complex to put in a proof of concept and it is a problem already solved by others anyway. I used the simplest possible path to put a pre-cached glyph on the screen, and for that wrote a super naive texture cache, and used FreeType2 for rasterizing the glyphs.
The idea of including chars was to explore if text glyphs, which accounts for most of typical Web page's content, could be batched together with all others drawings that use a rectangle primitive.

Note should be taken that this proof-of-concept is not intended to become a new library. It is just a vehicle to validate an idea by providing the minimum implementation needed to test its limits. Eventually, all this would have to be implemented in existing libraries. I just happen to be very fluent at glib and C :), as to prototype fast.

Comparisons

Before we jump into FPS excitements, lets clarify that any comparison here should be taken with a grain of salt. 2D rasterizers are complex libraries that do a lot of non-trivial things like anti-aliasing, sub-pixel alignment, color space conversion, adaptation to the specifics of the underlying hardware/driver/GL-version combos, to name just a few.

Thus, any comparison should be put in the context of what code paths are being selected, what rendering operations are being grouped, and when and why they aren't; how many GL operations are submitted to the pipeline to render the same scene, etc.

I have included 3 initial examples that try to illustrate how batching and merging of "compatible" draws (sharing the same underlying primitive) improves performance when ordering is ignored, while at the same time each element can have its own color, layout and transformation. For each example, I have written a Skia counterpart that tries to render exactly the same, to the extent possible, for the sake of comparing.

The data below corresponds to runs in my laptop, which is a Thinkpad T440p running Debian GNU/Linux, has an integrated Intel(tm) GPU (4th gen), and the OpenGL driver is provided by Mesa 10.2.1.

I used apitrace to look at what GL commands are actually sent to the driver.

Lets start with the RectsAndText example. It basically draws a lot of alternating filled rectangles and character glyphs, each with its own color, transformation and layout. In the screencast below, both examples (Skia and glr) are running at the same time. This of course does not reflect real performance since both compete for GPU resources, but I decided to record it this way because the improvement is much better noticed. The frames-per-second decrease proportionally for both examples when run at the same time, so it remains relevant for comparison.

The window in the left corresponds to the Skia example, and the right to glr. The same goes for all screencasts below.



This video file is also available for download.

The difference is considerable. Skia performs at an average of 6-7 FPS while the new approach gives around 40 FPS. That’s a 5x-6x improvement, not bad. Also, notice that CPU usage is considerably higher in the case of Skia.

The interesting thing here is that in the case of glr, all elements are batched together (both rectangles and chars), so only one drawing operation is actually submitted to the pipeline, as you can see in the available apitrace dump. A trace for the corresponding Skia example is also available.



apitrace output for RectAndText glr example



apitrace output for RectAndText Skia example

The next example is Rects, which is similar but renders only rectangles, alternating between filled and stroked. The interesting bit is that in the case of glr, each style of rectangles is drawn onto one different layer, each layer operating on its own separate thread; demonstrating that parallelism is now possible during batching.



This video file is available for download.

In this example, the performance difference is even higher. glr is around 8x faster. Again, apitrace traces for the glr example and the Skia version are available. This time glr submits a total of 2 instanced drawing operations, one for filled rects and one for stroked.



apitrace output for Rects glr example



apitrace output for Rects Skia example

The last example draws several layers of non-overlapping rounded rectangles. As with previous examples, every element is given a unique layout, color and transformation. This example tries to illustrate that because batching operates only at layer level, the more layers you have the less you benefit from this technique. In this particular example, the gap is reduced considerably. In fact it looks like Skia is faster by a few FPS, but it is actually not true. When both examples are run together, Skia is faster, but if run separately, glr example is faster (though not much). I’m still figuring this out.



This video file is available for download.

And the traces for the glr example and the Skia example.



apitrace output for Layers glr example



apitrace output for Layers Skia example


If you are curious about the implementation, take a look at where most of the magic happens: GlrContext, GlrCanvas and GlrBatch objects, and the vertex shader. The rest of the code is mostly API and glue to provide a coherent way to use this approach. Specifically, an abstract concept of "layer" is introduced. The workflow goes this way:

  • For initialization, a context, a rendering target and a canvas object are created. This is similar to how other 2D libraries work.
  • In the rendering loop and for each frame, the canvas is first notified that a new frame will be rendered.
  • Then any number of layer objects are created and attached to the canvas. The drawing API works against a layer (instead of a canvas), and will group and batch all the drawing operations in internal commands. When drawing to a layer finishes, the layer is notified that it is ready.
  • Finally, the canvas is requested to finish the frame, right before swapping buffers. This call will wait for all the attached layers to finish (blocking if needed). Once all complete, the canvas will take the batched commands from each layer, in the order they were attached, and submit them to the pipeline for rendering.

One thing to remark is that layers are self-contained stateful objects, and can survive frames without needing to redraw.

Other benefits

One by-product derived from the fact that layers cache drawing operations in internal commands (which in turn use locally allocated buffers), is that layers now become data-parallel. This is a term rarely used in the context of OpenGL because as you probably know, the way its API is designed makes it a giant state machine, making any parallelization unpractical.

With this approach, layers can be drawn in separated threads (or fully moved to OpenCL), which can bring extra performance if there are several complex layers that need drawing at the same time.

Another potential extra benefit comes from the fact that the canvas renders to a target that is actually a framebuffer backed up by a multisample texture. This means we can use any previously rendered frame as a texture, the same way it currently works in both Chromium and Webkit, where layers are texture-mapped then composited into the final scene.

So, we have the flexibility that, if a particular layer is too complex or slow to draw, we can attach it alone to a canvas, render it, and use the texture as with the current model. But, if we are short on texture memory, it is possible to keep commands batched in layers and render them on every frame. This is kind of similar to what Chromium does, recording draw operations into an SkPicture and then re-playing back when needed.

Future work

This is an approach that needs validation for a number of real world use cases before it can be even considered for testing on a Web engine. It is key to explore how complex information (for example, multi-step gradient backgrounds, or complex border styling with rounded rectangles) can be passed to the shaders and rendered correctly and efficiently. Also, there are shadows and blurring effects, all parametrized to cover the most creative use cases, that also need verification against this model.

Basically, we need to understand the limits of the approach by trying to implement modern W3C specs, selecting the most complex features first.

Other important priorities are:

  • Understand how much workload can be imposed on shaders side before the gained performance starts to degrade.
  • Test on OpenGL-ES and constrained GPU on embedded ARM, to detect the minimum requirements.
  • Figure out how to implement a mid-frame flushing mechanism when texture cache exhausts or command buffers get too large. This is not trivial, since to flush a layer (that is possibly running in a separate thread) it has to be blocked, then the canvas has to wait for all layers below it to finish and then execute their commands, then signal the blocked layer to continue.
  • Try how scrolling would behave if previously batched layers are drawn for every frame, instead of using current scrolling techniques that rely on rolling big textures, or moving several tiles up and down. These techniques impose either great pressure on texture memory, or a lot of complexity on tile management (or both), specially in the context of new super-high resolution screens.

Conclusions and final words

I have tried to detail an idea that although not new, I believe has not been explored in full in the context of Web engines. It relies on two essential hypothesis:

  • That it is possible to batch not only geometry, but the complex attributes of arbitrarily styled HTML elements, and render that geometry as instances using shader code.
  • It is safe to ignore ordering of draw operations during rasterization phase, and leverage on Web engine’s layer tree to solve overlapping.

Modern GPUs and OpenGL APIs have great potential for optimizing 2D rasterization, but as it happens most of the times, there is no one solution to fit all. Instead, each particular application and use case requires a different set of strategies and trade-offs for optimum performance.

This approach, even if valid for a sufficient number of use cases is unlikely to go faster than existing approaches for all tests cases. Even less replace these approaches. This is pretty clear in the case of canvas 2D for example, which will continue to require a general purpose rasterizer. But if there is a sufficient number of use cases that would benefit from this approach to some degree, then maintaining one code path that enables it will already be a win.

Finally, I want to thank Samsung SRA for partially sponsoring the time I dedicated to pursue this idea, and also Igalia and igalians which are always there to back me up and help me move forward.

Now, is there anyone interested in helping me explore this idea further?

by elima at July 04, 2014 08:28 AM

July 02, 2014

Chromium Blog

Migrate Your Legacy Packaged Apps to Chrome Apps

In 2010, we created packaged apps to fill a missing link between extensions and hosted apps. They look the same as a hosted app to the user, but under the covers, they are more like traditional extensions. Over time, we realized that a clearer separation between the Chrome browser and apps was necessary, both for security reasons and to conform to user expectations. We launched the next generation of Chrome Apps, a new version of packaged apps, last year to address those issues, and today we're announcing the deprecation of legacy packaged apps.

Starting today, no new legacy packaged apps can be published in the Chrome Web Store. In December, all existing legacy packaged app listings will be removed from Chrome Web Store’s search and browse functions. Existing legacy packaged apps can be updated until Chrome stops loading them in June of 2015. Nothing will change for hosted apps or new packaged apps.

Developers are strongly encouraged to migrate their legacy packaged apps to either Chrome Apps or extensions. To get started, check out our migration tutorial, and contact us on the chromium-apps forum or our G+ page with any questions.

Posted by Amanda Bishop, Product Manager

by Google Chrome Blog (noreply@blogger.com) at July 02, 2014 01:25 PM