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

++wythern++

X presents Y for a better Z

【轉】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)  編輯 收藏 引用

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美国产在线观看| 免费影视亚洲| 激情久久久久久久久久久久久久久久| 欧美视频在线一区二区三区| 免费影视亚洲| 欧美日本一区| 国产精品亚洲片夜色在线| 国产日韩欧美三区| 在线高清一区| 亚洲麻豆av| 亚洲一区免费网站| 久久精品中文| 亚洲电影在线观看| 欧美激情一区二区三级高清视频 | 欧美亚洲第一区| 国产精品美女久久久| 国产自产精品| 亚洲美女区一区| 性欧美xxxx大乳国产app| 久久免费国产| 亚洲日韩欧美视频| 欧美一区1区三区3区公司| 久久一区视频| 国产精品天天看| 亚洲精品国产精品久久清纯直播| 亚洲男人影院| 蜜臀av在线播放一区二区三区| 亚洲精品视频在线播放| 久久精品视频一| 国产精品乱人伦一区二区| 亚洲激情社区| 久久视频在线看| 日韩午夜激情电影| 狼人天天伊人久久| 国产亚洲欧美日韩在线一区| 一本到高清视频免费精品| 久久久久久久久一区二区| 99re6热在线精品视频播放速度 | 欧美视频1区| 亚洲国产精品久久久久秋霞影院| 亚洲专区在线视频| 亚洲日本欧美日韩高观看| 欧美在线在线| 国产婷婷色一区二区三区| 亚洲天堂男人| 亚洲国产欧美一区| 另类av一区二区| 国内精品伊人久久久久av一坑| 亚洲一区二区视频在线| 亚洲电影欧美电影有声小说| 久久久久网址| 伊人色综合久久天天| 久久精品人人做人人综合| 亚洲深夜av| 免费观看一区| 久久国产精品免费一区| 欧美一级欧美一级在线播放| 欧美大片在线看| 激情欧美一区二区三区在线观看| 亚洲精品欧洲精品| 噜噜噜91成人网| 欧美一区二区大片| 国产伦精品一区二区三区免费迷| 日韩西西人体444www| 欧美国产日韩一二三区| 久久精品国产一区二区电影| 国产精品高潮呻吟久久av无限 | 男女激情久久| 先锋影音网一区二区| 国产精品一区视频| 久久av红桃一区二区小说| 亚洲欧美精品一区| 国产视频自拍一区| 久久一区亚洲| 蜜臀av国产精品久久久久| 亚洲国产精品久久久久秋霞蜜臀| 欧美高清视频在线播放| 麻豆国产精品777777在线| 亚洲国产免费看| 亚洲国产mv| 欧美岛国在线观看| 亚洲视频一区在线观看| 亚洲小视频在线| 一区二区三区自拍| 亚洲精品网址在线观看| 国产精品日日做人人爱| 久久女同互慰一区二区三区| 久久综合九九| 亚洲一本视频| 久久精品视频免费播放| 亚洲美女网站| 亚洲综合视频网| 1769国产精品| 一区二区三区日韩在线观看| 国产在线精品二区| 亚洲日本国产| 精品99一区二区| 一区二区三区 在线观看视| 国产一区二区你懂的| 亚洲大胆女人| 国产女人精品视频| 亚洲成色最大综合在线| 国产精品综合av一区二区国产馆| 欧美成人dvd在线视频| 国产精品激情电影| 欧美jizz19性欧美| 国产精品欧美一区二区三区奶水 | 亚洲性感激情| 久久久久国产免费免费| 亚洲一区www| 欧美高清视频在线观看| 久久精品人人做人人综合| 欧美色大人视频| 亚洲成人资源网| 国内外成人免费激情在线视频网站| 亚洲精品少妇| 亚洲精品久久久久久下一站| 午夜精品久久久久久久久| av成人免费观看| 美女诱惑黄网站一区| 久久激五月天综合精品| 国产精品高潮在线| 99综合精品| 99xxxx成人网| 欧美精品v日韩精品v国产精品| 久久婷婷国产综合精品青草| 国产日韩精品久久久| 亚洲视频在线一区| 亚洲午夜激情网页| 欧美日韩国产成人| 91久久久精品| 亚洲另类视频| 你懂的国产精品永久在线| 另类综合日韩欧美亚洲| 有码中文亚洲精品| 久久美女性网| 亚洲电影成人| 一本久久综合| 欧美性猛交99久久久久99按摩 | 9色国产精品| 9人人澡人人爽人人精品| 免费亚洲电影| 亚洲国产中文字幕在线观看| 亚洲国产高清在线| 你懂的成人av| 亚洲免费播放| 欧美一区二区三区在线观看| 国产精品视频观看| 午夜精品一区二区三区在线播放| 久久激情五月丁香伊人| 精品成人在线视频| 欧美成人69av| 中文网丁香综合网| 久久精品盗摄| 1024亚洲| 欧美性大战久久久久久久蜜臀| 亚洲欧美日韩国产一区二区| 欧美一区二区黄色| 海角社区69精品视频| 欧美 日韩 国产在线| 99re这里只有精品6| 先锋a资源在线看亚洲| 韩国三级电影久久久久久| 麻豆精品网站| 亚洲午夜久久久久久久久电影院| 久久精品在线视频| 日韩视频免费在线| 国产免费观看久久黄| 麻豆国产精品va在线观看不卡| 日韩视频在线观看免费| 久久精品123| 在线一区亚洲| 激情一区二区三区| 亚洲欧洲精品一区二区三区波多野1战4| 久久精品女人的天堂av| 亚洲国产精品日韩| 欧美在线免费一级片| 亚洲精选视频免费看| 国产精品免费网站| 欧美二区在线看| 久久国产精品网站| 日韩亚洲精品视频| 毛片一区二区| 欧美一二三区精品| 日韩午夜免费| 亚洲国产精品成人精品| 国产麻豆精品视频| 欧美日本韩国一区| 久久久综合网| 欧美影院在线| 亚洲视屏一区| 亚洲日本免费电影| 欧美黑人在线观看| 久久久精品国产免大香伊| 亚洲一级黄色av| 一本大道久久a久久综合婷婷| 亚洲高清自拍| 国产一区二区久久| 国产主播精品| 国产一区二区你懂的|