(轉載)瞭解Android 4.1,之三:黃油項目 —— 運做機理及新鮮玩意

 

Welcome back to GTKA, everyone's favorite investigative series where we learn all about the newest version of Android (with a heavy emphasis on "all"). The previous two episodes, if you didn't catch them, are here and here.

歡迎回到人見人愛的《瞭解Android》系列文章。從這個系列中,咱們會了解Android新版本的全部(注意,是全部喔!)內容。若是你還沒看過以前兩篇的話,它們在這裏和這裏。android

Today we'll be doing something a little different and looking at something near and dear to everyone's hearts: performance. Jelly Bean is crazy fast. Slap it on a Galaxy Nexus and it'll feel like a brand new phone. Scrolling is faster and smoother, and the touch response is hyper-sensitive. In addition to all the smoothness work, there are new transitions all over the place.

今天,咱們要關注一些跟之前不一樣的內容,更貼近咱們需求的東西:性能! Jelly Bean快的很瘋狂啊!把它搞到一部Galaxy Nexus裏,你會感受好像拿了一臺新手機同樣。捲動是那麼的迅速順暢、而觸摸響應是那麼的敏感。此外,還多了不少動畫效果! web

I'm sure you've all seen a sweeping overview of this, but those are boring. What exactly is new, and how did they do it? That's what we're here to figure out. So, grab your popcorn, kids; it's time to learn all about Project Butter.     How They Did It

我知道大家已經看過一些關於這個的說明,但它們寫的都弱透了。到底哪些是新的,而它們又是如何作到的?咱們立刻就能搞清這些。好,抓上你的爆米花,孩子;咱們來了解一下傳說中的「黃油項目」吧。他們是怎麼幹的app

So how do you make an 8 month old Galaxy Nexus run like a Galaxy S III? Lots of hard work. Hard work that was thoughtfully detailed to us at Google I/O by two of my favorite I/O presenters, Chet Haase and Romain Guy. An hour long PowerPoint presentation geared towards developers is not the most accessible thing in the world, so I'm going steal some slides and try to cover the more interesting parts, and (hopefully) condense it down to a few minutes. Doesn't that sound like fun?     VSync Turns Frame Drawing Into A Well-Oiled Machine

怎麼才能讓一部壽命已達八個月的老Galaxy Nexus跑的好似Galaxy S III同樣呢?嗯,這須要不少努力。在Google I/O上,我最愛的兩個I/O演講者——Chet Haase 和Romain Guy爲咱們詳細闡述了這些努力。長達一個小時的PPT演示着眼於說明開發者是怎樣一羣不容於世的存在,因此我乾脆偷出一些包含有趣內容的頁面,把它們壓縮到幾分鐘內(但願如此),聽起來很爽吧?垂直同步爲幀繪製加油less

_0006_Layer-2 _0007_Layer-1

_0006_Layer-2_0007_Layer-1

 

PC Gamers are probably familiar with the term "VSync." It's that graphics option checkbox that will stop your screen from tearing in a video game.

PC遊戲玩家大概對垂直同步這個詞很熟悉了。包含這個詞的鉤選框能夠幫助你的遊戲避免畫面撕裂的問題。 ide

To understand what exactly VSync is, we're going to need a quick display primer: Video (ie a phone display doing stuff) is made of individual pictures called "frames." Smooth animation is usually 60 frames per second. Frames are made of pixels, and, when the display draws a frame, the pixels are filled in row by row. Got it? Good.

爲了理解垂直同步究竟是個什麼東西,咱們須要對顯示系統作一個新手教學:視象(好比說手機屏幕顯示的東西)是由一系列叫作「幀」的獨立圖片所組成的。平滑的動畫通常須要每秒六十幀。而幀是由像素點構成的。當屏幕繪製一幀的時候,像素點是一行一行的進行填充的。明白?很好。性能

The display (LCD, AMOLED, whatever) gets each frame from the graphics chip, and starts drawing it line by line. Ideally, you want the display to get a new frame from the graphics chip after it is finished drawing the previous frame. Tearing occurs when the graphics chip loads a new frame in the middle of the LCD draw, so you get half of one frame and half of another.

顯示屏(LCD,AMOLED或者別的什麼)從圖形芯片獲取每幀的數據,而後一行一行的進行繪製。理想情況下,你指望顯示屏在繪製完一幀以後,圖形芯片整好能提供新幀的數據。圖像撕裂的情況就發生在圖形芯片在圖像繪製到一半的時候,就載入了新一幀的數據,以至你最終獲得的數據幀是半個幀的新數據和半個幀的老數據。 動畫

VSync, well, synchronizes things. It tells the GPU to wait for the screen to finish its line by line drawing before loading the next frame.

而垂直同步,顧名思義,就是用來同步的。它告知GPU在載入新幀以前,要等待屏幕繪製完成前一幀。 ui

Android has always used VSync to stop screen tearing, but Jelly Bean takes things a step further. The VSync pulse is now used to start all the processing for the next frame.

Android一直使用垂直同步來避免屏幕撕裂。而Jelly Bean更進一步。垂直同步脈衝如今會貫穿於全部的圖形運做過程。 this

Most Android displays run at or around 60 frames per second (or 60 Hz, in display jargon). In order to have a smooth animation, you have to actually be able to process 60 frames per second - that means you've got 16ms to process each frame. If you take longer than 16ms, the animation will stutter, and that buttery smooth feeling we're aiming for melts away.

大多數Android顯示系統是以每秒鐘60幀的頻率工做的(專業點說,叫60Hz)。爲得到更平滑的動畫,就必須具備每秒鐘處理60幀的能力——意味着每幀只能花費16毫秒的時間。若是這個過程超過16毫秒,動畫顯示就會有停滯感,咱們期待的如絲般順滑的體驗也就消失無蹤了。spa

16 milliseconds isn't a lot of time, so you're going to want to make the most of it. In Ice Cream Sandwich, processing for the next frame would just kind-of lazily start whenever the system got around to it. In Jelly Bean, the whole process of making the next frame starts as soon as the last frame is finished, at the beginning of the VSync pulse. In other words, they're using as much of the 16ms as they can. Here's an example:

16毫秒不是很長的一段時間,因此你會但願充分利用它。在ICS中,系統對下一幀的處理有點懶加載的意思,須要的時候才進行處理。而在Jelly Bean中,整個進程將在上一幀剛結束時,在垂直同步脈衝開始時,就馬上開始下一幀的處理過程。換句話說,系統會盡可能充分的利用那16毫秒。舉個例子說:

Untitled-1

Untitled-1

 

This is what life is like without running everything off of VSync. In these slides, the numbers are frames. First the frame is processed by the CPU and GPU, and, when it's finished, it's handed to the display at the beginning of the next VSync.

這就是在沒有進行全面垂直同步時的狀態。在圖片中,數字表明着幀。首先,幀由CPU和GPU進行處理,當處理完成後,在下一個垂直同步開始時交付顯示。

So in this picture, Frame 0 is displayed, and, during the 16ms of display time, the CPU and GPU prepare the next frame. The calculations get done in time, and at the next VSync pulse, they hand over the next frame, "Frame 1." Great.

在例圖裏,先顯示了第0幀,在16毫秒的顯示時間內,CPU和GPU準備下一幀。運算按時完成了,在下一個垂直同步脈衝到達時,它們交付了下一幀:第1幀。很好。

We're now showing frame 1, and it's time to start working on frame 2. Something slows the system down, though, and processing for the next frame doesn't start until we're well into our 16ms time limit. The system now only has about 4ms to figure out frame 2, so the processing for it doesn't get finished in time. With no frame 2, the display is forced to show frame 1 again, for another 16ms. Team Android has dubbed this "Jank," and it basically means any animations happening during this time won't be fluid; the user will see stuttering.

顯示了第一幀後,是時間完成第二幀了。但某些因素致使了系統變慢,因此,直到16毫秒即將過去時,下一幀的處理工做纔剛剛開始。此時,僅剩4毫秒來繪製第二幀了。毫無心外的,這工做沒及時完成。此時,顯示屏在第二幀沒完成的狀況下,只能在後面的16毫秒內再次顯示第一幀。Android小組將這種狀況稱爲」廢幀「,標示着此其間內全部的屏幕動效都沒法及時傳遞,而用戶會體驗到停滯感。 

_0003_Layer-5

_0003_Layer-5

 

Here's the new way of doing things in Jelly Bean. All the processing for the next frame starts at the VSync pulse, so you're now making the most of your 16ms of render time.

這幅圖展現了在Jelly Bean中事情是如何運做的。全部下一幀的運算工做都在垂直同步脈衝抵達時開始。這樣16毫秒的渲染時間就會被充分利用了。 

Frame processing has moved from "Yeah whenever we get around to it," to a rigidly scheduled, highly organized affair. Sort of like the difference between a car mechanic and a NASCAR pit crew. In this example, all the processing happens within the 16ms time limit, all the frames get delivered on time, and you get a smooth, buttery experience.     Triple Buffering Stops Jank From Snowballing

幀處理由」無論三七二十一,反正我搞完了「,變成了高度組織,嚴格按照時間表執行。有點相似街邊修汽車的和雲斯頓賽車維修站的區別。在這個例子中,全部的處理都在16毫秒限制內發生,全部幀都按時交付,而用戶則得到了平滑、流暢的體驗。三倍緩衝解決了畫面撕裂問題

VSync isn't the only thing that helps out animation smoothness, Android is also able to recover from a slowdown more smoothly.

除了垂直同步外,Android還使用了其它方式來使動效更順暢。 

_0002_Layer-6

_0002_Layer-6

 

So what the heck is a "buffer"? Put simply, a buffer is the container the frame is built and stored in. We've been referring to frames by number, but really, those frames sit in one of the two buffers. Android is double buffered, a pretty typical setup, meaning it can display 1 frame while working on another. In this picture the buffers are labeled "A" and "B."  While displaying buffer A, the system starts building a new frame in buffer B. When that's ready, they swap buffers. B gets displayed, and A gets cleared and a new frame is worked on.

那麼,到底什麼是「緩衝」呢?簡單的說,緩衝就是幀構建和保存的容器。咱們在前面用序號指代幀,但實際上,這些幀實際上是在兩個緩衝中的。遵循慣例,Anroid採用雙緩衝機制,意味着它能夠在顯示一幀的同時進行另外一幀的處理。在圖中,就是緩衝A和B。當顯示緩衝A時,系統在緩衝B中構建新的幀。完成後,則交換緩衝。顯示緩衝B,而A則被清空,繼續下一幀的繪製。

_0001_Layer-7

_0001_Layer-7

 

The problem with double buffer arises when you take longer than 16ms to draw your frame. Here the processing on buffer B runs over, which means a stutter (Jank!) happens. Stuttering is bad and all, but the real problem here is all the white space in the CPU and GPU graphs, that's wasted time. In the first frame, buffer B runs over, so that buffer is in use until it can be displayed, buffer A is also in use, because it is being displayed for 2 frames in a row, and remember, you can only switch frames (and hence, buffers) at the VSync pulse. The CPU and GPU are out of usable buffers, so they just sit there. One slowdown puts the system behind, which causes more slowdowns. This was how Ice Cream Sandwich worked.

當某幀的繪製時間超過16毫秒時,雙緩衝的問題就暴露出來了。如圖所示,當緩衝B超時後,一個卡頓發生了。卡頓老是很差的,但更嚴重的問題在於圖中表明CPU和GPU的圖片之間的空白,這是對時間的浪費。在第一幀中,緩衝B超時,則在它被顯示以前,都處於使用中的狀態,而緩衝A由於爲了填補空白,仍在顯示,則也處於使用中的狀態。咱們知道,僅在收到垂直同步脈衝時,纔會進行幀(緩衝)切換。則CPU和GPU受限於可使用的緩衝數,不得不消極怠工。一步慢步步慢,這就是ICS的缺陷。 

_0000_Layer-8

_0000_Layer-8

 

In Jelly Bean, we've got a solution for 2 full buffers, a third one! Same situation as before, buffer B takes too long, and A is in use displaying the current frame. This time though, instead of wasting processing time during the repeated buffer, the systems creates a C buffer, and gets to work on the next frame. Triple buffering stops the stutter fest, and after the initial skip, the user sees a smooth animation. It's all about presenting a stiff upper lip to the user even though things aren't going so smoothly under the hood.

在Jelly Bean中,咱們有了解決雙緩衝問題的辦法:再加入第三個緩衝!在前述的狀況下,B緩衝超時,而A緩衝用於當前幀的顯示中。此時,不會因前述緣由形成時間的浪費,系統會新建立緩衝C,並繼續下一幀的工做。三倍緩衝結束了頻繁卡頓的產生,在初始化跳頓後,用戶獲得了平滑的動畫效果。即使有些問題發生了,但系統還會努力給用戶滿意的結果

So why don't they just do triple buffering all the time? Well, as you can see from the diagram, triple buffering introduces a bit of input lag into the process. Look, for instance, at the distance between the rendering of buffer C (the blue/green part), and the displaying of it. So, when things are misbehaving, you get a choice of 2 evils: input lag (your touches taking longer to have an effect) or choppy animation.

那麼,爲何不乾脆一直用三倍緩衝呢?正如你在圖中看到的,三倍緩衝在整個過程當中引入了一些輸入延遲。好比說,在緩衝C(暗綠色部分)渲染過程與它被顯示之間。因此,當出現某些錯誤行爲時,你有兩個選項: 輸入延遲(你的觸摸操做生效時間會延長)或者畫面卡頓。 

To address this, Jelly Bean doesn't do triple buffering all the time. It normally runs a double buffer, but that third one is around whenever you need it. This way you get less input lag, and when things go wrong, you've got a third buffer at the ready to help you recover.     The Results

爲解決這個問題,Jelly Bean沒有一直使用三倍緩衝。通常狀況下,它只使用了雙緩衝,但當須要的時候,會用三倍緩衝來進行加強。這樣,即將輸入延遲下降到最少,又能在發生意外的狀況下保持畫面流暢。結果 

The result of all this hard work is buttery smooth animation. The team was so impressed with their new animation aptitude that they spruced up many of the transition animations, which I will now present to you in excruciating detail. Check out ICS vs Jelly Bean, in super slow-mo.     New Animations

以上努力的結果是獲得了順暢的動畫。咱們都爲簇新的動畫效果震驚了,過會兒我會展現這些動畫的詳情。相對於Jelly Bean, ICS簡直就像拉車的老牛同樣。新動畫 

Icon Launch Transitions - Left: ICS's no-frills app launch transition. Right: JB zooms in from the location of the icon

 

There isn't much to say about these videos, but I'll try my best. Ice Cream Sandwich (left) has an absolutely boring icon launch transition. It's just a simple stretch and fade to the center of the screen. In Jelly Bean (right), applications zoom out from the icon position. This manages to be both neater looking and more communicative: "You pressed this icon, and this is opening from it." I like it.

 

Uninstalling - Left: ICS just uses the standard screen transition. Right: Jelly Bean's fun "toilet flush" animation

 

Uninstall gets a cool transition too. It's a slide/fade/shrink animation to the bottom of the screen. It sort of reminds me of a toilet flush. The previous screen also gracefully slides into view when the app is gone.

 

Launching from within an app - Left: ICS does a simple fade. Right:  JB slides things all over the place.

 

This transition is pretty much the uninstall animation in reverse, and it is used all over the place. I think it's triggered whenever an app opens another app. So here, you see the play store launching an app, and you'll see it when something like Google Reader launches a web browser, it's all over the place.

 

Update: Googler Clarification!

 

The always-helpful Dianne Hackborn, an Android Framework Engineer, stopped by our Google+ page (you are following us on G+ right?) with some insight on this animation:

 

"One thing I'd like to clarify -- the "uninstall" and "launch" animations are actually the same thing. This is the animation set for a "task switch". That is, moving in the UI from one task to another. A task is the thing you see in recent tasks, so this effectively tells you that you are moving between tasks that would be seen in the recent tasks UI."

 

So there's even more communication through animation. Thanks Dianne!

 

Recent Apps - Left: ICS oddly fades to a blank desktop. Right: JB's awesome transition

 

Recent apps probably has the coolest animation out of the bunch. The app grows out of the thumbnail, which is, again, neat looking and communicative - the perfect use of an animation system like this.

 

And finally, the new Jelly Bean camera animation. Snapping a picture sends your still flying off to the right, and a swipe will bring it back. I didn't bother showing you the ICS version because, well, nothing happens.

 

That's about it for Project Butter. You really have to experience it to get the full effect. Everything is smooth and fast. It really is impressive how much more power they've managed to squeeze out of my old Nexus.
相關文章
相關標籤/搜索