Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
429 views
in Technique[技术] by (71.8m points)

jquery - Test if Hardware Acceleration has been enabled for a CSS animation?

How can I tell (for testing purposes) if Hardware Acceleration has been enabled for a CSS animation?

I have the following code which essentially enlarges an element and makes it fullscreen (without using the HTML5 fullscreen API). It runs like a stuttering asthmatic tortoise on most mobiles when using a jQuery animation so I have used CSS3 instead.

Here is the jsFiddle example:

$("#makeFullscreen").on("click", function() {        

    var map = $("#map"),
        mapTop = map.offset().top,
        mapLeft = map.offset().left;
    
    $("#map").css({
        "position": "fixed",
        "top": mapTop,
        "left": mapLeft,
        "width": map.outerWidth(true),
        "height": map.outerHeight(true)
    });
    
    setTimeout(function(){map.addClass("fullscreen")},1);
    
    return false;        
});
.mapContainer {    
    width: 150px;
    height: 200px;
    position: relative;
    margin: 0 auto;
}

.map {  
    background: #00f;
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    text-align: center;
}
.fullscreen {
    -webkit-transition: top 300ms ease-out, height 300ms ease-out, left 300ms ease-out, width 300ms ease-out;
    -moz-transition: top 300ms ease-out, height 300ms ease-out, left 300ms ease-out, width 300ms ease-out;
    -ms-transition: top 300ms ease-out, height 300ms ease-out, left 300ms ease-out, width 300ms ease-out;
    -o-transition: top 300ms ease-out, height 300ms ease-out, left 300ms ease-out, width 300ms ease-out;
    transition: top 300ms ease-out, height 300ms ease-out, left 300ms ease-out, width 300ms ease-out;
    
    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    -ms-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    
    top: 0 !important;
    left: 0 !important;
width: 100% !important;
height: 100% !important;
}

#makeFullscreen {
    margin-top: 20px;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mapContainer">
    <div id="map" class="map">
        <button id="makeFullscreen">Make Fullscreen</button> 
    </div>
</div>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Overview

A CSS property transition on an element is hardware-accelerated if all these conditions are met:

  1. Hardware-accelerated layer compositing is enabled in the browser
  2. The CSS property being transitioned is acceleratable
  3. The element has been given its own compositing layer

Generally, the requirements for these conditions are:

  1. The relevant hardware-acceleration options must be enabled, and the device's GPU and graphics drivers must not be blacklisted
  2. Only compositing CSS properties (opacity, transform: translate / scale / rotate, etc) are acceleratable
  3. Each browser has specific reasons for deciding whether to give an element its own compositing layer (or it can be forced by using a "go faster" hack like transform: translate3d)

Hardware-accelerated layer compositing

To identify whether this is enabled:

Chrome

1. General acceleration

  • Go to chrome://settings
  • Click the + Show advanced settings button
  • In the System section, inspect the status of the Use hardware acceleration when available checkbox

If acceleration is enabled, then:

2. Accelerated compositing

  • Go to chrome://gpu
  • In the Graphics Feature Status section, inspect the value of Compositing. This will be one of the following:
    • Hardware accelerated
    • Software only, hardware acceleration unavailable

More details on the Software Compositor from the docs:

In some situations hardware compositing is infeasible, e.g. if the device's graphics drivers are blacklisted or the device lacks a GPU entirely. For these situations is an alternative implementation to the GL renderer called the SoftwareRenderer

(Note: Chrome also has a Legacy Software Rendering Path, which is "still lingering as of May 2014, but will soon be removed entirely in Blink.")

Here's a great article with more info: Accelerated Rendering in Chrome.

Firefox

1. General acceleration

  • Go to Firefox's Preferences
  • Go to the Advanced tab
  • Go to the General subtab
  • Inspect the status of the Use hardware acceleration when available checkbox

If acceleration is enabled, then:

2. Layer acceleration

  • Go to about:config
  • Search for layers.acceleration.disabled

If layer acceleration is enabled (if the value is false), then:

3. GPU accelerated windows

  • Go to about:support
  • In the Graphics section, inspect the value of GPU Accelerated Windows

If it does not begin with 0/, and a rendering API is shown (eg. OpenGL, Direct3D), then GPU acceleration is active.

Safari

  • Enable Safari's debug menu by running this command in the Terminal:
    defaults write com.apple.Safari IncludeInternalDebugMenu 1
  • Open (or restart) Safari
  • In Safari's Debug menu, inspect the status of the Disable Accelerated Compositing option in the Drawing/Compositing Flags submenu

Acceleratable CSS properties

The only CSS property transitions which can be hardware-accelerated are those which occur in the compositing stage of the rendering process. For example:

To fully benefit from acceleration, no non-compositing properties must be transitioned. For example:

  • A transition on just transform: translate can receive the full benefit of acceleration (because the element's layer can simply be recomposited by the GPU).
  • A transition on both transform: translate and width will receive almost no benefit from acceleration (because a transition on width causes the element's layer to be repainted by the CPU for every animation frame).

Compositing layers & coloured borders

The browser's rendering engine decides (based on user preferences, CSS styles, etc) whether or not to give an element its own compositing layer.

For example, Chrome has this list of reasons, and also has this option in chrome://flags:

Compositing for RenderLayers with transitions
Enabling this option will make RenderLayers with a transition on opacity, transform or filter have their own composited layer.

If an element has not been given its own layer, then no CSS transitions on that element will be accelerated.

transform: translate3d (the "go faster" hack) generally forces an element to be given its own layer.

But even if an element has been given its own layer, transitions on non-compositing properties (width, height, left, top, etc) still cannot be accelerated, because they occur before the compositing stage (eg. in the layout or paint stages). @ChrisSpittles This is why you saw no visual improvement after adding transform: translate3d.

Most browsers can display coloured borders around composited layers, to make them easy to identify for development/debugging:

Chrome

Displaying the borders of composited layers can be done in one of two ways:

  • For all pages — Go to chrome://flags and enable Composited render layer borders ("Renders a border around composited Render Layers to help debug and study layer compositing"). You'll need to relaunch Chrome for this to take effect.
  • For individual pages — Open the Developer Tools, then open the Drawer, select the Rendering tab, and enable Show composited layer borders. Now, opening the Developer Tools on any page will cause layer borders to be shown on that page.

Now trigger the CSS transition on the element. If it has a coloured border, then it has its own compositing layer.

The border colours and their meanings are defined in debug_colors.cc. More details here and here.

Firefox

To draw the borders of composited layers:

  • Go to about:config
  • Search for layers.draw-borders and enable it

Now trigger the CSS transition on the element. If it has a coloured border, then it has its own compositing layer.

The border colours and their meanings are defined in Compositor::DrawDiagnosticsInternal.

Safari

(This does not work for me with Safari 7.0.3, but it seems it did work for some people as recently as last year.)

Launch Safari from the Terminal with the CA_COLOR_OPAQUE boolean environment variable set:

$ CA_COLOR_OPAQUE=1 /Applications/Safari.app/Contents/MacOS/Safari

Alternative method:

$ export CA_COLOR_OPAQUE=1 
$ /Applications/Safari.app/Contents/MacOS/Safari

Apparently, hardware-accelerated layers should be coloured red. More details here and here.

Update:

Here's an alternative method which works for me in Safari 7.0.3 (credit to David Calhoun):

  • In Safari's Debug menu, enable Show Compositing Borders in the Drawing/Compositing Flags submenu

Now trigger the


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...