青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

++wythern++

X presents Y for a better Z

【轉(zhuǎn)】Why your Android Apps Suck

Original Post is here.

Why I wrote this article?

When I learn more about Android’s graphics system, and do more work about how to use CPU/GPU in more paralleled way to improve the graphics performance in Android, I start to think that there are actually some big design mistakes in Android graphics system, especially the rendering architecture in the client side.

Some mistakes have been solved after 3.x, especially above 4.1, but others can never be solved due to the compatible reason. As developers, we need to know how the Android graphics system work, how to utilize the new features Android 3.x and 4.x provided, and how to do the optimazation and overcome the shortage of Android.

Direct Rendering

In the very beginning, Android’s client/server architecture of its graphics system choose the direct rendering mode, Android team develop a lightweight Window Compositor – SurfaceFlinger by themself, it response to create native windows, allocate graphics buffers and composite the window surface to display (via framebuffer). In client side, apps (through Android runtime) can use CPU to access the graphics buffer of native window directly (through Skia), or use GPU to manipulate it indirectly (through GLES). This direct rendeing mode is more appropriate than the traditional X in desktop Linux.

Window Composite in Server Side

SurfaceFlinger use GLES1 to do the window composition (via texture operation) in the very beginning, this cause two issues :

  • GPU may have more efficient way to do the window composition than use GLES;
  • When the client side also use GLES to render the window surface, it may competes with the server about the GPU resources;

Just mention, when GPU do not support GLES1, Android has a built-in SW version GLES1 stack, and it can use copybit HAL module provided by chip vendor to accelerated the texture operation.

So, after 3.0, Android introduce hwcomposer HAL module to solve these issues, also abandon the old copybit module. Chip vendor can through the implementation of hwcomposer module to declare they can do all of or part of windows’ composition by themselves, usually with dedicated hardware and always more efficient than use GLES. Also, after 4.1, hwcomposer can provide the vsync signal of the display, so that Android can sync three things together :

  • the windows composition in server side
  • the rendering of window surface in client side
  • the refresh of display

vsync

Rendering Architecture in Client Side

The most mistake Android team make is the rendering architecture of its GUI framework :

  1. It do not has a layer rendering architecture (or called scene graph in some GUI fw);
  2. It do not has a dedicated rendering thread to render the window surface;
  3. It’s rendering only use CPU until 3.0;

The first one is partially support after 3.0, the third is support after 3.0, but the second problem can never be solved…

Compare to iOS

In iOS, every View has a Layer as its backing store, app can create more Layers for better performance. View’s content will be drew into its Layer, as long as the content do not changed, the View do not need to draw itself again. iOS do a lot of things to avoid change the content of a View, many many properties of a View can be changed without affect to its content, such as background, border, opacity, position, transformation, even the geometry!!!

The composition of Layers done by another dedicated rendering thread, it always use GPU to draw each Layer to the window surface. The main thread only reponse to handle touch event, relayout the Views, draw View’s content into its Layer when necessary, etc… So the main thread only use CPU and the rendering thread use GPU mostly, and I think there will be just a few synchronization between these two threads, and they can run concurrently in most of time.

But in Android, the main thread need to do everything, such as handle touch events, relayout views, dequeue/enqueue graphics buffer, draw views’ content on window surface, and other things need to be done by app… And it only use CPU before 3.0!!! Even the position of a View just change one pixel, Android need to redraw its content along with the contents of other Views overlapped, and the content drawing is very expensive for CPU!!!

The Improvements

A lot improvements have been made after 3.0 to overcome the shortage of previous versions. Android 3.0 introduce a new hwui module, and it can use GPU to accelerated the drawing of View’s content, it create a hw accelerated Canvas to replace the old sw Canvas, the new Canvas use OpenGL ES as its backend instead of use SkCanvas from Skia.

Android 3.0 also introduce the DisplayList mechanism, DisplayList can be considered as a 2D drawing commands buffer, every View has its own DisplayList , and when its onDraw method called, all drawing commands issue through the input Canvas actually store into its own DisplayList. When every DisplayList are ready, Android will draw all the DisplayLists, it actually turn the 2D drawing commands into GLES commands to use GPU to render the window surface. So the rendering of View Hierarchy actually separated into two steps, generate View’s DisplayList, and then draw the DisplayLists, and the second one use GPU mostly.

When app invalidate a View, Android need to regenerate its DisplayList, but the overlapped View’s DisplayList can keep untouched.  Also, Android 4.1 introduce DisplayList properties, DisplayList now can has many properties such as opacity, transformation, etc…, and the changed of some properties of View will just cause changed of corresponding properties of its DisplayList and need not to regenerate it. These two improvements can save some times by avoid regenerate DisplayLists unnecessary.

Although Android can never has a layer rendering architecture, it actually introduce some Layer support after 3.0, a View can has a Layer as its backing store. The so called HW Layer actually back by a FBO, if the content of View is too complicated and unlikely to change in the future, use Layer may help. Also, when a View is animating (but content do not change), cache itself and its parent with Layers may also help. But use Layer with caution, because it increase the memory usage, if your want to use Layers during animation, your may need to release them when the animation is finish, Android 4.2 provide new animation API to help you about that. Also, because Android use GLES to draw the content of View, so most Views’ drawing will be fast enough, and the use of Layer may be unnecessary.

Android 4.0 also introduce a new type of native window – SurfaceTextureClient (back by a SurfaceTexture) and its Java wrapper TextureView, app can create and own this kind of native window and response to its composition. If the content of View is too complicated and continue to change, TextureView will be very helpful, app can use another thread to generate the content of TextureView and notify the main thread to update, and main thread can use the TextureView as a normal texture and draw it directly on the window of current Activity. (TextureView can also replace the usage of original SurfaceView and GLSurfaceView)

Android 4.1 make the touch event handling and ui drawing sync with the vsync signal of display, it also use triple buffers to avoid block the main thread too often because it need to wait the SurfaceFlinger to do the page flip and release the previous front buffer, and SurfaceFlinger will always sync with vsync signal of display.

The OpenGL Renderer for hw accelerated Canvas is continue be improved and become faster, especially for complicated shape drawing.

But…

But Android can never has a dedicated rendering thread… Although the drawing is much faster than before, and keep the changed of everything as little as possible during animating, it still need to share the 16ms interval with other jobs in main thread to achieve 60 fps.

So…

So, as developer, we need to utilize the improvements in higher version Android as much as possible :

  1. Turn on the GPU acceleration switch above Android 3.0;
  2. Use the new Animation Framework for your animation;
  3. Use Layer and TextureView when necessary;
  4. etc…

And avoid to block the main thread as much as possible, that means :

  1. If your handle the touch events too long, do it in another thread;
  2. If your need to load a file from sdcard or read data from database, do it in another thread;
  3. If your need to decode a bitmap, do it in another thread;
  4. If your View’s content is too complicated, use Layer, if it continue to change, use TextureView and generate its content in another thread;
  5. Even your can use another standalone window (such as SurfaceView) as a overlay and render it in another thread;
  6. etc…

Golden Rules for Butter Graphics

  • Whatever you can do in another thread, then do it in another thread;
  • Whatever you must do in main thread, then do it fast;
  • Always profiling, it is your most dear friend;

All you need to do is keep the loop of main thread under 16ms interval, and every frame will be perfect!

The Last Word

When I finish this article, what make me think most is, when you make a big design mistake in the very beginning, and you can not change it due to some reasons, no matter how hard you try to patch it in future, it will never get perfect again.

Android team make huge effects to provide features like Strict Mode, AsyncTask, Concurrent & Background GC, hw accelerated Canvas, hw Layer, TextureView, vsync, triple buffers, etc… All they do just about two things, do everything you can in another thread, and make the must thing in main thread faster, and these actually help a lot. But no matter how hard you try to use these features to improve your app, it is nearly impossible to get every frame perfect, because it is so hard to forecast everything the main thread will do in every loop, it may suddenly jump into something totally uncontrollable by you app and make you break the 16ms curse.

And the worse is, if you has a good design, you can continue improve it (like utilize more advance hardware), but the developer need not to know anything about this and do not need to change even one line of their code, if the app run on higher version OS with faster device, it just got the performance boost. If you has a bad design, although you do a lot of things to patch it, but the developer need to know why, they need to rewrite their code to use these new features, they need to know how to avoid the trap, they need to know how to make compatible with older version system, and many many other things…

This is too hard for a developer just want to build a useful and beauty app…

posted on 2013-11-04 22:32 wythern 閱讀(719) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧美日本日韩| 欧美一区二区视频97| 亚洲精品一区久久久久久 | 欧美一区二区三区的| 亚洲在线免费| 欧美在线观看www| 在线观看三级视频欧美| 欧美大片免费| 一区二区三区回区在观看免费视频| 亚洲一区尤物| 在线日本成人| 国产午夜一区二区三区| 欧美精品一区在线| 亚洲综合丁香| 在线成人小视频| 欧美丝袜一区二区| 久久在线观看视频| 欧美亚洲尤物久久| 亚洲性色视频| 欧美激情视频一区二区三区不卡| 久久精品中文字幕一区| 亚洲——在线| 亚洲午夜av电影| 亚洲啪啪91| 黄色综合网站| 黄色成人小视频| 国产精品一区二区黑丝| 欧美日韩综合| 欧美日韩高清一区| 一本色道久久综合亚洲精品高清| 亚洲国产精品99久久久久久久久| 欧美亚洲一区二区在线观看| 一本色道久久88综合亚洲精品ⅰ| 国产精品美女在线| 欧美日韩亚洲一区二区| 欧美好骚综合网| 欧美高清不卡| 欧美激情一区二区三区全黄| 欧美一区永久视频免费观看| 亚洲私人影院在线观看| 亚洲影院色在线观看免费| 日韩亚洲欧美中文三级| 欧美精品日韩www.p站| 欧美日韩xxxxx| 欧美激情精品久久久久久黑人 | 国产精品女人网站| 久久综合久色欧美综合狠狠 | 亚洲欧美国产高清| 久久久国产成人精品| 久久午夜av| 99在线热播精品免费| 亚洲免费黄色| 性久久久久久久久久久久| 亚洲欧美日韩成人| 亚洲一区二区三区在线播放| 一区二区三区欧美在线| 亚洲一区精品在线| 欧美在线日韩精品| 久久久视频精品| 亚洲国产你懂的| 亚洲一区二区高清视频| 久久成人羞羞网站| 欧美电影免费观看大全| 欧美日本韩国| 亚洲精品一二区| 亚洲男人的天堂在线| 麻豆国产精品一区二区三区| 欧美/亚洲一区| 欧美视频亚洲视频| 韩国视频理论视频久久| 久久综合电影| 国产精品videossex久久发布| 国产嫩草一区二区三区在线观看| 狠狠色丁香婷综合久久| 1000部精品久久久久久久久| 亚洲视频一区二区免费在线观看| 久久久久久9999| 亚洲久久一区| 亚洲精品在线视频观看| 国产精品夜夜夜| 久久综合一区二区| 亚洲精品少妇网址| 欧美承认网站| 欧美va天堂| 一区二区成人精品| 一区二区三区av| 国产精品久久久久天堂| 性感少妇一区| 亚洲午夜高清视频| 国产精品国产自产拍高清av王其 | 欧美色精品天天在线观看视频| 亚洲高清免费在线| 欧美本精品男人aⅴ天堂| 中文av字幕一区| 亚洲午夜精品久久久久久app| 亚洲黄色av| 欧美久久一级| 久久精品91久久香蕉加勒比 | 欧美日韩成人在线| 久久国产日韩| 欧美劲爆第一页| 久久精品国产清高在天天线 | 久久久国产视频91| 欧美成人黑人xx视频免费观看| 99成人精品| 欧美一区二区三区四区在线 | 99精品免费视频| 国产资源精品在线观看| 亚洲精品欧美日韩| 国外成人在线| 亚洲成色777777女色窝| 国产嫩草影院久久久久| 亚洲国产一区二区三区在线播| 欧美日韩在线视频首页| 久久久国产亚洲精品| 欧美日韩一区二区国产| 麻豆国产精品一区二区三区 | 久久久亚洲高清| 欧美日韩在线精品| 欧美承认网站| 国产麻豆91精品| 亚洲毛片播放| 亚洲精品视频在线播放| 久久国产夜色精品鲁鲁99| 日韩午夜在线| 久久婷婷蜜乳一本欲蜜臀| 亚洲欧美日韩在线不卡| 欧美激情精品久久久久久大尺度 | 亚洲精品日日夜夜| 一色屋精品视频免费看| 午夜精品久久久久久99热| 一区二区三区四区五区在线| 久热综合在线亚洲精品| 久久男人资源视频| 国产精品久久网| 亚洲精品免费看| 亚洲精品精选| 欧美成在线观看| 欧美激情片在线观看| 影音先锋久久| 免费观看国产成人| 亚洲国产一区二区精品专区| 亚洲欧洲综合| 欧美电影电视剧在线观看| 亚洲国产mv| 亚洲精品极品| 欧美日韩综合| 午夜宅男欧美| 久久久久一区二区三区四区| 久久成人免费| 国产精品一二三四区| 亚洲欧美精品在线| 久久成人精品无人区| 国产午夜精品美女毛片视频| 午夜精品国产更新| 午夜在线观看欧美| 国产欧美精品久久| 欧美亚洲自偷自偷| 久久一本综合频道| 亚洲美女福利视频网站| 欧美人在线观看| 亚洲欧美自拍偷拍| 欧美成人免费在线视频| 亚洲欧洲一区| 欧美午夜激情视频| 久久国产欧美精品| 最近看过的日韩成人| 国产精品99久久不卡二区| 欧美午夜性色大片在线观看| 午夜一级在线看亚洲| 免费一级欧美片在线播放| 亚洲精品永久免费| 欧美亚男人的天堂| 久久久国产91| 亚洲欧洲视频在线| 久久gogo国模啪啪人体图| 国产亚洲精品久久飘花| 免费欧美电影| 亚洲欧美日本精品| 亚洲国产小视频| 久久久久九九九九| 亚洲综合日本| 91久久黄色| 国产欧美日韩综合一区在线播放 | 宅男噜噜噜66国产日韩在线观看| 久久免费精品日本久久中文字幕| 亚洲久久在线| 一区三区视频| 国产精品午夜在线观看| 欧美激情影院| 久久久久久夜| 亚洲日本va午夜在线影院| 久久九九国产精品怡红院| 夜夜夜久久久| 亚洲精美视频| 在线看成人片| 黑人操亚洲美女惩罚| 国产酒店精品激情| 欧美婷婷在线| 欧美日本一道本|