├── .gitignore ├── LICENSE ├── README.md ├── SA ├── Container │ ├── Container-01.md │ ├── graphic-system-03.drawio │ ├── graphic-system-03.png │ ├── graphic-system-04.drawio │ ├── graphic-system-04.png │ ├── graphic-system-05.drawio │ ├── graphic-system-05.png │ ├── graphic-system-06.drawio │ ├── graphic-system-06.png │ ├── graphic-system-07.drawio │ ├── graphic-system-07.png │ ├── graphic-system-08.drawio │ ├── graphic-system-08.png │ ├── graphic-system-09.drawio │ ├── graphic-system-09.png │ ├── graphic-system-10.drawio │ ├── graphic-system-10.png │ ├── graphic-system-11.drawio │ └── graphic-system-11.png ├── Context │ ├── Analysis-Objective.md │ ├── graphic-system-01.drawio │ ├── graphic-system-01.png │ ├── graphic-system-01.puml │ ├── graphic-system-02.drawio │ ├── graphic-system-02.png │ ├── graphic-system-02.puml │ ├── graphic-system-02a.png │ ├── graphic-system-03.png │ ├── graphic-system-03.puml │ ├── graphic-system-04.png │ └── graphic-system-04.puml └── README.md ├── document ├── brief-design │ ├── brief-design.md │ └── gui_BufferQueue Component Diagram - thumbnail.svg ├── client-design │ ├── Android Game SDK.pdf │ ├── High refresh rate rendering on Android.pdf │ └── client-design.md ├── contents.md ├── framework-design │ ├── Android Native Window Buffer Statemachine Diagram - Consumer.svg │ ├── Android Native Window Buffer Statemachine Diagram - Producer-Consumer.svg │ ├── Android Native Window Buffer Statemachine Diagram - Producer.svg │ ├── Android Native Window Buffer Statemachine Diagram - native.svg │ ├── BufferQueue-00.fig │ ├── BufferQueue-00.svg │ ├── BufferQueue-01.fig │ ├── BufferQueue-01.svg │ ├── BufferQueue-02.fig │ ├── BufferQueue-02.svg │ ├── BufferQueue-03.fig │ ├── BufferQueue-03.svg │ ├── BufferQueue-04.fig │ ├── BufferQueue-04.svg │ ├── Graphic Buffer Alloc Component Diagram - Client-Server.svg │ ├── Graphic Buffer Statemachine Diagram - Producer-Queue-Consumer.svg │ ├── buffer-window-design.md │ ├── bufferqueue-design.md │ ├── composer-design.md │ ├── framework-design.md │ ├── gui_BufferQueue Component Diagram - 2-stage.svg │ ├── gui_BufferQueue Component Diagram - FramebufferSurface.svg │ ├── gui_BufferQueue Component Diagram - GraphicBuffer Allocation.svg │ ├── gui_BufferQueue Component Diagram - VirtualDisplaySurface.svg │ ├── gui_BufferQueue Component Diagram - link.svg │ ├── gui_BufferQueue Component Diagram.svg │ ├── gui_IConsumerListener Component Diagram - Call Path.svg │ ├── gui_IConsumerListener Component Diagram.svg │ ├── gui_ISurfaceComposer Component Diagram.svg │ ├── gui_Surface Class Diagram.svg │ ├── gui_Surface Component Diagram - Call Path.svg │ ├── gui_Surface Component Diagram.svg │ ├── nativebase_nativebase Class Diagram.svg │ ├── system_window Class Diagram.svg │ ├── ui_GraphicBuffer Class Diagram.svg │ ├── ui_GraphicBuffer Component Diagram - Call Path.svg │ ├── ui_GraphicBuffer Component Diagram - native.svg │ └── ui_GraphicBuffer Component Diagram.svg ├── general-design │ ├── 2-stage.md │ ├── DispSync-01.fig │ ├── DispSync-01.svg │ ├── DispSync-02.fig │ ├── DispSync-02.svg │ ├── DispSync-03.fig │ ├── DispSync-03.svg │ ├── DispSync-04.fig │ ├── DispSync-04.svg │ ├── DispSync-05.fig │ ├── DispSync-05.svg │ ├── VSYNC.md │ ├── dispsync.png │ ├── general-design.md │ ├── services_surfaceflinger_CompositionEngine_include_compositionengine_DisplaySurface Class Diagram.svg │ ├── services_surfaceflinger_DisplayHardware_HWComposer Component Diagram.svg │ ├── services_surfaceflinger_NativeWindowSurface Class Diagram.svg │ ├── services_surfaceflinger_Scheduler_DispSync Class Diagram.svg │ ├── services_surfaceflinger_Scheduler_DispSync Component Diagram.svg │ ├── services_surfaceflinger_Scheduler_DispSyncSource Class Diagram.svg │ ├── services_surfaceflinger_Scheduler_EventControlThread Class Diagram.svg │ ├── services_surfaceflinger_Scheduler_EventThread Class Diagram.svg │ ├── services_surfaceflinger_Scheduler_MessageQueue Class Diagram.svg │ ├── services_surfaceflinger_Scheduler_Scheduler Class Diagram.svg │ ├── services_surfaceflinger_SurfaceFlinger Component Diagram - ComposerCallback.svg │ ├── services_surfaceflinger_SurfaceFlinger Sequence Diagram - Layer-DisplaySurface.svg │ ├── services_surfaceflinger_SurfaceFlinger Sequence Diagram - RenderSurface-DisplaySurface.svg │ └── symmetrical-design.md ├── hal-design │ ├── VSYNC.md │ ├── ape_fwk_graphics.png │ ├── bufferqueue.png │ ├── continuous_capture_activity.png │ ├── fence.md │ ├── gralloc.md │ ├── graphics_pipeline.png │ ├── graphics_secure_texture_playback.png │ ├── hal-module.md │ ├── hardware_fb Class Diagram.svg │ ├── hardware_gralloc Class Diagram.svg │ ├── hardware_gralloc1 Class Diagram.svg │ ├── hardware_hardware Class Diagram.svg │ ├── hardware_hwcomposer Class Diagram.svg │ ├── hardware_hwcomposer2 Class Diagram.svg │ ├── hardware_power Class Diagram.svg │ ├── hwcomposer.md │ ├── reuse.md │ ├── window-01.fig │ ├── window-01.svg │ ├── window-02.fig │ └── window-02.svg ├── hidl-design │ ├── graphics_allocator_2.0_IAllocator Component Diagram.svg │ ├── graphics_composer_2.1_IComposer Component Diagram.svg │ ├── graphics_composer_2.1_utils_vts_include_composer-vts_2.1_ComposerVts Component Diagram.svg │ ├── graphics_composer_2.2_IComposer Component Diagram.svg │ ├── graphics_composer_2.2_utils_vts_include_composer-vts_2.2_ComposerVts Component Diagram.svg │ ├── graphics_composer_2.3_IComposer Component Diagram.svg │ ├── graphics_composer_2.3_utils_vts_include_composer-vts_2.3_ComposerVts Component Diagram.svg │ ├── graphics_mapper_2.0_IMapper Component Diagram.svg │ ├── graphics_mapper_2.0_utils_vts_include_mapper-vts_2.0_MapperVts Component Diagram.svg │ ├── graphics_mapper_2.1_IMapper Component Diagram.svg │ ├── graphics_mapper_2.1_utils_vts_include_mapper-vts_2.1_MapperVts Component Diagram.svg │ └── hidl-design.md ├── original-design │ ├── 01-server-side-drawing.fig │ ├── 01-server-side-drawing.svg │ ├── 02-client-side-drawing.fig │ ├── 02-client-side-drawing.svg │ ├── 03-window.fig │ ├── 03-window.svg │ ├── 04-two-stage-copy.fig │ ├── 04-two-stage-copy.svg │ ├── 05-zero-copy.fig │ ├── 05-zero-copy.svg │ └── original-design.md ├── pattern-design │ ├── 01-bufferqueue-01.fig │ ├── 01-bufferqueue-01.svg │ ├── 02-bufferqueue-02.fig │ ├── 02-bufferqueue-02.svg │ ├── 03-bufferqueue-03.fig │ ├── 03-bufferqueue-03.svg │ ├── 04-bufferqueue-04.fig │ ├── 04-bufferqueue-04.svg │ ├── 05-bufferqueue-05.fig │ ├── 05-bufferqueue-05.svg │ ├── Active_Object.png │ ├── Thread_pool.svg │ ├── command_implementation_-_uml_class_diagram.gif │ ├── observer_implementation_-_uml_class_diagram.gif │ └── pattern-design.md ├── server-algorithm │ └── compositing-path.md └── server-design │ ├── Active Object Class Diagram - EventThread.svg │ ├── Active Object Class Diagram - SurfaceComposerClient.svg │ ├── Active Object Class Diagram - internal.svg │ ├── Active Object Class Diagram.svg │ ├── Active Object Sequence Diagram - EventThread.svg │ ├── Active Object Sequence Diagram - SurfaceComposerClient.svg │ ├── Active Object Sequence Diagram - internal.svg │ ├── Active Object Sequence Diagram.svg │ ├── active-object.md │ ├── component-pattern.md │ ├── message.md │ ├── module.md │ ├── renderengine_include_renderengine_RenderEngine Component Diagram.svg │ ├── server-design.md │ ├── services_surfaceflinger_BufferQueueLayer Component Diagram.svg │ ├── services_surfaceflinger_CompositionEngine_include_compositionengine_CompositionEngine Component Diagram.svg │ ├── services_surfaceflinger_DisplayHardware_ComposerHal Component Diagram.svg │ ├── services_surfaceflinger_DisplayHardware_PowerAdvisor Class Diagram.svg │ ├── services_surfaceflinger_Layer Component Diagram.svg │ ├── services_surfaceflinger_Scheduler_MessageBase Sequence Diagram.svg │ ├── services_surfaceflinger_Scheduler_MessageQueue Class Diagram.svg │ └── services_surfaceflinger_SurfaceFlinger Sequence Diagram - VSYNC.svg ├── notes ├── 4+1.md ├── C4-drawio.md ├── C4-model.md ├── README.md ├── SA.md ├── c4.drawio.library.xml └── c4.drawio.png └── ref ├── 3tier-architecture.png ├── Introduction-to-Software-Architecture.lyx ├── Introduction-to-Software-Architecture.pdf ├── README.md ├── SoftwareArchitectLecture.pdf ├── Understanding-Application-Architectures.lyx ├── Understanding-Application-Architectures.pdf ├── client-server-model.png ├── component-based-software-engineering-example-1.png ├── domain-drivel-design.png ├── layered-architecture-300x217.png ├── message-bus.gif ├── message-bus.png ├── object-oriented-architecture.png ├── onion-application-architecture.jpg ├── soa.png └── software-architecture.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # VIM Edit Results 35 | *~ 36 | .*.un~ 37 | .*.swp 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Design-Of-Android-10.0-Graphic-System 2 | Learn and reuse the design of android 10.0 graphic system. 3 | -------------------------------------------------------------------------------- /SA/Container/graphic-system-03.drawio: -------------------------------------------------------------------------------- 1 | 7Vxbd9o4EP41nLP7EI58BR65lLRn291s2Z5uHw0WoI2xXFkE2F+/I/kuG+qQELzUJCexRtLoNt+nGUtJxxhv9vfMCdafqIu9jo7cfceYdHRdM5ENv4TkEEsMW4skK0bcWJYJZuRfHAtRLN0SF4eFgpxSj5OgKFxQ38cLXpA5jNFdsdiSesVWA2eFS4LZwvHK0q/E5etYqtmDLOM9Jqt13HRf70UZGycpHI8kXDsu3eVExruOMWaU8uhpsx9jT8xeMi9RvemR3LRjDPu8ogKd/yPmQ0eeM4dFkQU6uu1B2ZFLnuBxJR4TURg4vugkP8Qjt79vRc9GS+rzu1CuyxAKaGawzzJVLfNMYPnOBsOvJAs6NleLgyxqtySu6OELOt2v7LM1mtEl38EEQpHZIeR484OOvbC9STPGnawVe+3lEK2LbiUgTlrWqjphAawXjAScUL9oJpGa032Qpu85C7wGQGNWBLm0PCm4f/gS80+uMZkjfqAx3QTUB/x0o1IJtv6c3f8W/nE3WdvvjE8a/dBzQnJnGiloUzBmK6AzuvVdLBQg6OFuTTieBdBBEOyAG0G25huBQ03MFPG8MfUok3WNgfzEM5iTT+VHLDhn9BHncvq6+IIchmG6nbnsBUqn5gkzjvdHiULLjeQe0w3m7ABFMtaOqsSc3bPi9C5HgP1Yts5xn5ZQnROvxyrVnfESPMTTlyRjpmpZq2WtlrWE4P1XSUwhZkfIS38+eZk/CXnZejPJ65kcI8y8Bq2hIxQB2jlerH2Y89VBNGVNalvflxD87cjRzlTInOXWX0SGj8BB9uqYnX3S7LDvDoWPDqm5RxePip3BYOOAQENl+zKR+ErtK/HORU3QOyVeosd1wrW07STx4HCOmcBSX9DNSRPF3lz2TxglgVFL7WAVfwuT7VpJ8ltswTIx2RdShyS1JzxXDVLfkv7Cc1ZJJA4FRGC3FKQoeIBppVu2wCfWwjbjVXXYCvO6jk4OYTkEWRUASmQMew4nT8UOV4EqbuGBEknACeK1IoBtFZfRQONa+QBJUZR2KFakDxRF0USUFEmMp8NuYX8O7Hs3DnvYTnPAv0NdJPWdRL9IPWBGwK4weza8G47aHjJfCbVK8GH2WtS+FWr7t4jaK2+6dl345h30K8BX8Zr7r7TpmqqiFr55+H7G37c45NUI/jAiEJSxOsgd3DBytS7Sejnsoq5m907iVyTUnTa3eyNNK7jtXa1vXHbz/iFNWHV9c1u/Jk1YRhHd1pksYSt6DK1liZMsEQbUd1/KEhbq3C5LpLBOWcLuWS9hicHALLKEfXWWiMBfgyWsqzoTthLBW+c6E5bdgFigPXWICGwMxRziC7sWxSr5rAk9/YnOCT5jwfwJ96sbAxj5SH6jX9a7LekIAQofifNrp/pUIVJH/BVkbqi79cQJE13Cj2EQeMC3omidwwbrcielxqg/nujl/ef4YYM+tadDu3ORwwb9yBvG9qC0AUTQUlYDKSs72ERjj2D/SOibclclUYl1lVXFGeiGCP/xXKa63LFow5iq10yqSiz0zLjqKqFcRisFAimipCYehr7LKJiojqYMhDvKHuuY7en3Pc8y2+PRVt6gferjsi0j+QG545GVAKeHl2L4cqEfaEhizC7ASgULj5LA7aNSYENcV/Q+LTCMFc4p53TTUeLGcpAZJFGXGKhwYaKxh2lKz1J/0SDOVoPa6nh0kW0jL4ZjAr+KWwlmFfxM9c1IRfj1GdDl+Cvprh2LnCrQrlU0ZyitOZ6YC4fjkTCpsA2yLuyxlK92tT7Km/sosy1bQqGpB1xx9ApWRtzy5jtZiCXD7KnWm7jCW9zXdTsQsnuj4XPcDoSsybB/GbdDvY3VFLej5RvVlWkjpIawz1fiiz8TOSMsyijp9+j1rY7yyk4z0v8iEKLCgeMH6a5d6LK7hVqGahmqZagTDPXROfzwnXMlQcWOFWTlVJympdP3hxtCSxdwlJpCQ2/7ZqUpN+HsW7+/2tM7xnPvr6YH7aadv46jdZF+5kF7Iy7UXPWo3LAGXUt5U3PmYXlZVencvb1VczHCuMmrsxlhmA288H5d5Kp/pmJq+nm47SsbfwvaNwPtLd6arQuwq900L+HmzP1OVWSpG+drAQeS2T/piGpn/+vEePcf -------------------------------------------------------------------------------- /SA/Container/graphic-system-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Container/graphic-system-03.png -------------------------------------------------------------------------------- /SA/Container/graphic-system-04.drawio: -------------------------------------------------------------------------------- 1 | 7Zxbc9o4FMc/DTPdh2R8wcY8hly6nW1n083utHkUtgBtjEVlU8h++j3yVZaN4xADJVbSadDR1ZL+Px/JMgPzern9yNBq8YV62B8YmrcdmDcDw3BsB/7nhufEMHTGiWHOiJeY9MLwQP7DqVFLrWvi4bCUMKLUj8iqbHRpEGA3KtkQY3RTTjajfrnWFZrjiuHBRX7V+o140SK16va4iPgdk/kirdoxRknEEmWJ0ysJF8ijG8Fk3g7Ma0ZplHxabq+xz/su65ck392O2LxhDAdRTQY6/Zf3h6H5aApDEicYGLYPaSczGvCYMHpOL9P+saZZxEUYD8IVJNC11baIhE/z9G9cyrQwWAFaYviTRUErppXk7A1VWpNrSIdIgNnAuhGqSS4lqynuER+5eAHjjFl57OM2xoarwGMUOtLQ7hgYN5Q9JUmyzv368PGP8M+Lm4V9a37R6acRCsmFng9aPhjF5RiMrgMP8/waNGWzIBF+WEFLwLABZYBtES35OOjwMYwYfcLX1Kcszm06Bv/l3UF8P7MHNMBpDwlJtfgH7Mgn8wBsPp7xq4/H+Z6GJCKUm12YF9Bb5uQnZhGBGf1ZSrAknsdbnye4Sguc0iiiS4jwULiIL6locyYCbllhRpYYKuEXSoJ5eu1hHjKK0N90lUbzy0l1rmtpJfcogmJ43YALzQGrmw93kisZH95SvN0pAHGEPmIKbWPPkCTNMEyFmJJI59OVhzeFrqFzE9tCkPTQTI0onU/zvOi8tr9AayiYQ3fm1Vl2ub6s+o2IkZrq5NqQz7sGRXjCZ1goahw+CBdamOLZmQVTECgovACFe0a9tQtFvUwCQ5HgrEkwssoksKvSzGVYkqbdCxJ45KesUxi7oJVShx3CAWxJvRVzTQvf0GhnJ12WKxAen1M8GbQ2wu4iAAHOn3nTS8w5YUsFlnbbgdktIfPKs5r1ukZY4Ke7jKxippQGtozj+ja0hPQ3EnAnOlkHFIMRx8EUn8T/4vWG0Jh0cr+IdbM7rIvw5lC3pmiWIa+O4JXbgD0eG5MbiGEYuh9N41Z0hD9dkzwhp+oJ6U4NkHSjgX8lFCnuKO68J+7cMcxv6JP1bJZ5iJ3jx+kpfswa90vhR+FH4SfHT8Kdr2u8xgeCj671hD6WoZwfRR9Fn9fQB7lPh3Z+9L4svoa68n4UfxR/XrX4Spp0WAANewIg21QAUgBSAHoFgD6j58Nxx+oJd8Zq4aW4o7jzOscnnjYHdnzsngLoV3F8+n7wRtjWbJ6oo+4mqjp2c4JjN+ZY8gBqBDgc1giwJ+du+g4CKCtcL1udwNM7fFiqWHACFozlMyh1Z/AMxYK+suBhzWaQ6M6H6dqOCGNFhLMmgikptO58/qjOPe/J+fzjarl2+d9Sux7+wV36D78NalesnyYEpNhG00bznjwOvCv+ihfXhE/dJ2ktKk1kSadDjf/WCgfKvSN+Vk5JZfVq2M0L7E/j9mUa5qYtib6nsuGfH/nny5GVBm+2QtzNcxYIYAZ9z9sHATEbDxf54lCWMell7FXecpNkCR1L18zFDaORiSFCbI6jhoTio1xB54KwrBpdZTaGfRSRn+X2Nkj7npL4VpnK2nCkVb68eE+uM81VaLWmIKNUEACjXFDSD5WCeir6riTfvBt1ppLP1HuhXWq6JGHjBQXHofvsXv5qWb+o1tLJr5PL1dDG+8nVsuSCnOPLtfWDg6699mYJt94xb6n1D2GyLz2N96V3aH65RKuMB82Sb97XO47kO7iF73cHP+YN3GyJBHFz5ehEMKVtekvb8wYun/SsFKSI8KsSoXkt/wsTQd+HCNrpiDBs6ySIbtnRkeDIStb3RII9fqEg5dOLqkbujzVhHXj1ZvN3Zyiv/nXKPpUOR9KmvbGvDuVH8ZWClA5FHcKwYRR2oUPjPevwUHtjp5JbRSWjPeVW0a1ckJKbKLd/QhzWK222DtzkxJcGc89vo7jm91rOXHGCs/pYktiOm162bs4940fBZ673kjv0ds9i+avLx2T33b+W19GVgpToDyb6d/nc6s2iN+1Ra9nzwP6b3t09y9JP+zBL/qoE3doPBpWClAdwNBg0v+DRVxhYI0eEwaWmOecBBJHtRwdC5eW9vTfH5deQFRCOBoR3/Yj7vJYEpbfvjr/Al0WoWZdjWyt+hvuJW9figsply+dmuxL4gL+fTSMxd/FN4Obt/w== -------------------------------------------------------------------------------- /SA/Container/graphic-system-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Container/graphic-system-04.png -------------------------------------------------------------------------------- /SA/Container/graphic-system-05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Container/graphic-system-05.png -------------------------------------------------------------------------------- /SA/Container/graphic-system-06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Container/graphic-system-06.png -------------------------------------------------------------------------------- /SA/Container/graphic-system-07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Container/graphic-system-07.png -------------------------------------------------------------------------------- /SA/Container/graphic-system-08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Container/graphic-system-08.png -------------------------------------------------------------------------------- /SA/Container/graphic-system-09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Container/graphic-system-09.png -------------------------------------------------------------------------------- /SA/Container/graphic-system-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Container/graphic-system-10.png -------------------------------------------------------------------------------- /SA/Container/graphic-system-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Container/graphic-system-11.png -------------------------------------------------------------------------------- /SA/Context/Analysis-Objective.md: -------------------------------------------------------------------------------- 1 | # 所要研究的对象 2 | 3 | 比起其它基于网络服务的大型系统来说,基于本地的 Android 图形系统的语境图(Context)相当简单。用户只和图形界面的应用软件打交道。图形应用软件背后会和一个 Graphic Server 打交道。两者都有硬件加速支持。 4 | 5 | ![Android 图形系统的语境图1](graphic-system-01.png) 6 | 7 | 我们针对应用软件的图形模块进行放大,得到下图: 8 | 9 | ![Android 图形系统的语境图2](graphic-system-02.png) 10 | 11 | 图形模块可以简单地分成上下两层,逻辑层和执行层。逻辑层由开发应用的团队负责,依需求不同而各式各样。执行层位于 Android Framework 层中,具有通用性。其功能又可分为先后执行的两个部分: 12 | * 渲染模块(Renderer)。就是给窗口画点、线、面,或者渲染图像的模块。如果应用没有自行实现,则底层就采用 Android 现有的模块:hwui / skia。 13 | * 合成模块(Composer)。就是将多窗口的内容合成并显示在屏幕的模块。这个功能主要由著名的 SurfaceFlinger 软件完成。 14 | 15 | 本系列文章主要分析合成模块(Composer),如图中的阴影区块所示。渲染模块(Renderer)是另外一块不亚于本系列的大块头,留待以后有机会再说。 16 | -------------------------------------------------------------------------------- /SA/Context/graphic-system-01.drawio: -------------------------------------------------------------------------------- 1 | 7Vtbc9o4FP41zOw+hJHv8MglSTs7nc0uk2n7aGyBtTWWK4tA+utXsmVbso0xCYGmtZkJ1pF0JJ3Ld44kMjBmm/09cePgE/ZhONCBvx8Y84Guayaw2RenPAuKYWsZZU2QL2glYYF+QEEEgrpFPkyUhhTjkKJYJXo4iqBHFZpLCN6pzVY4VEeN3TWsERaeG9apn5FPA0HV7HFZ8QGidSCGHulOVrFx88ZiJUng+ngnkYzbgTEjGNPsbbOfwZBLL5dL1u/uQG0xMQIj2tABL//j8tBB6C6ZUtIGokvoejBggoBEFQ6KEkq2HkU4yujQR5yD71KXfeEVF34AOU+8gyRbU8zLO0QDFBXVa4K3seAppvvP4v6v5O+beWDfGp80/NFxE3RjOIUcivUl9DmXfcbGmBKYoB/uMiUDVs44P0FC4b7JCETTUvSykDRpyHuIN5CSZ9YkZ2SLLsJeTVHcSbrPmwSS2jVHEF0h0nXBulQJexHLzItCSS0Ks0NWPfXRkyIa+/uWm83UwyEmA2PCKsl6+YduWQO+ZsYaVN7/5AUuOrALEIU3ScyMIOsZYbJxw5Ipe1uL73Rw1jRqHH2FI3qTpC7L+WhmvD/MZVkSrMjdMDOx8iomiGW1OaNl49bIqSxU6lXFw6XQRTyjRulY0wfmhszhrLm0xoznT7N0Ud9pQScazf4mYUO0iHdJ3r9p5FEtb6c1dbFYnPMIilP4VZyjizVw7EndKsWNx4TDcxp4JaZp1YSrZRL5BDNo1gFvOTwWF1oxfNSK4QzCIx9yBhqbZyrBRSbA+Y6lDIwW0E0oqln4wd/gLFMN620AYGjWjEsShaFCNzVnLCSs0PnD6C7xRC5haG0RQ44Mx0OUFC9EfHC6xgfw6vhQywCa5yvykic33EI56ks6YWxY+gSP68NN4iynWqE91+EZFXR+jewPRuxRg0JGp+vjaIB+l2HzZZM+FMwWeEV3TIOsyeI5oXCjxrUrzu2M4eSqIH8QpUv0n8RxiDw3G6NLEJA6DDtAvinn0G2QD45DTA03bGc6qePGXfo0I5A1n4xO2SWcsBuw1N1AgRoy3Dehi6a//XagR5sebX4KtClgJD0DQh7XBiRPRV5ZQ5/FlqwY27sQRes8T20HHP03ARxz1APO+wKc9om9crwezC4NZvcPjwdAi/8BM7yJccScuVOaZLwZao3T5xTUGun8c5k0yWzaFfeo1aNWj1pvg1ofPqfAdPjQTz8dvMzfBLyqKdfPAl4nYsySdII1cAAiGHcKvSBiMl8/86GseWfre0xgktEkFtLJY7udWa12BiN/wm9xWWkZYu9bxbDY6sQxrwbqBmUC/ikMKr+/5T0Z3zsU5nx8NwmKM2peeHAphYQ7z4jjS6tNwnCZzo9bIfLcMOXOzOALt9GhlRe/CpNNC/O9UnpWzBn6tSvpijEzSbtkDWnXMxrJ6iWrthqMOqcRGLoUPanzaDJ0McIDRikoCqcqTmHzfYxW8ZUEb4kHRS/5lrvCyDZURrVz9EwQNUap3xXL7l1RX22j7GJfB15633bcM+3eMwvPhHtEpW6s9DWfL3svO/HC6d6cecNRb+7i9vKe4/JuXz0vrYbIrm5fYzTu3f5Sbt/+m5z36fZdXfFajmNZjpqEVsNcZ8cxD2SzveO8ueO0/xDifTpOGfdMtiMsIx8Yjsd6a/TjhQdIELMoSOSYKthZthJ/h0BzjsVgXqqyPGeQ1bsGWXlvfHmssJ0hMFUv14zh2AblY54n7JrVX0n06CGjx7/w+xYmtBlAPk5R5He73Rr/wsChKaChW+2YUeCDig26dQQarpJqy5eSV0CB8XCslx6vVfKH8RCIg7b0sV8GCJajD4Ej8anAg946So8WKlokMY7816KFBQa/LloABS2cjmihqWjhXBItOucMV91fGJVtgfHSjbk5PsLoXD7PiuW/xmS9y/8wMm7/Bw== -------------------------------------------------------------------------------- /SA/Context/graphic-system-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Context/graphic-system-01.png -------------------------------------------------------------------------------- /SA/Context/graphic-system-01.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml 3 | ' uncomment the following line and comment the first to use locally 4 | '!include 5 | 6 | 'LAYOUT_TOP_DOWN() 7 | 'LAYOUT_AS_SKETCH() 8 | 'LAYOUT_WITH_LEGEND() 9 | 10 | Person(user, "User", "An Android User.") 11 | 12 | ' analysis objective 13 | System(client, "Application", "An Android Application.") 14 | System(server, "SurfaceFlinger", "Android Graphic Server.") 15 | 16 | System_Ext(gpu, "GPU", "3D Component.") 17 | System_Ext(compositor, "HWComposer", "2D Component.") 18 | 19 | Rel_D(user, client, "Uses") 20 | Rel_R(client, server, "Request") 21 | Rel_L(server, client, "Respond") 22 | Rel_D(client, gpu, "Uses") 23 | Rel(server, gpu, "Uses") 24 | Rel_D(server, compositor, "Uses") 25 | 26 | 'Lay_D(user, client) 27 | 'Lay_L(client, server) 28 | 'Lay_D(client, gpu) 29 | 'Lay_D(server, compositor) 30 | 31 | SHOW_LEGEND() 32 | 33 | @enduml 34 | -------------------------------------------------------------------------------- /SA/Context/graphic-system-02.drawio: -------------------------------------------------------------------------------- 1 | 7Vxbd9o4EP41nNM+JMd3yCOXJu1ue5ot2+320dgCa2MsVxYB+utXkuWbfMEhBAhxegkayyNrNN830kimp4+Xmztsh94X5AK/pynupqdPepqmmX2T/mKSbSxRdUuNJQsMXSHLBFP4GwihIqQr6IKoUJEg5BMYFoUOCgLgkILMxhiti9XmyC+2GtoLUBJMHdsvS39Al3hCqlo32YWPAC480fRA68cXlnZSWfQk8mwXrXMi/UNPH2OESPxpuRkDn1kvsUt8323N1fTBMAhIxQ1o9h+zh6b49owOCq8gbvFtB3jUEAAXjQODiOCVQyAKYjlwIdPg2sSmv9CcGd8DTCdaAxz3KWTlNSQeDNLLC4xWodApHvev6d2f0deriWd90L+o6FPfjuCV3k/tkPYvItvE9rEafYRBBH/bMy5WaDnW/AgwAZsqJxBVM9PnjaTmmrwDaAkI3tIqiSJL3CL81RDFdW7skypebtjVvhDawqSLVHU2JPSD6GZSFIPUMGCWTy+PXPhYMI31a8XcZuQgH+GePqQX8WL2TjMp3OiDUNWK9Pk9KzDTKWsPEnAVhdQJ4jsDhJe2nymlnxbiN2+cVg0qW5+jgFxFHLJMj2qEm3ots0xgBvaSuomZXKKGmMnVqSxutyTmtihKT2oeZoU25hlUWscc3VMYUsCZk1wfY51n03VxvVWHnug0m6uINtFg3hl+/a6RRLWknlp1i0njnINhyOm3AI423sC4h8OK88b3iNEzD7w5pfzSkA3LMHAxotSsKazm9a640Mjhg0YOpxQeuIApUOlzcgtOYwNO1nTKQGUeWfriMg0/6AGM46Ghd+uKoqvmmFkS+n5Bbqj9G2Hhgpz9ULmNHTGX0NWmiJGPDLtDVC5eiPjQbxsflGfHh9IMoPp5xbzk0fZXIB/1c2NC1dDpE9g9HnYUxnOqOdywMTzgAB1+RDa1EXtQMSCDp4/HzgD9KsPmfg9dF8ymaE7WdARplek2ImC548Ge2d7kPPp9wFB10gBSGwGyyHJ3/70msLD/lDFahiigAL5uEToMvWXoUHZTlcQ/N/ynzD+3/KeKyQYa+9N7wmqj/apCKy4qBkpF1KgiKVV7+VVFR1odaV06aX38wXmpflKsPZ27jDfCXdaZktcTOWaGW9GaUkMRVDsBjhdQmy+2rClz0tr76BIrimU5FbmZebOfmY1+BgJ3yLKctDTzkfMgORbtnVgGqUrZoQyF/UkdKslvsjup3lvoJ3pcO/LSNRwr3NuEAMzAM2D80uiTwJ/x52NeCB26XKaiDST/Mhe9NkXpZ9Iu/TzZCO/lhW3BlYFbStdKjkzNg1bYAW2XrDmPz3m0WeHQiQwD3ybwsfgcVU4uWrhHkBNiMhkwioBKU92Jivj5xV35DPAORbq8xiQ2XgBSUsQxl3a7g6E2XwVx0ltTHJ6L2o1K6xJRGVB/yMGSFX8mUGSFDJi89HRkxg7ZdkVwdGSqahFQlhzBWiPTlCB+0yHzWMhs3lJ6/cikE88cNq+Ua4XrawIoL90DDKlfAXxpqO0rh0KtFE8NeU+vBrXUoextrlrIKkT1D2zcFNvpW4WNW/oh1thRwoEooXmH4pVSwmmn0JbWlhvy6+STc0NfTvvvG9ENWVEX0fPw/QZ+rUBEqhH8aQQDN0nFNCP35hKRmwRzFrvVfmGmfa1aqaAumAvgq8nNAvrpvbXwZwV5FvDMqcFOnjCNljwRE8qpeMLUi/A296QJayDNRTqWaGSJKESB+1yWMJXeBbJEGt8VVS3A3OqbzTBP+EUtUkvfbMEsL0gFp0W4Ja3tzX1nAoa1Q9ExMN72zFkNbE/CFOVdtoYjby0ZZBiGPgVMvB7YTRT5nY5n7tnUgzm/mxOgAJRJJTul5MMFYwgfzFm3+UDfowiKjSmHYowhcZTwwmepwhK6Lnv6tMJQKJwhQtBSpqUyh4UJ3FlHYbAQfY/SkpaV/kahuCxzZjXdxQPyrL2nK2nvqepwj6lVkIYhJ9y6jfOX2Dgf02o2DIA4SFk5FziHJ31DW92f0QI6zPHZvEoZ+guEIfGW1XOsP4b/DONzrvTfiP9lhfst8RJCLZ8fzVOukjT3GTwCv82+uakdjoOlfXN9NBhzwmq9b67dWrdDq/ci++aqvAcwKHNXd+in466Ou3LrQbbiS9Z8MlmlFKW889YrGFNV9ADt9zVMFatj8xhNWSJ35bOpJ3+JKcdhrTjr5c4pnhdnaXIWpKOsjrI6ymqgrOxcoTL2IQhqUt4pd1USFRtXfis7griEbCG1L1O93KnEM2OqwXlS1WtMzGS08vyEzGgVUU1RlCwJ2vhs8wnHLitz0KyMk8WQg610pM2TdNcjh0WtKkujNr2EJZr7xt7nDhZ87pZs1rR4R1utaE6XWrN9ZhubgBFzsahEAG85WXtITsheNr3FVLhG+KENLTTv/Xa0cLa0IB+fyuHSqArJpQPQl0kDxwXwuRy+si57c/Ykh68KOdTjv78gZQmMfc9bqnXphu60xIujsnkn9JWiMjslbeg3Pb39GwyVp6DOAuQtTk4V1vwnf5tpfzaQj2DJs4JjsEGXaYx5asdZjS63eIzc4nSF57TSrU/n8w1f55Msrvg38PHN2CnAj61OzhWOZB02XagoVn80LEeH+nShopiTISP9I7zE3KUL95/DTNCSrhQPkhew/W0EWa7wK7cRi0ItnPaAu3ENiYG3mAUofRHBeMyxipg6wrCjHSp/L08bKk5HmJWA3OOLmyRA0mL2rZvx9CH78lL9w/8= -------------------------------------------------------------------------------- /SA/Context/graphic-system-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Context/graphic-system-02.png -------------------------------------------------------------------------------- /SA/Context/graphic-system-02.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml 3 | !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml 4 | ' uncomment the following line and comment the first to use locally 5 | '!include 6 | '!include 7 | 8 | 'LAYOUT_TOP_DOWN() 9 | 'LAYOUT_AS_SKETCH() 10 | 'LAYOUT_WITH_LEGEND() 11 | 12 | Person(user, "User", "An Android User.") 13 | 14 | System_Boundary(client, "Application") { 15 | Container_Boundary(high, "Business Level") { 16 | Container(logic, "Logic and Algorithm", "JAVA, C++, Python", $descr="Logic Level of Application.") 17 | } 18 | Container_Boundary(framework, "Android Framework") { 19 | Container(renderer, "Renderer", "C++ : hwui, skia", $descr="Rendering module of Application.") 20 | Container(composer, "Composer Client", "C++", $descr="Content Committer of Application.") 21 | } 22 | } 23 | System(server, "SurfaceFlinger", "Android Graphic Server.") 24 | 25 | System_Ext(gpu, "GPU", "3D Component.") 26 | System_Ext(compositor, "HWComposer", "2D Component.") 27 | 28 | Lay_R(renderer, composer) 29 | Lay_R(composer, server) 30 | Lay_R(gpu, compositor) 31 | 32 | Rel_D(user, logic, "Uses") 33 | Rel_D(logic, renderer, "Uses") 34 | Rel_D(logic, composer, "Uses") 35 | Rel_R(composer, server, "Request") 36 | Rel_L(server, composer, "Respond") 37 | Rel_D(renderer, gpu, "Uses") 38 | Rel(server, gpu, "Uses") 39 | Rel_D(server, compositor, "Uses") 40 | 41 | SHOW_LEGEND() 42 | 43 | /' 44 | box "Analysis Objective" 45 | participant composer 46 | participant server 47 | end box 48 | '/ 49 | 50 | @enduml 51 | -------------------------------------------------------------------------------- /SA/Context/graphic-system-02a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Context/graphic-system-02a.png -------------------------------------------------------------------------------- /SA/Context/graphic-system-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Context/graphic-system-03.png -------------------------------------------------------------------------------- /SA/Context/graphic-system-03.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | '!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml 3 | !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml 4 | !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml 5 | ' uncomment the following line and comment the first to use locally 6 | '!include 7 | '!include 8 | '!include 9 | 10 | 'LAYOUT_TOP_DOWN() 11 | 'LAYOUT_AS_SKETCH() 12 | 'LAYOUT_WITH_LEGEND() 13 | 14 | Container_Boundary(framework, "Android Framework") { 15 | Container(renderer, "Renderer", "C++ : hwui, skia", $descr="Rendering module of Application.") 16 | Container(composer, "Composer Client", "C++", $descr="Content Committer of Application.") 17 | Container(window, "Window", "C++") 18 | } 19 | System(server, "SurfaceFlinger", "Android Graphic Server.") 20 | Container(layer, "Layer", "C++") 21 | 22 | System_Ext(gpu, "GPU", "3D Component.") 23 | System_Ext(compositor, "HWComposer", "2D Component.") 24 | 25 | Lay_R(renderer, composer) 26 | Lay_R(composer, server) 27 | 'Lay_R(gpu, compositor) 28 | 29 | Rel_R(composer, server, "Request") 30 | Rel_L(server, composer, "Respond") 31 | Rel_D(renderer, window, "Uses") 32 | Rel_D(composer, window, "Uses") 33 | Rel_D(window, gpu, "Uses") 34 | Rel_D(server, layer, "Uses") 35 | Rel_D(layer, compositor, "Uses") 36 | 37 | SHOW_LEGEND() 38 | 39 | @enduml 40 | -------------------------------------------------------------------------------- /SA/Context/graphic-system-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/SA/Context/graphic-system-04.png -------------------------------------------------------------------------------- /SA/Context/graphic-system-04.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | '!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml 3 | !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml 4 | !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml 5 | ' uncomment the following line and comment the first to use locally 6 | '!include 7 | '!include 8 | '!include 9 | 10 | 'LAYOUT_TOP_DOWN() 11 | 'LAYOUT_AS_SKETCH() 12 | 'LAYOUT_WITH_LEGEND() 13 | 14 | Container_Boundary(framework, "Android Framework") { 15 | 'Container_Boundary(producer, "Producer") { 16 | Component(window, "Window", "C++") 17 | Component(free, "Free Buffer", "C++") 18 | '} 19 | } 20 | Container_Boundary(server, "SurfaceFlinger", "Android Graphic Server.") { 21 | 'Container_Boundary(queue, "Queue") { 22 | Component(buffer_queue, "BufferQueue", "C++") 23 | Component(back, "Back Buffer", "C++") 24 | Component(front, "Front Buffer", "C++") 25 | '} 26 | 'Container_Boundary(consumer, "Consumer") { 27 | Component(layer, "Layer", "C++") 28 | Component(frame, "Frame Buffer", "C++") 29 | '} 30 | } 31 | 32 | 'Lay_R(framework, server) 33 | 'Lay_R(producer, queue) 34 | 'Lay_R(queue, consumer) 35 | Lay_R(window, buffer_queue) 36 | Lay_R(buffer_queue, layer) 37 | Lay_D(window, free) 38 | Lay_D(buffer_queue, back) 39 | Lay_D(buffer_queue, front) 40 | Lay_D(layer, frame) 41 | 42 | Rel_R(window, buffer_queue, "queue()") 43 | Rel_L(buffer_queue, window, "dequeue()") 44 | Rel_R(buffer_queue, layer, "acquire()") 45 | Rel_L(layer, buffer_queue, "release()") 46 | Rel_D(window, free, "Uses") 47 | Rel_D(buffer_queue, back, "Uses") 48 | Rel_D(buffer_queue, front, "Uses") 49 | Rel_D(layer, frame, "Uses") 50 | Rel_L(back, free, "(same buffer)") 51 | Rel_R(front, frame, "(same buffer)") 52 | 53 | SHOW_LEGEND() 54 | 55 | @enduml 56 | -------------------------------------------------------------------------------- /SA/README.md: -------------------------------------------------------------------------------- 1 | # 从软件架构分析 Android 图形系统 2 | * * * 3 | 4 | # 前言 5 | 6 | 今天所使用的 Android 图形系统的基本框架是在 Android 4.1 的时候引入的,进化到今天已经十分复杂。这是一个迷宫一样的庞大系统,要想掌握它的架构并理解其中的运行原理,是一件十分困难的事情。但是,如果我们使用一些软件架构可视化的工具去分析它,则可以从中学习到很多关于软件设计的知识。 7 | 8 | 本系列文章试图从自顶向下的方向分析 Android 图形系统的架构,从而使读者从实例出发掌握设计大型软件架构的要点,并为将来设计出类似的系统做准备。 9 | 10 | 俗话说,软件架构师就是那种不写一行代码,不懂开发,就知道写写画画忽悠人的岗位。所以本系列也尽可能不出现一行代码,尽量看图说话瞎忽悠。 11 | 12 | # [所要研究的对象](Context/Analysis-Objective.md) 13 | 14 | # [重大技术决策](Container/Container-01.md) 15 | 16 | 17 | -------------------------------------------------------------------------------- /document/client-design/Android Game SDK.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/client-design/Android Game SDK.pdf -------------------------------------------------------------------------------- /document/client-design/High refresh rate rendering on Android.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/client-design/High refresh rate rendering on Android.pdf -------------------------------------------------------------------------------- /document/client-design/client-design.md: -------------------------------------------------------------------------------- 1 | # Android 的图形系统客户端的设计 2 | * * * 3 | 4 | # 应用程序的绘图流程 5 | 6 | 从以 Buffer Queue 为中心的 Producer-Consumer 模式看,客户端的绘图流程大致分为: 7 | ``` 8 | A. 绘图阶段 9 | 1. lock buffer 10 | 2. render buffer 11 | 3. unlock buffer 12 | B. 提交阶段 13 | 1. queue buffer 14 | 2. dequeue buffer 15 | ``` 16 | 17 | 这个绘图流程,不论是对于 CPU 绘图,还是 GPU 绘图,或者是 codec 解码视频,都是一样。不同的硬件只是在 render buffer 时所用的方法不一样,但是都有 lock / unlock / queue / dequeue buffer 这些调用序列。 18 | 19 | 对于 EGL/OpenGLES 程序,一个绘图循环的结束的标志,就是调用了 eglSwapBuffers() 函数。该函数在底层就会执行 queue front buffer / dequeue back buffer 这一对调用序列。front buffer 入队,意味着刚被渲染好的帧被提交给显示服务器,将被显示到屏幕上。back buffer 出队,意味着有新的缓冲区提供给应用做渲染,将做为下一帧显示。显示服务器,在 Android 显示系统里就是 surfaceflinger service。 20 | 21 | 严格地说,应用程序的绘图循环可以有自己的节拍,节拍也可以不规律。显示服务器都要应付各种异常情况。但是,如果应用程序的绘图循环的节拍如果和显示服务器同步,听从显示服务器的指挥,则会使得应用程序的画面更顺滑流畅。 22 | 23 | 这样的编程需要了解 2 个方面的内容: 24 | * Choreographer 25 | * Frame Pacing Library 26 | 27 | # Choreographer 28 | 29 | Choreographer 用以协调动画、输入和绘图的时间安排。 30 | 31 | Choreographer 从显示子系统接收定时脉冲(例如垂直同步信号 VSYNC),做为显示系统的一部分被触发,然后为显示下一帧调度任务。 32 | 33 | 应用程序通常使用动画框架或视图层次结构中更高级别的抽象来间接地与 Choreographer 交互。 34 | 35 | Choreographer 的引入,主要是基于 HW VSYNC,给应用程序的渲染动作在恰当的时机提供一个 VSYNC 事件。也就是 VSYNC 事件到来的时候,就是应用程序的渲染并提交帧的时机。对于 EGL/OpenGLES 程序,以调用 eglSwapBuffers() 函数表示为一个循环的结束。显示子系统通过对 VSYNC 信号周期的调整,来控制每一帧绘制操作的时机。 36 | 37 | 为了使得显示更加顺滑流畅,新版本的 Android 显示系统要能应付更高刷新率的情况,如 90Hz / 120 Hz 等。在 Android 11 以后,还要能处理应用可变刷新率。这时应用程序不能再做刷新率为 60Hz 这个假设。实现新功能需要做不少工作,挑战更大。具体见[ High refresh rate rendering on Android ](https://android-developers.googleblog.com/2020/04/high-refresh-rate-rendering-on-android.html)一文的说明。 38 | 39 | 一般关于 Choreographer 的文档都是说明位于客户端的 JAVA 层的代码。Choreographer 框架分布于 Producer-Consumer 模式的两端,是一个运行关系很复杂的系统。要理解 Android 显示系统就必须对 Choreographer 框架的设计有了解。Choreographer 框架的具体工作原理见《Android 的图形系统的总体设计》的[ VSYNC 模块的设计](../general-design/VSYNC.md)中的内容。 40 | 41 | # Frame Pacing Library 42 | 43 | Android Frame Pacing 库以前称为 Swappy,是 Android 游戏 SDK 的一部分。它帮助使用 OpenGL 和 Vulkan 的游戏在 Android 上采用正确的帧速度并实现平滑渲染。 44 | 45 | 帧间隔(Frame pacing)将游戏逻辑和渲染循环与操作系统的显示子系统和底层显示硬件的同步。Android 显示子系统的设计是为了避免某些视觉瑕疵,比如撕裂。显示子系统通过执行以下操作来避免撕裂: 46 | * 内部缓存过去的帧 47 | * 检测延迟的帧提交 48 | * 当检测到延迟帧时继续显示当前帧 49 | 50 | 不一致的帧显示时间是由于游戏的渲染循环以不同于本机显示硬件支持的速率运行所导致的。当游戏的渲染循环对于底层显示硬件运行得太慢,导致显示时间不一致时,就会出现问题。例如,当以 30 fps 的速度运行的游戏试图在本机支持 60 fps 的设备上进行渲染时,游戏的渲染循环会导致重复帧在屏幕上多停留 16ms。这种类型的断开会在帧时间上造成大量不一致,如 33ms、16ms、49ms 等等。过于复杂的场景进一步加剧了这个问题,因为它们会导致错过帧。 51 | 52 | Frame Pacing 库执行以下任务: 53 | * 弥补由于游戏打顿造成的短帧(图像的显示时长不够)。 54 | + 添加显示示时间戳,以便帧能够按时而不是提前显示。 55 | + 使用显示时间戳扩展 EGL_ANDROID_presentation_time 和 VK_GOOGLE_display_timing。 56 | * 对打顿和延迟的长帧(图像的显示时间过长)使用同步栅栏。 57 | + 向应用程序注入等待操作。这样可以让显示管道跟上,而不是让负荷增大。 58 | + 使用同步同步栅栏(EGL_KHR_fence_sync 和 VkFence)。 59 | * 如果你的设备支持多种刷新率,选择合适的刷新率以提供灵活和流畅的显示。 60 | + 使用[ frame stats ](https://developer.android.com/games/sdk/frame-pacing/#frame_stats)提供帧状态信息,以便进行调试和分析。 61 | 62 | # 代码复用 63 | 64 | 应用程序要想在 C++ 层复用 Android 的图形系统,如 ANativeWindow,则需要了解 Window 更多的概念。 65 | 66 | 在图形系统中,Window 这个概念实际上分为联系紧密的两层。在上层,Window 是做为输入输出的聚合对象提供给应用。在下层,Window 是做为可绘图的对象提供给应用。 67 | 68 | 对于上层概念,就有了 Widget / layout / input focus / event process 这些概念。再往上堆叠的就是 GTK / QT 这些被称之为图形库、控件库的东西。 69 | 70 | 对于下层概念,对应的就是 Cairo / Skia / hwui 这些被称之为渲染库的东西。渲染库只是单纯地渲染图像,不会处理输入事件。 71 | 72 | 对于 ANativeWindow,也只能单纯地用于渲染图像,没有输入焦点,光标处理这些东西。Android 的图形系统,上层概念是在 JAVA 层完成的。如果要想在 C++ 层复用 Android 的图形系统,则需要用 C++ 代码补齐这些东西,然后再往上移植 GTK / QT 这些图形库、控件库。这样,原先的 Linux 世界里的东西就可以在 Android 中运行起来。 73 | 74 | # 参考文件 75 | 76 | 1. [Graphics Architecture](https://source.android.com/devices/graphics/architecture) 77 | 1. [Developer Reference : Choreographer](https://developer.android.com/reference/android/view/Choreographer) 78 | 1. [NDK Reference : Choreographer](https://developer.android.com/ndk/reference/group/choreographer) 79 | 1. [Frame Pacing Library Overview](https://source.android.com/devices/graphics/frame-pacing) 80 | 1. [High refresh rate rendering on Android](https://android-developers.googleblog.com/2020/04/high-refresh-rate-rendering-on-android.html) 81 | 1. [Android Game SDK](https://android-developers.googleblog.com/2019/12/android-game-sdk.html) 82 | 1. [Not all 120Hz smartphone displays are made equally — here’s why](https://www.androidauthority.com/120hz-displays-1112345/) 83 | 1. [Android 基于 Choreographer 的渲染机制详解](https://zhuanlan.zhihu.com/p/87954949) 84 | 1. [Android Choreographer 源码分析](https://www.jianshu.com/p/996bca12eb1d/) 85 | 86 | -------------------------------------------------------------------------------- /document/contents.md: -------------------------------------------------------------------------------- 1 | # 第一章 前言 2 | 3 | # 第二章 [基本原理与设计思路](original-design/original-design.md) 4 | 5 | # 第三章 [按照设计模式进行设计](pattern-design/pattern-design.md) 6 | 7 | # 第四章 [Android 的图形系统的简略设计](brief-design/brief-design.md) 8 | 9 | # 第五章 [Android 的图形系统的 HAL 接口与约定](hal-design/hal-module.md) 10 | 11 | # 第六章 [Android 的图形系统的 HIDL 接口与约定](hidl-design/hidl-design.md) 12 | 13 | # 第七章 [Android 的图形系统的 Framework 接口与约定](framework-design/framework-design.md) 14 | 15 | # 第八章 [Android 的图形系统客户端的设计](client-design/client-design.md) 16 | 17 | # 第九章 [Android 的图形系统的总体设计](general-design/general-design.md) 18 | 19 | # 第十章 [Android 的图形系统服务端的设计](server-design/server-design.md) 20 | 21 | # SurfaceFlinger 所使用的算法 22 | # 用 Systrace 剖析图形系统性能 23 | # Android 的图形系统的 HAL 接口的实现 24 | # Android 的图形系统的复用 25 | 26 | -------------------------------------------------------------------------------- /document/framework-design/BufferQueue-00.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.6a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 11 | -2025 5850 0 5850 0 6750 -2025 6750 -2025 5850 12 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 13 | 675 5850 2700 5850 2700 6750 675 6750 675 5850 14 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 15 | 2700 5850 4725 5850 4725 6750 2700 6750 2700 5850 16 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 17 | 4725 5850 6750 5850 6750 6750 4725 6750 4725 5850 18 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 19 | 6750 5850 8775 5850 8775 6750 6750 6750 6750 5850 20 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 21 | 8775 5850 10800 5850 10800 6750 8775 6750 8775 5850 22 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 23 | 10800 5850 12825 5850 12825 6750 10800 6750 10800 5850 24 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 25 | 12825 5850 14850 5850 14850 6750 12825 6750 12825 5850 26 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 27 | 14850 5850 16875 5850 16875 6750 14850 6750 14850 5850 28 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 29 | 0 0 1.00 60.00 120.00 30 | 17550 6300 16875 6300 31 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 32 | -2700 4275 18225 4275 33 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 34 | -2025 1800 0 1800 0 2700 -2025 2700 -2025 1800 35 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 36 | 675 1800 2700 1800 2700 2700 675 2700 675 1800 37 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 38 | 2700 1800 4725 1800 4725 2700 2700 2700 2700 1800 39 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 40 | 4725 1800 6750 1800 6750 2700 4725 2700 4725 1800 41 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 42 | 6750 1800 8775 1800 8775 2700 6750 2700 6750 1800 43 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 44 | 8775 1800 10800 1800 10800 2700 8775 2700 8775 1800 45 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 46 | 10800 1800 12825 1800 12825 2700 10800 2700 10800 1800 47 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 48 | 12825 1800 14850 1800 14850 2700 12825 2700 12825 1800 49 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 50 | 14850 1800 16875 1800 16875 2700 14850 2700 14850 1800 51 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 52 | -2025 1800 -2025 -225 53 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 54 | 16875 1800 16875 -225 55 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 56 | 12825 1800 12825 1125 57 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 58 | 10800 1800 10800 1125 59 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 60 | 8775 1800 8775 1125 61 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 62 | 675 1800 675 225 63 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 64 | 0 0 1.00 60.00 120.00 65 | 0 0 1.00 60.00 120.00 66 | 12825 1350 16875 1350 67 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 68 | 0 0 1.00 60.00 120.00 69 | 0 0 1.00 60.00 120.00 70 | 8775 1350 10800 1350 71 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 72 | 0 0 1.00 60.00 120.00 73 | 0 0 1.00 60.00 120.00 74 | 675 1350 8775 1350 75 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 76 | 0 0 1.00 60.00 120.00 77 | 0 0 1.00 60.00 120.00 78 | 675 450 16875 450 79 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 80 | 0 0 1.00 60.00 120.00 81 | 0 0 1.00 60.00 120.00 82 | -2025 0 16875 0 83 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 84 | 0 0 1.00 60.00 120.00 85 | 17550 2250 16875 2250 86 | 4 0 0 50 -1 0 12 0.0000 4 150 660 15075 6300 slot 00#\001 87 | 4 0 0 50 -1 0 12 0.0000 4 150 660 13050 6300 slot 01#\001 88 | 4 0 0 50 -1 0 12 0.0000 4 150 660 11025 6300 slot 02#\001 89 | 4 0 0 50 -1 0 12 0.0000 4 150 660 9000 6300 slot 03#\001 90 | 4 0 0 50 -1 0 12 0.0000 4 150 660 6975 6300 slot 04#\001 91 | 4 0 0 50 -1 0 12 0.0000 4 150 660 4950 6300 slot 05#\001 92 | 4 0 0 50 -1 0 12 0.0000 4 150 660 2925 6300 slot 06#\001 93 | 4 0 0 50 -1 0 12 0.0000 4 150 660 900 6300 slot 07#\001 94 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 15075 6525 buffer: ALLOC\001 95 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 13050 6525 buffer: ALLOC\001 96 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 11025 6525 buffer: ALLOC\001 97 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 9000 6525 buffer: ALLOC\001 98 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 6975 6525 buffer: NULL\001 99 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 4950 6525 buffer: NULL\001 100 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 2925 6525 buffer: NULL\001 101 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 900 6525 buffer: NULL\001 102 | 4 0 0 50 -1 0 12 0.0000 4 150 660 -1800 6300 slot 63#\001 103 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 -1800 6525 buffer: NULL\001 104 | 4 0 0 50 -1 0 12 0.0000 4 150 975 -2475 4050 Server side\001 105 | 4 0 0 50 -1 0 12 0.0000 4 195 1275 -2475 3825 SurfaceFlinger\001 106 | 4 0 0 50 -1 0 12 0.0000 4 150 900 -2475 4725 Client side\001 107 | 4 0 0 50 -1 0 12 0.0000 4 195 990 -2475 4950 Application\001 108 | 4 0 0 50 -1 0 12 0.0000 4 150 810 -3600 4275 Linux OS\001 109 | 4 0 0 50 -1 0 12 0.0000 4 150 1380 17550 6300 Surface::mSlots\001 110 | 4 0 0 50 -1 0 12 0.0000 4 150 660 15075 2250 slot 00#\001 111 | 4 0 0 50 -1 0 12 0.0000 4 150 660 11025 2250 slot 02#\001 112 | 4 0 0 50 -1 0 12 0.0000 4 150 660 9000 2250 slot 03#\001 113 | 4 0 0 50 -1 0 12 0.0000 4 150 660 6975 2250 slot 04#\001 114 | 4 0 0 50 -1 0 12 0.0000 4 150 660 4950 2250 slot 05#\001 115 | 4 0 0 50 -1 0 12 0.0000 4 150 660 2925 2250 slot 06#\001 116 | 4 0 0 50 -1 0 12 0.0000 4 150 660 900 2250 slot 07#\001 117 | 4 0 0 50 -1 0 12 0.0000 4 150 660 -1800 2250 slot 63#\001 118 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 -1800 2475 state: FREE\001 119 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 900 2475 state: FREE\001 120 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 2925 2475 state: FREE\001 121 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 4950 2475 state: FREE\001 122 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 6975 2475 state: FREE\001 123 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 9000 2475 state: FREE\001 124 | 4 0 0 50 -1 0 12 0.0000 4 195 1680 11025 2475 state: DEQUEUED\001 125 | 4 0 0 50 -1 0 12 0.0000 4 195 1395 15075 2475 state: QUEUED\001 126 | 4 0 0 50 -1 0 12 0.0000 4 150 660 13050 2250 slot 01#\001 127 | 4 0 0 50 -1 0 12 0.0000 4 195 1395 13050 2475 state: QUEUED\001 128 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 9225 1125 mFreeBuffers\001 129 | 4 0 0 50 -1 0 12 0.0000 4 150 645 9225 1350 size = 1\001 130 | 4 0 0 50 -1 0 12 0.0000 4 195 1425 13500 1350 mQueue size = 2\001 131 | 4 0 0 50 -1 0 12 0.0000 4 195 3495 13050 900 if producer is EGL, only allows one item.\001 132 | 4 0 0 50 -1 0 12 0.0000 4 150 1680 3150 1350 mFreeSlots size = 4\001 133 | 4 0 0 50 -1 0 12 0.0000 4 150 2580 6750 450 mDefaultMaxBufferCount = 8\001 134 | 4 0 0 50 -1 0 12 0.0000 4 195 2595 6750 0 NUM_BUFFER_SLOTS = 64\001 135 | 4 0 0 50 -1 0 12 0.0000 4 195 1920 675 -1125 mQueue = [ 00#, 01# ]\001 136 | 4 0 0 50 -1 0 12 0.0000 4 195 1965 675 -675 mFreeBuffers = [ 03# ]\001 137 | 4 0 0 50 -1 0 12 0.0000 4 195 3015 675 -225 mFreeSlots = [ 04#, 05#, 06#, 07# ]\001 138 | 4 0 0 50 -1 0 12 0.0000 4 195 2250 17550 2250 BufferQueueCore::mSlots\001 139 | 4 0 0 50 -1 0 12 0.0000 4 90 315 225 2250 ***\001 140 | 4 0 0 50 -1 0 12 0.0000 4 90 315 225 6300 ***\001 141 | -------------------------------------------------------------------------------- /document/framework-design/BufferQueue-01.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.6a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 11 | -2025 5850 0 5850 0 6750 -2025 6750 -2025 5850 12 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 13 | 675 5850 2700 5850 2700 6750 675 6750 675 5850 14 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 15 | 2700 5850 4725 5850 4725 6750 2700 6750 2700 5850 16 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 17 | 4725 5850 6750 5850 6750 6750 4725 6750 4725 5850 18 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 19 | 6750 5850 8775 5850 8775 6750 6750 6750 6750 5850 20 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 21 | 8775 5850 10800 5850 10800 6750 8775 6750 8775 5850 22 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 23 | 10800 5850 12825 5850 12825 6750 10800 6750 10800 5850 24 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 25 | 12825 5850 14850 5850 14850 6750 12825 6750 12825 5850 26 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 27 | 14850 5850 16875 5850 16875 6750 14850 6750 14850 5850 28 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 29 | 0 0 1.00 60.00 120.00 30 | 17550 6300 16875 6300 31 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 32 | -2700 4275 18225 4275 33 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 34 | 675 1800 2700 1800 2700 2700 675 2700 675 1800 35 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 36 | 2700 1800 4725 1800 4725 2700 2700 2700 2700 1800 37 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 38 | 4725 1800 6750 1800 6750 2700 4725 2700 4725 1800 39 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 40 | 6750 1800 8775 1800 8775 2700 6750 2700 6750 1800 41 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 42 | 8775 1800 10800 1800 10800 2700 8775 2700 8775 1800 43 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 44 | 10800 1800 12825 1800 12825 2700 10800 2700 10800 1800 45 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 46 | 12825 1800 14850 1800 14850 2700 12825 2700 12825 1800 47 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 48 | 14850 1800 16875 1800 16875 2700 14850 2700 14850 1800 49 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 50 | -2025 1800 -2025 -225 51 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 52 | 16875 1800 16875 -225 53 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 54 | 8775 1800 8775 1125 55 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 56 | 675 1800 675 225 57 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 58 | 0 0 1.00 60.00 120.00 59 | 0 0 1.00 60.00 120.00 60 | 675 1350 8775 1350 61 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 62 | 0 0 1.00 60.00 120.00 63 | 0 0 1.00 60.00 120.00 64 | 675 450 16875 450 65 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 66 | 0 0 1.00 60.00 120.00 67 | 0 0 1.00 60.00 120.00 68 | -2025 0 16875 0 69 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 70 | 0 0 1.00 60.00 120.00 71 | 17550 2250 16875 2250 72 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 73 | 14850 1800 14850 1125 74 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 75 | 0 0 1.00 60.00 120.00 76 | 11700 3150 11700 2700 77 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 78 | 0 0 1.00 60.00 120.00 79 | 15750 3150 15750 2700 80 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 81 | 0 0 1.00 60.00 120.00 82 | 11700 7200 11700 6750 83 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 84 | 0 0 1.00 60.00 120.00 85 | 9675 3600 9675 2700 86 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 87 | 10800 1800 10800 1125 88 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 89 | 0 0 1.00 60.00 120.00 90 | 0 0 1.00 60.00 120.00 91 | 10800 1350 14850 1350 92 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 93 | 0 0 1.00 60.00 120.00 94 | 9675 7200 9675 6750 95 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 96 | -2025 1800 0 1800 0 2700 -2025 2700 -2025 1800 97 | 4 0 0 50 -1 0 12 0.0000 4 150 660 15075 6300 slot 00#\001 98 | 4 0 0 50 -1 0 12 0.0000 4 150 660 13050 6300 slot 01#\001 99 | 4 0 0 50 -1 0 12 0.0000 4 150 660 11025 6300 slot 02#\001 100 | 4 0 0 50 -1 0 12 0.0000 4 150 660 9000 6300 slot 03#\001 101 | 4 0 0 50 -1 0 12 0.0000 4 150 660 6975 6300 slot 04#\001 102 | 4 0 0 50 -1 0 12 0.0000 4 150 660 4950 6300 slot 05#\001 103 | 4 0 0 50 -1 0 12 0.0000 4 150 660 2925 6300 slot 06#\001 104 | 4 0 0 50 -1 0 12 0.0000 4 150 660 900 6300 slot 07#\001 105 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 15075 6525 buffer: ALLOC\001 106 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 13050 6525 buffer: ALLOC\001 107 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 11025 6525 buffer: ALLOC\001 108 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 9000 6525 buffer: ALLOC\001 109 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 6975 6525 buffer: NULL\001 110 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 4950 6525 buffer: NULL\001 111 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 2925 6525 buffer: NULL\001 112 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 900 6525 buffer: NULL\001 113 | 4 0 0 50 -1 0 12 0.0000 4 150 660 -1800 6300 slot 63#\001 114 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 -1800 6525 buffer: NULL\001 115 | 4 0 0 50 -1 0 12 0.0000 4 150 975 -2475 4050 Server side\001 116 | 4 0 0 50 -1 0 12 0.0000 4 195 1275 -2475 3825 SurfaceFlinger\001 117 | 4 0 0 50 -1 0 12 0.0000 4 150 900 -2475 4725 Client side\001 118 | 4 0 0 50 -1 0 12 0.0000 4 195 990 -2475 4950 Application\001 119 | 4 0 0 50 -1 0 12 0.0000 4 150 810 -3600 4275 Linux OS\001 120 | 4 0 0 50 -1 0 12 0.0000 4 150 1380 17550 6300 Surface::mSlots\001 121 | 4 0 0 50 -1 0 12 0.0000 4 150 660 15075 2250 slot 00#\001 122 | 4 0 0 50 -1 0 12 0.0000 4 150 660 11025 2250 slot 02#\001 123 | 4 0 0 50 -1 0 12 0.0000 4 150 660 9000 2250 slot 03#\001 124 | 4 0 0 50 -1 0 12 0.0000 4 150 660 6975 2250 slot 04#\001 125 | 4 0 0 50 -1 0 12 0.0000 4 150 660 4950 2250 slot 05#\001 126 | 4 0 0 50 -1 0 12 0.0000 4 150 660 2925 2250 slot 06#\001 127 | 4 0 0 50 -1 0 12 0.0000 4 150 660 900 2250 slot 07#\001 128 | 4 0 0 50 -1 0 12 0.0000 4 150 660 -1800 2250 slot 63#\001 129 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 -1800 2475 state: FREE\001 130 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 900 2475 state: FREE\001 131 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 2925 2475 state: FREE\001 132 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 4950 2475 state: FREE\001 133 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 6975 2475 state: FREE\001 134 | 4 0 0 50 -1 0 12 0.0000 4 150 660 13050 2250 slot 01#\001 135 | 4 0 0 50 -1 0 12 0.0000 4 195 1395 13050 2475 state: QUEUED\001 136 | 4 0 0 50 -1 0 12 0.0000 4 150 1680 3150 1350 mFreeSlots size = 4\001 137 | 4 0 0 50 -1 0 12 0.0000 4 150 2580 6750 450 mDefaultMaxBufferCount = 8\001 138 | 4 0 0 50 -1 0 12 0.0000 4 195 2595 6750 0 NUM_BUFFER_SLOTS = 64\001 139 | 4 0 0 50 -1 0 12 0.0000 4 195 3015 675 -225 mFreeSlots = [ 04#, 05#, 06#, 07# ]\001 140 | 4 0 0 50 -1 0 12 0.0000 4 195 2250 17550 2250 BufferQueueCore::mSlots\001 141 | 4 0 0 50 -1 0 12 0.0000 4 195 3450 10350 3375 IGraphicBufferProducer::queueBuffer()\001 142 | 4 0 0 50 -1 0 12 0.0000 4 195 3660 8325 3825 IGraphicBufferProducer::dequeueBuffer()\001 143 | 4 0 0 50 -1 0 12 0.0000 4 195 1425 12150 1350 mQueue size = 2\001 144 | 4 0 0 50 -1 0 12 0.0000 4 195 1395 11025 2475 state: QUEUED\001 145 | 4 0 0 50 -1 0 12 0.0000 4 195 1635 15075 2475 state: ACQUIRED\001 146 | 4 0 0 50 -1 0 12 0.0000 4 195 1680 9000 2475 state: DEQUEUED\001 147 | 4 0 0 50 -1 0 12 0.0000 4 195 2220 8550 7425 Surface::dequeueBuffer()\001 148 | 4 0 0 50 -1 0 12 0.0000 4 195 2010 11025 7425 Surface::queueBuffer()\001 149 | 4 0 0 50 -1 0 12 0.0000 4 195 1920 675 -1125 mQueue = [ 01#, 02# ]\001 150 | 4 0 0 50 -1 0 12 0.0000 4 195 1950 675 -675 mFreeBuffers = empty\001 151 | 4 0 0 50 -1 0 12 0.0000 4 90 315 225 2475 ***\001 152 | 4 0 0 50 -1 0 12 0.0000 4 90 315 225 6525 ***\001 153 | 4 0 0 50 -1 0 12 0.0000 4 195 3675 14400 3375 IGraphicBufferConsumer::acquireBuffer()\001 154 | -------------------------------------------------------------------------------- /document/framework-design/BufferQueue-02.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.6a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 11 | -2025 5850 0 5850 0 6750 -2025 6750 -2025 5850 12 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 13 | 675 5850 2700 5850 2700 6750 675 6750 675 5850 14 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 15 | 2700 5850 4725 5850 4725 6750 2700 6750 2700 5850 16 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 17 | 4725 5850 6750 5850 6750 6750 4725 6750 4725 5850 18 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 19 | 6750 5850 8775 5850 8775 6750 6750 6750 6750 5850 20 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 21 | 8775 5850 10800 5850 10800 6750 8775 6750 8775 5850 22 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 23 | 10800 5850 12825 5850 12825 6750 10800 6750 10800 5850 24 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 25 | 12825 5850 14850 5850 14850 6750 12825 6750 12825 5850 26 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 27 | 14850 5850 16875 5850 16875 6750 14850 6750 14850 5850 28 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 29 | 0 0 1.00 60.00 120.00 30 | 17550 6300 16875 6300 31 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 32 | -2700 4275 18225 4275 33 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 34 | 675 1800 2700 1800 2700 2700 675 2700 675 1800 35 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 36 | 2700 1800 4725 1800 4725 2700 2700 2700 2700 1800 37 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 38 | 4725 1800 6750 1800 6750 2700 4725 2700 4725 1800 39 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 40 | 6750 1800 8775 1800 8775 2700 6750 2700 6750 1800 41 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 42 | 8775 1800 10800 1800 10800 2700 8775 2700 8775 1800 43 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 44 | 10800 1800 12825 1800 12825 2700 10800 2700 10800 1800 45 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 46 | 12825 1800 14850 1800 14850 2700 12825 2700 12825 1800 47 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 48 | 14850 1800 16875 1800 16875 2700 14850 2700 14850 1800 49 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 50 | -2025 1800 -2025 -225 51 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 52 | 16875 1800 16875 -225 53 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 54 | 675 1800 675 225 55 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 56 | 0 0 1.00 60.00 120.00 57 | 0 0 1.00 60.00 120.00 58 | 675 1350 6750 1350 59 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 60 | 0 0 1.00 60.00 120.00 61 | 0 0 1.00 60.00 120.00 62 | 675 450 16875 450 63 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 64 | 0 0 1.00 60.00 120.00 65 | 0 0 1.00 60.00 120.00 66 | -2025 0 16875 0 67 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 68 | 0 0 1.00 60.00 120.00 69 | 17550 2250 16875 2250 70 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 71 | 14850 1800 14850 1125 72 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 73 | 0 0 1.00 60.00 120.00 74 | 9675 7200 9675 6750 75 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 76 | -2025 1800 0 1800 0 2700 -2025 2700 -2025 1800 77 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 78 | 0 0 1.00 60.00 120.00 79 | 7650 7200 7650 6750 80 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 81 | 0 0 1.00 60.00 120.00 82 | 7650 3600 7650 2700 83 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 84 | 0 0 1.00 60.00 120.00 85 | 9675 3150 9675 2700 86 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 87 | 6750 1800 6750 1125 88 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 89 | 8775 1800 8775 1125 90 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 91 | 0 0 1.00 60.00 120.00 92 | 0 0 1.00 60.00 120.00 93 | 8775 1350 14850 1350 94 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 95 | 0 0 1.00 60.00 120.00 96 | 7875 4725 7875 2700 97 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 98 | 0 0 1.00 60.00 120.00 99 | 7875 4950 7875 5850 100 | 4 0 0 50 -1 0 12 0.0000 4 150 660 15075 6300 slot 00#\001 101 | 4 0 0 50 -1 0 12 0.0000 4 150 660 13050 6300 slot 01#\001 102 | 4 0 0 50 -1 0 12 0.0000 4 150 660 11025 6300 slot 02#\001 103 | 4 0 0 50 -1 0 12 0.0000 4 150 660 9000 6300 slot 03#\001 104 | 4 0 0 50 -1 0 12 0.0000 4 150 660 6975 6300 slot 04#\001 105 | 4 0 0 50 -1 0 12 0.0000 4 150 660 4950 6300 slot 05#\001 106 | 4 0 0 50 -1 0 12 0.0000 4 150 660 2925 6300 slot 06#\001 107 | 4 0 0 50 -1 0 12 0.0000 4 150 660 900 6300 slot 07#\001 108 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 15075 6525 buffer: ALLOC\001 109 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 13050 6525 buffer: ALLOC\001 110 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 11025 6525 buffer: ALLOC\001 111 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 9000 6525 buffer: ALLOC\001 112 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 4950 6525 buffer: NULL\001 113 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 2925 6525 buffer: NULL\001 114 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 900 6525 buffer: NULL\001 115 | 4 0 0 50 -1 0 12 0.0000 4 150 660 -1800 6300 slot 63#\001 116 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 -1800 6525 buffer: NULL\001 117 | 4 0 0 50 -1 0 12 0.0000 4 150 975 -2475 4050 Server side\001 118 | 4 0 0 50 -1 0 12 0.0000 4 195 1275 -2475 3825 SurfaceFlinger\001 119 | 4 0 0 50 -1 0 12 0.0000 4 150 900 -2475 4725 Client side\001 120 | 4 0 0 50 -1 0 12 0.0000 4 195 990 -2475 4950 Application\001 121 | 4 0 0 50 -1 0 12 0.0000 4 150 810 -3600 4275 Linux OS\001 122 | 4 0 0 50 -1 0 12 0.0000 4 150 1380 17550 6300 Surface::mSlots\001 123 | 4 0 0 50 -1 0 12 0.0000 4 150 660 15075 2250 slot 00#\001 124 | 4 0 0 50 -1 0 12 0.0000 4 150 660 11025 2250 slot 02#\001 125 | 4 0 0 50 -1 0 12 0.0000 4 150 660 9000 2250 slot 03#\001 126 | 4 0 0 50 -1 0 12 0.0000 4 150 660 6975 2250 slot 04#\001 127 | 4 0 0 50 -1 0 12 0.0000 4 150 660 4950 2250 slot 05#\001 128 | 4 0 0 50 -1 0 12 0.0000 4 150 660 2925 2250 slot 06#\001 129 | 4 0 0 50 -1 0 12 0.0000 4 150 660 900 2250 slot 07#\001 130 | 4 0 0 50 -1 0 12 0.0000 4 150 660 -1800 2250 slot 63#\001 131 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 -1800 2475 state: FREE\001 132 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 900 2475 state: FREE\001 133 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 2925 2475 state: FREE\001 134 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 4950 2475 state: FREE\001 135 | 4 0 0 50 -1 0 12 0.0000 4 150 660 13050 2250 slot 01#\001 136 | 4 0 0 50 -1 0 12 0.0000 4 195 1395 13050 2475 state: QUEUED\001 137 | 4 0 0 50 -1 0 12 0.0000 4 150 2580 6750 450 mDefaultMaxBufferCount = 8\001 138 | 4 0 0 50 -1 0 12 0.0000 4 195 2595 6750 0 NUM_BUFFER_SLOTS = 64\001 139 | 4 0 0 50 -1 0 12 0.0000 4 195 2250 17550 2250 BufferQueueCore::mSlots\001 140 | 4 0 0 50 -1 0 12 0.0000 4 195 1395 11025 2475 state: QUEUED\001 141 | 4 0 0 50 -1 0 12 0.0000 4 195 1635 15075 2475 state: ACQUIRED\001 142 | 4 0 0 50 -1 0 12 0.0000 4 195 1950 675 -675 mFreeBuffers = empty\001 143 | 4 0 0 50 -1 0 12 0.0000 4 90 315 225 2475 ***\001 144 | 4 0 0 50 -1 0 12 0.0000 4 90 315 225 6525 ***\001 145 | 4 0 0 50 -1 0 12 0.0000 4 195 2220 6525 7425 Surface::dequeueBuffer()\001 146 | 4 0 0 50 -1 0 12 0.0000 4 195 2010 9000 7425 Surface::queueBuffer()\001 147 | 4 0 0 50 -1 0 12 0.0000 4 195 3660 6300 3825 IGraphicBufferProducer::dequeueBuffer()\001 148 | 4 0 0 50 -1 0 12 0.0000 4 195 3450 8325 3375 IGraphicBufferProducer::queueBuffer()\001 149 | 4 0 0 50 -1 0 12 0.0000 4 150 1680 3150 1350 mFreeSlots size = 3\001 150 | 4 0 0 50 -1 0 12 0.0000 4 195 1425 11025 1350 mQueue size = 3\001 151 | 4 0 0 50 -1 0 12 0.0000 4 195 1395 9000 2475 state: QUEUED\001 152 | 4 0 0 50 -1 0 12 0.0000 4 195 1680 6975 2475 state: DEQUEUED\001 153 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 6975 6525 buffer: ALLOC\001 154 | 4 0 0 50 -1 0 12 0.0000 4 195 2595 675 -225 mFreeSlots = [ 05#, 06#, 07# ]\001 155 | 4 0 0 50 -1 0 12 0.0000 4 195 2340 675 -1125 mQueue = [ 01#, 02#, 03# ]\001 156 | 4 0 0 50 -1 0 12 0.0000 4 195 3570 6300 4950 IGraphicBufferProducer::requestBuffer()\001 157 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 7875 2925 create in server\001 158 | 4 0 0 50 -1 0 12 0.0000 4 150 1560 7875 5850 transform to client\001 159 | -------------------------------------------------------------------------------- /document/framework-design/BufferQueue-03.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.6a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 11 | -2025 5850 0 5850 0 6750 -2025 6750 -2025 5850 12 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 13 | 675 5850 2700 5850 2700 6750 675 6750 675 5850 14 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 15 | 2700 5850 4725 5850 4725 6750 2700 6750 2700 5850 16 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 17 | 4725 5850 6750 5850 6750 6750 4725 6750 4725 5850 18 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 19 | 6750 5850 8775 5850 8775 6750 6750 6750 6750 5850 20 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 21 | 8775 5850 10800 5850 10800 6750 8775 6750 8775 5850 22 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 23 | 10800 5850 12825 5850 12825 6750 10800 6750 10800 5850 24 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 25 | 12825 5850 14850 5850 14850 6750 12825 6750 12825 5850 26 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 27 | 14850 5850 16875 5850 16875 6750 14850 6750 14850 5850 28 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 29 | 0 0 1.00 60.00 120.00 30 | 17550 6300 16875 6300 31 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 32 | -2700 4275 18225 4275 33 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 34 | 675 1800 2700 1800 2700 2700 675 2700 675 1800 35 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 36 | 2700 1800 4725 1800 4725 2700 2700 2700 2700 1800 37 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 38 | 4725 1800 6750 1800 6750 2700 4725 2700 4725 1800 39 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 40 | 6750 1800 8775 1800 8775 2700 6750 2700 6750 1800 41 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 42 | 8775 1800 10800 1800 10800 2700 8775 2700 8775 1800 43 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 44 | 10800 1800 12825 1800 12825 2700 10800 2700 10800 1800 45 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 46 | 12825 1800 14850 1800 14850 2700 12825 2700 12825 1800 47 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 48 | 14850 1800 16875 1800 16875 2700 14850 2700 14850 1800 49 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 50 | -2025 1800 -2025 -225 51 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 52 | 16875 1800 16875 -225 53 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 54 | 675 1800 675 225 55 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 56 | 0 0 1.00 60.00 120.00 57 | 0 0 1.00 60.00 120.00 58 | 675 1350 6750 1350 59 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 60 | 0 0 1.00 60.00 120.00 61 | 0 0 1.00 60.00 120.00 62 | 675 450 16875 450 63 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 64 | 0 0 1.00 60.00 120.00 65 | 0 0 1.00 60.00 120.00 66 | -2025 0 16875 0 67 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 68 | 0 0 1.00 60.00 120.00 69 | 17550 2250 16875 2250 70 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 71 | -2025 1800 0 1800 0 2700 -2025 2700 -2025 1800 72 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 73 | 6750 1800 6750 1125 74 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 75 | 8775 1800 8775 1125 76 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 77 | 0 0 1.00 60.00 120.00 78 | 15750 3150 15750 2700 79 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 80 | 0 0 1.00 60.00 120.00 81 | 13725 3600 13725 2700 82 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 83 | 12825 1800 12825 1125 84 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 85 | 0 0 1.00 60.00 120.00 86 | 0 0 1.00 60.00 120.00 87 | 8775 1350 12825 1350 88 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 89 | 14850 1800 14850 1125 90 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 91 | 0 0 1.00 60.00 120.00 92 | 0 0 1.00 60.00 120.00 93 | 14850 1350 16875 1350 94 | 4 0 0 50 -1 0 12 0.0000 4 150 660 15075 6300 slot 00#\001 95 | 4 0 0 50 -1 0 12 0.0000 4 150 660 13050 6300 slot 01#\001 96 | 4 0 0 50 -1 0 12 0.0000 4 150 660 11025 6300 slot 02#\001 97 | 4 0 0 50 -1 0 12 0.0000 4 150 660 9000 6300 slot 03#\001 98 | 4 0 0 50 -1 0 12 0.0000 4 150 660 6975 6300 slot 04#\001 99 | 4 0 0 50 -1 0 12 0.0000 4 150 660 4950 6300 slot 05#\001 100 | 4 0 0 50 -1 0 12 0.0000 4 150 660 2925 6300 slot 06#\001 101 | 4 0 0 50 -1 0 12 0.0000 4 150 660 900 6300 slot 07#\001 102 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 15075 6525 buffer: ALLOC\001 103 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 13050 6525 buffer: ALLOC\001 104 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 11025 6525 buffer: ALLOC\001 105 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 9000 6525 buffer: ALLOC\001 106 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 4950 6525 buffer: NULL\001 107 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 2925 6525 buffer: NULL\001 108 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 900 6525 buffer: NULL\001 109 | 4 0 0 50 -1 0 12 0.0000 4 150 660 -1800 6300 slot 63#\001 110 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 -1800 6525 buffer: NULL\001 111 | 4 0 0 50 -1 0 12 0.0000 4 150 975 -2475 4050 Server side\001 112 | 4 0 0 50 -1 0 12 0.0000 4 195 1275 -2475 3825 SurfaceFlinger\001 113 | 4 0 0 50 -1 0 12 0.0000 4 150 900 -2475 4725 Client side\001 114 | 4 0 0 50 -1 0 12 0.0000 4 195 990 -2475 4950 Application\001 115 | 4 0 0 50 -1 0 12 0.0000 4 150 810 -3600 4275 Linux OS\001 116 | 4 0 0 50 -1 0 12 0.0000 4 150 1380 17550 6300 Surface::mSlots\001 117 | 4 0 0 50 -1 0 12 0.0000 4 150 660 15075 2250 slot 00#\001 118 | 4 0 0 50 -1 0 12 0.0000 4 150 660 11025 2250 slot 02#\001 119 | 4 0 0 50 -1 0 12 0.0000 4 150 660 9000 2250 slot 03#\001 120 | 4 0 0 50 -1 0 12 0.0000 4 150 660 6975 2250 slot 04#\001 121 | 4 0 0 50 -1 0 12 0.0000 4 150 660 4950 2250 slot 05#\001 122 | 4 0 0 50 -1 0 12 0.0000 4 150 660 2925 2250 slot 06#\001 123 | 4 0 0 50 -1 0 12 0.0000 4 150 660 900 2250 slot 07#\001 124 | 4 0 0 50 -1 0 12 0.0000 4 150 660 -1800 2250 slot 63#\001 125 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 -1800 2475 state: FREE\001 126 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 900 2475 state: FREE\001 127 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 2925 2475 state: FREE\001 128 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 4950 2475 state: FREE\001 129 | 4 0 0 50 -1 0 12 0.0000 4 150 2580 6750 450 mDefaultMaxBufferCount = 8\001 130 | 4 0 0 50 -1 0 12 0.0000 4 195 2595 6750 0 NUM_BUFFER_SLOTS = 64\001 131 | 4 0 0 50 -1 0 12 0.0000 4 195 2250 17550 2250 BufferQueueCore::mSlots\001 132 | 4 0 0 50 -1 0 12 0.0000 4 195 1395 11025 2475 state: QUEUED\001 133 | 4 0 0 50 -1 0 12 0.0000 4 90 315 225 2475 ***\001 134 | 4 0 0 50 -1 0 12 0.0000 4 90 315 225 6525 ***\001 135 | 4 0 0 50 -1 0 12 0.0000 4 150 1680 3150 1350 mFreeSlots size = 3\001 136 | 4 0 0 50 -1 0 12 0.0000 4 195 1395 9000 2475 state: QUEUED\001 137 | 4 0 0 50 -1 0 12 0.0000 4 195 1680 6975 2475 state: DEQUEUED\001 138 | 4 0 0 50 -1 0 12 0.0000 4 150 1350 6975 6525 buffer: ALLOC\001 139 | 4 0 0 50 -1 0 12 0.0000 4 195 2595 675 -225 mFreeSlots = [ 05#, 06#, 07# ]\001 140 | 4 0 0 50 -1 0 12 0.0000 4 195 3660 14400 3375 IGraphicBufferConsumer::releaseBuffer()\001 141 | 4 0 0 50 -1 0 12 0.0000 4 195 3675 12375 3825 IGraphicBufferConsumer::acquireBuffer()\001 142 | 4 0 0 50 -1 0 12 0.0000 4 150 660 13050 2250 slot 01#\001 143 | 4 0 0 50 -1 0 12 0.0000 4 195 1635 13050 2475 state: ACQUIRED\001 144 | 4 0 0 50 -1 0 12 0.0000 4 150 1050 15075 2475 state: FREE\001 145 | 4 0 0 50 -1 0 12 0.0000 4 195 1425 10125 1350 mQueue size = 2\001 146 | 4 0 0 50 -1 0 12 0.0000 4 150 1200 15300 1125 mFreeBuffers\001 147 | 4 0 0 50 -1 0 12 0.0000 4 150 645 15300 1350 size = 1\001 148 | 4 0 0 50 -1 0 12 0.0000 4 195 1920 675 -1125 mQueue = [ 02#, 03# ]\001 149 | 4 0 0 50 -1 0 12 0.0000 4 195 1965 675 -675 mFreeBuffers = [ 00# ]\001 150 | -------------------------------------------------------------------------------- /document/framework-design/composer-design.md: -------------------------------------------------------------------------------- 1 | # Composer 的设计 2 | * * * 3 | 4 | 在 surfaceflinger service 中的重要实现类 Layer / SurfaceFlinger,声明位于这里: 5 | * frameworks/native/services/surfaceflinger/Layer.h 6 | * frameworks/native/services/surfaceflinger/SurfaceFlinger.h 7 | 8 | SurfaceFlinger 类,是图形内容的 Consumer 端。SurfaceFlinger 类暴露的接口,是一种代理模式: 9 | * ISurfaceComposer。对 SurfaceFlinger 类的代理。接口中的方法很多,这里主要关注下面几个: 10 | + createConnection():为客户端提供访问 Composer 的接口:ISurfaceComposerClient。 11 | + createDisplayEventConnection():为客户端提供访问 VSYNC 的接口:IDisplayEventConnection。 12 | * ISurfaceComposerClient:客户端访问 Composer 的接口。接口中的方法很多,这里主要关注下面几个: 13 | + createSurface() 14 | * IDisplayEventConnection: 客户端访问/管理 VSYNC 的接口。 15 | 16 | 这些接口的声明位于这里: 17 | * frameworks/native/include/gui/IDisplayEventConnection.h 18 | * frameworks/native/include/gui/ISurfaceComposer.h 19 | * frameworks/native/include/gui/ISurfaceComposerClient.h 20 | 21 | 此外,一路对应上来的硬件合成器(HWC)的接口,在 surfaceflinger 里底层的 DisplayHardware 模块里: 22 | * Composer:对应 HAL 中的 hwcomposer 接口,以及 HIDL 中的 IComposer 接口。 23 | * PowerAdvisor:对应 HAL 中的 power 接口,以及 HIDL 中的 IPower 接口。 24 | 25 | 下图是 Composer 接口的关系组合图: 26 | [Composer 接口的关系组合图](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/server-design/services_surfaceflinger_DisplayHardware_ComposerHal%20Component%20Diagram.svg) 27 | 28 | 下图是 PowerAdvisor 接口的关系组合图: 29 | [PowerAdvisor 接口的关系组合图](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/server-design/services_surfaceflinger_DisplayHardware_PowerAdvisor%20Class%20Diagram.svg) 30 | 31 | 32 | -------------------------------------------------------------------------------- /document/framework-design/framework-design.md: -------------------------------------------------------------------------------- 1 | # Android 的图形系统的 Framework 接口与约定 2 | * * * 3 | 4 | 在 Framework 层实现的接口,就是为了提供给应用程序使用。前面所讨论的 HAL 接口,以及后来新的 HIDL 接口,就是为了实现 Framework 层的接口。图形系统在 Framework 层的代码,设计上同样还是贯彻 Producer-Consumer 模式的设计思路。 5 | 6 | # Framework 代码分布 7 | 8 | 与图形相关的 Framework 代码主要分布以下目录: 9 | * frameworks/native/include/ui/ 10 | * frameworks/native/libs/ui/ 11 | * frameworks/native/include/gui/ 12 | * frameworks/native/libs/gui/ 13 | 14 | 各目录所要实现的功能如下: 15 | * "ui/" 目录主要是 ANativeWindowBuffer 接口的实现:GraphicBuffer。是在 Producer-Consumer 模式两端所用的工作介质。 16 | * "gui/" 目录主要是 ANativeWindow 接口的实现:Surface。对应的是 Producer 端。 17 | + 相对应的是 ANativeWindow 接口背后的 Queue 的实现:BufferQueue 18 | + 以及在 BufferQueue 两端跨进程的 Listener 模型的接口: 19 | - IConsumerListener 20 | - IGraphicBufferConsumer 21 | - IGraphicBufferProducer 22 | - IProducerListener 23 | + 以及在 Queue 中传输的 GraphicBuffer 的封装:BufferItem / BufferSlot; 24 | + 对于 Consumer 端如何消费 GraphicBuffer 的约定接口: 25 | - ConsumerBase 26 | - CpuConsumer 27 | - GLConsumer 28 | + 还有从 C/S 模型看,Server 端 SurfaceFlinger 对 Client 端暴露的接口: 29 | - IDisplayEventConnection 30 | - ISurfaceComposerClient 31 | - ISurfaceComposer 32 | * 在 ui / gui 目录里的接口,主要对应的是 Producer 端和 Queue 中的内容。相应的层次对应 Consumer 端的内容,在 surfaceflinger service 中,基本上都是基于 BufferQueue 的对称设计。 33 | 34 | # [Buffer 与 Window 的设计](buffer-window-design.md) 35 | 36 | # [BufferQueue 的设计](bufferqueue-design.md) 37 | 38 | # [Composer 的设计](composer-design.md) 39 | 40 | # 小结 41 | 42 | Android HAL 中和图形系统有关的,有这几方面的知识: 43 | * 面向 Application,用 GraphicBuffer 类实现 ANativeWindowBuffer 接口,用 Surface 类实现 ANativeWindow 接口。EGL / OpenGLES 模块是 ANativeWindowBuffer 接口和 ANativeWindow 接口最主要的使用者。 44 | * 面向 Graphic Server,用 Composer 实现合成器设备(hwc_composer_device_1_t)接口,用 FrameBufferSurface 类管理帧缓冲(Framebuffer)设备。最重要的,硬件合成器(HWC)是整个显示子系统的硬件抽象,包括显示设备,是所有 Android 合成操作的核心。 45 | 46 | # 参考文件 47 | 1. [The Android Graphics microconference](https://lwn.net/Articles/569704/) 48 | 1. [Graphics](https://source.android.com/devices/graphics/index.html) 49 | 1. [BufferQueue and gralloc](https://source.android.com/devices/graphics/arch-bq-gralloc) 50 | 1. [Android's Graphics Buffer Management System (Part II: BufferQueue)](https://www.codeproject.com/Articles/990983/Androids-Graphics-Buffer-Management-System-Part-II) 51 | 1. [Implementing the Hardware Composer HAL](https://source.android.com/devices/graphics/implement-hwc) 52 | 53 | # 详细类图列表 54 | 55 | 下图是 GraphicBuffer 的类图: 56 | ![GraphicBuffer 的类图](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/framework-design/ui_GraphicBuffer%20Class%20Diagram.svg) 57 | 58 | 下图是 Surface 的类图: 59 | ![Surface 的类图](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/framework-design/gui_Surface%20Class%20Diagram.svg) 60 | 61 | -------------------------------------------------------------------------------- /document/general-design/DispSync-01.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 6 9450 1800 12600 5175 11 | 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 11025 3600 1575 1575 11025 3600 12600 3600 12 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 13 | 0 0 1.00 60.00 120.00 14 | 11025 3600 12600 3600 15 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 16 | 0 0 1.00 60.00 120.00 17 | 11025 3600 11025 2025 18 | 4 0 0 50 -1 0 12 0.0000 4 135 255 10935 1935 "0"\001 19 | 4 0 0 50 -1 0 12 0.0000 4 135 360 11700 3600 r = 1\001 20 | -6 21 | 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6075 3600 1575 1575 6075 3600 7650 3600 22 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 23 | 0 0 1.00 60.00 120.00 24 | 6075 3600 6795 2205 25 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 26 | 0 0 1.00 60.00 120.00 27 | 6075 3600 5400 2205 28 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 29 | 5400 3555 5400 2205 30 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 31 | 6075 3600 4500 3600 32 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 33 | 0 0 1.00 60.00 120.00 34 | 6075 3600 6075 2025 35 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 36 | 6795 3600 6795 2250 37 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 38 | 0 0 1.00 60.00 120.00 39 | 6075 3600 7650 3600 40 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 41 | 0 0 1.00 60.00 120.00 42 | 11019 3597 11739 2202 43 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 44 | 0 0 1.00 60.00 120.00 45 | 11017 3605 10342 2210 46 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 47 | 0 0 1.00 60.00 120.00 48 | 11025 3600 12150 2475 49 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 50 | 0 0 1.00 60.00 120.00 51 | 11025 3600 10575 2115 52 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 53 | 0 0 1.00 60.00 120.00 54 | 11025 3600 11475 2115 55 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 56 | 0 0 1.00 60.00 120.00 57 | 11700 1800 11520 2025 58 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 59 | 0 0 1.00 60.00 120.00 60 | 8775 900 14175 900 61 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 62 | 11475 900 11475 225 63 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 64 | 9225 900 9225 225 65 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 66 | 13725 900 13725 225 67 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 68 | 11925 900 11925 450 69 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 70 | 0 0 1.00 60.00 120.00 71 | 0 0 1.00 60.00 120.00 72 | 11475 315 13725 315 73 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 74 | 0 0 1.00 60.00 120.00 75 | 0 0 1.00 60.00 120.00 76 | 11475 540 11925 540 77 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 78 | 11925 540 12825 540 79 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 80 | 9675 900 9675 450 81 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 82 | 0 0 1.00 60.00 120.00 83 | 0 0 1.00 60.00 120.00 84 | 9225 315 11475 315 85 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 86 | 0 0 1.00 60.00 120.00 87 | 10035 360 11003 1785 88 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 89 | 0 0 1.00 60.00 120.00 90 | 11250 0 11475 225 91 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 92 | 0 0 1.00 60.00 120.00 93 | 11925 900 12150 1125 94 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 95 | 0 0 1.00 60.00 120.00 96 | 11700 1620 11700 945 97 | 4 0 0 50 -1 0 12 0.0000 4 165 570 6750 2925 sin(1#)\001 98 | 4 0 0 50 -1 0 12 0.0000 4 165 570 4950 2925 sin(2#)\001 99 | 4 0 0 50 -1 0 12 0.0000 4 165 600 5400 3825 cos(2#)\001 100 | 4 0 0 50 -1 0 12 0.0000 4 165 600 6210 3825 cos(1#)\001 101 | 4 0 0 50 -1 0 12 0.0000 4 180 825 6570 2025 sample 1#\001 102 | 4 0 0 50 -1 0 12 0.0000 4 135 255 5985 1935 "0"\001 103 | 4 0 0 50 -1 0 12 0.0000 4 135 360 6930 3600 r = 1\001 104 | 4 0 0 50 -1 0 12 0.0000 4 180 1935 5175 4500 average = 0, mPhase = 0\001 105 | 4 0 0 50 -1 0 12 0.0000 4 135 210 12150 2475 1#\001 106 | 4 0 0 50 -1 0 12 0.0000 4 135 210 11700 2160 2#\001 107 | 4 0 0 50 -1 0 12 0.0000 4 135 210 10485 2070 3#\001 108 | 4 0 0 50 -1 0 12 0.0000 4 135 210 10125 2205 4#\001 109 | 4 0 0 50 -1 0 12 0.0000 4 135 615 11475 1800 mPhase\001 110 | 4 0 0 50 -1 0 12 0.0000 4 135 675 12150 225 mPeriod\001 111 | 4 0 0 50 -1 0 12 0.0000 4 135 615 12150 540 mPhase\001 112 | 4 0 0 50 -1 0 12 0.0000 4 135 675 9900 225 mPeriod\001 113 | 4 0 0 50 -1 0 12 0.0000 4 135 420 13950 900 Time\001 114 | 4 0 0 50 -1 0 12 0.0000 4 180 870 10125 1350 map to 2PI\001 115 | 4 0 0 50 -1 0 12 0.0000 4 180 825 4950 2025 sample 2#\001 116 | 4 0 0 50 -1 0 12 0.0000 4 180 1950 5175 4275 sample 1# = - sample 2#\001 117 | 4 0 0 50 -1 0 12 0.0000 4 180 2460 10575 -450 DispSync : mPeriod & mPhase\001 118 | 4 0 0 50 -1 0 12 0.0000 4 135 1005 11025 0 HW VSYNC\001 119 | 4 0 0 50 -1 0 12 0.0000 4 135 975 11925 1350 SW VSYNC\001 120 | -------------------------------------------------------------------------------- /document/general-design/DispSync-02.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 11 | 0 0 1.00 60.00 120.00 12 | 1350 4275 10800 4275 13 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 14 | 0 0 1.00 60.00 120.00 15 | 1350 6075 10800 6075 16 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 17 | 1800 6075 1800 5175 18 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 19 | 3825 2925 3825 3375 2700 3375 2700 2925 3825 2925 20 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 21 | 5625 3600 5625 4050 4275 4050 4275 3600 5625 3600 22 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 23 | 5850 5400 5850 5850 1800 5850 1800 5400 5850 5400 24 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 25 | 9900 5400 9900 5850 5850 5850 5850 5400 9900 5400 26 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 27 | 7875 2925 7875 3375 6750 3375 6750 2925 7875 2925 28 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 29 | 9675 3600 9675 4050 8325 4050 8325 3600 9675 3600 30 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 31 | 5850 6075 5850 5175 32 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 33 | 9900 6075 9900 5175 34 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 35 | 2250 4275 2250 3375 36 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 37 | 6300 4275 6300 3375 38 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 39 | 10350 4275 10350 3375 40 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 41 | 2250 3330 2250 2250 42 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 43 | 2700 2925 2700 2475 44 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 45 | 4275 3600 4275 2250 46 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 47 | 0 0 1.00 60.00 120.00 48 | 0 0 1.00 60.00 120.00 49 | 2250 2565 2700 2565 50 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 51 | 630 2565 2250 2565 52 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 53 | 0 0 1.00 60.00 120.00 54 | 0 0 1.00 60.00 120.00 55 | 2250 2340 4275 2340 56 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 57 | 0 0 1.00 60.00 120.00 58 | 6750 2925 6750 2250 59 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 60 | 0 0 1.00 60.00 120.00 61 | 8325 3600 8325 2250 62 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 63 | 1800 4500 1800 4950 64 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 65 | 2250 4500 2250 4950 66 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 67 | 0 0 1.00 60.00 120.00 68 | 0 0 1.00 60.00 120.00 69 | 1800 4725 2250 4725 70 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 71 | 2250 4725 3825 4725 72 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 73 | 5850 4725 5850 5130 74 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 75 | 0 0 1.00 60.00 120.00 76 | 5625 4725 5625 5130 77 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 78 | 5625 4950 5850 4950 79 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 80 | 0 0 1.00 60.00 120.00 81 | 5850 4950 9675 4950 82 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 83 | 0 0 1.00 60.00 120.00 84 | 5175 4950 5625 4950 85 | 4 0 0 50 -1 0 12 0.0000 4 135 1005 450 6075 HW VSYNC\001 86 | 4 0 0 50 -1 0 12 0.0000 4 135 975 450 4275 SW VSYNC\001 87 | 4 0 0 50 -1 0 12 0.0000 4 180 1185 450 3825 SurfaceFlinger\001 88 | 4 0 0 50 -1 0 12 0.0000 4 180 975 450 3150 Application\001 89 | 4 0 0 50 -1 0 12 0.0000 4 180 690 2925 3150 Drawing\001 90 | 4 0 0 50 -1 0 12 0.0000 4 135 885 4500 4050 Frame N+1\001 91 | 4 0 0 50 -1 0 12 0.0000 4 180 630 450 5625 Display\001 92 | 4 0 0 50 -1 0 12 0.0000 4 180 1575 2700 5625 Presenting Frame N\001 93 | 4 0 0 50 -1 0 12 0.0000 4 180 1875 6750 5625 Presenting Frame N + 1\001 94 | 4 0 0 50 -1 0 12 0.0000 4 135 840 2925 3375 Frane N+1\001 95 | 4 0 0 50 -1 0 12 0.0000 4 180 690 6975 3150 Drawing\001 96 | 4 0 0 50 -1 0 12 0.0000 4 135 885 6975 3375 Frame N+2\001 97 | 4 0 0 50 -1 0 12 0.0000 4 135 885 8550 4050 Frame N+2\001 98 | 4 0 0 50 -1 0 12 0.0000 4 180 1800 2430 2250 sfVsyncPhaseOffsetNs\001 99 | 4 0 0 50 -1 0 12 0.0000 4 180 1635 675 2475 vsyncPhaseOffsetNs\001 100 | 4 0 0 50 -1 0 12 0.0000 4 180 1230 6075 2250 VSYNC trigger\001 101 | 4 0 0 50 -1 0 12 0.0000 4 180 1485 7650 2250 SF VSYNC trigger\001 102 | 4 0 0 50 -1 0 12 0.0000 4 165 1545 2250 4725 mPhase, almost = 0\001 103 | 4 0 0 50 -1 0 12 0.0000 4 135 420 10800 4275 Time\001 104 | 4 0 0 50 -1 0 12 0.0000 4 135 420 10800 6075 Time\001 105 | 4 0 0 50 -1 0 12 0.0000 4 180 1065 4500 3825 Compositing\001 106 | 4 0 0 50 -1 0 12 0.0000 4 180 1065 8550 3825 Compositing\001 107 | 4 0 0 50 -1 0 12 0.0000 4 180 1515 5175 4725 Retire fence signal\001 108 | 4 0 0 50 -1 0 12 0.0000 4 180 4920 6075 4950 PRESENT_TIME_OFFSET_FROM_VSYNC_NS, always = 0\001 109 | -------------------------------------------------------------------------------- /document/general-design/DispSync-03.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 6 10800 5850 11250 6075 11 | 4 0 0 50 -1 0 12 0.0000 4 135 420 10800 6075 Time\001 12 | -6 13 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 14 | 0 0 1.00 60.00 120.00 15 | 1350 4275 10800 4275 16 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 17 | 0 0 1.00 60.00 120.00 18 | 1350 6075 10800 6075 19 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 20 | 2250 4275 2250 3375 21 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 22 | 6300 4275 6300 3375 23 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 24 | 10350 4275 10350 3375 25 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 26 | 6075 3600 6075 4050 2700 4050 2700 3600 6075 3600 27 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 28 | 5850 2925 5850 3375 3150 3375 3150 2925 5850 2925 29 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 30 | 3150 2925 3150 2025 31 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 32 | 2700 3600 2700 2700 33 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 34 | 2250 3285 2250 2475 35 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 36 | 0 0 1.00 60.00 120.00 37 | 0 0 1.00 60.00 120.00 38 | 2250 2790 2700 2790 39 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 40 | 0 0 1.00 60.00 120.00 41 | 0 0 1.00 60.00 120.00 42 | 2250 2565 3150 2565 43 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 44 | 225 2790 2250 2790 45 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 46 | 10125 3600 10125 4050 6750 4050 6750 3600 10125 3600 47 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 48 | 0 0 1.00 60.00 120.00 49 | 6750 3600 6750 2700 50 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 51 | 9900 2925 9900 3375 7200 3375 7200 2925 9900 2925 52 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 53 | 0 0 1.00 60.00 120.00 54 | 7200 2925 7200 2475 55 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 56 | 10350 3330 10350 2025 57 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 58 | 0 0 1.00 60.00 120.00 59 | 0 0 1.00 60.00 120.00 60 | 3150 2115 10350 2115 61 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 62 | 450 2565 2250 2565 63 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 64 | 2475 6075 2475 5175 65 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 66 | 6525 5400 6525 5850 2475 5850 2475 5400 6525 5400 67 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 68 | 10575 5400 10575 5850 6525 5850 6525 5400 10575 5400 69 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 70 | 6525 6075 6525 5175 71 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 72 | 10575 6075 10575 5175 73 | 2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 74 | 14625 5400 14625 5850 10575 5850 10575 5400 14625 5400 75 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 76 | 2475 4500 2475 4950 77 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 78 | 2250 4500 2250 4950 79 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 80 | 2250 4725 2475 4725 81 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 82 | 0 0 1.00 60.00 120.00 83 | 2475 4725 4050 4725 84 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 85 | 0 0 1.00 60.00 120.00 86 | 1800 4725 2250 4725 87 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 88 | 6525 4725 6525 5130 89 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 90 | 0 0 1.00 60.00 120.00 91 | 6300 4725 6300 5130 92 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 93 | 6300 4950 6525 4950 94 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 95 | 0 0 1.00 60.00 120.00 96 | 6525 4950 10350 4950 97 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 98 | 0 0 1.00 60.00 120.00 99 | 5850 4950 6300 4950 100 | 4 0 0 50 -1 0 12 0.0000 4 135 1005 450 6075 HW VSYNC\001 101 | 4 0 0 50 -1 0 12 0.0000 4 135 975 450 4275 SW VSYNC\001 102 | 4 0 0 50 -1 0 12 0.0000 4 180 1185 450 3825 SurfaceFlinger\001 103 | 4 0 0 50 -1 0 12 0.0000 4 180 975 450 3150 Application\001 104 | 4 0 0 50 -1 0 12 0.0000 4 180 630 450 5625 Display\001 105 | 4 0 0 50 -1 0 12 0.0000 4 135 420 10800 4275 Time\001 106 | 4 0 0 50 -1 0 12 0.0000 4 135 885 3825 4050 Frame N+1\001 107 | 4 0 0 50 -1 0 12 0.0000 4 180 690 4050 3150 Drawing\001 108 | 4 0 0 50 -1 0 12 0.0000 4 135 840 4050 3375 Frane N+2\001 109 | 4 0 0 50 -1 0 12 0.0000 4 180 1635 585 2475 vsyncPhaseOffsetNs\001 110 | 4 0 0 50 -1 0 12 0.0000 4 135 885 7875 4050 Frame N+2\001 111 | 4 0 0 50 -1 0 12 0.0000 4 180 690 8100 3150 Drawing\001 112 | 4 0 0 50 -1 0 12 0.0000 4 135 885 8100 3375 Frame N+3\001 113 | 4 0 0 50 -1 0 12 0.0000 4 180 1230 6975 2475 VSYNC trigger\001 114 | 4 0 0 50 -1 0 12 0.0000 4 180 1485 5625 2700 SF VSYNC trigger\001 115 | 4 0 0 50 -1 0 12 0.0000 4 180 5460 4050 2025 (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))\001 116 | 4 0 0 50 -1 0 12 0.0000 4 180 1800 450 2745 sfVsyncPhaseOffsetNs\001 117 | 4 0 0 50 -1 0 12 0.0000 4 180 1065 3825 3825 Compositing\001 118 | 4 0 0 50 -1 0 12 0.0000 4 180 1065 7875 3825 Compositing\001 119 | 4 0 0 50 -1 0 12 0.0000 4 180 1575 3375 5625 Presenting Frame N\001 120 | 4 0 0 50 -1 0 12 0.0000 4 180 1875 7425 5625 Presenting Frame N + 1\001 121 | 4 0 0 50 -1 0 12 0.0000 4 180 1875 11475 5625 Presenting Frame N + 2\001 122 | 4 0 0 50 -1 0 12 0.0000 4 165 1545 2475 4725 mPhase, almost = 0\001 123 | 4 0 0 50 -1 0 12 0.0000 4 180 1515 5850 4725 Retire fence signal\001 124 | 4 0 0 50 -1 0 12 0.0000 4 180 4920 6750 4950 PRESENT_TIME_OFFSET_FROM_VSYNC_NS, always = 0\001 125 | -------------------------------------------------------------------------------- /document/general-design/DispSync-04.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 11 | 0 0 1.00 60.00 120.00 12 | 1350 4275 10800 4275 13 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 14 | 2250 4275 2250 3375 15 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 16 | 6300 4275 6300 3375 17 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 18 | 10350 4275 10350 3375 19 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 20 | 3150 3825 3150 4275 21 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 22 | 6750 3825 6750 4275 23 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 24 | 0 0 1.00 60.00 120.00 25 | 0 0 1.00 60.00 120.00 26 | 6300 3915 6750 3915 27 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 28 | 0 0 1.00 60.00 120.00 29 | 7425 3150 6795 3780 30 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 31 | 6750 3915 9000 3915 32 | 4 0 0 50 -1 0 12 0.0000 4 135 975 450 4275 SW VSYNC\001 33 | 4 0 0 50 -1 0 12 0.0000 4 135 420 10800 4275 Time\001 34 | 4 0 0 50 -1 0 12 0.0000 4 165 750 2925 4500 now(last)\001 35 | 4 0 0 50 -1 0 12 0.0000 4 135 1965 2925 3600 if now < nextEventTime\001 36 | 4 0 0 50 -1 0 12 0.0000 4 180 2205 2925 3825 goto sleep until targetTime\001 37 | 4 0 0 50 -1 0 12 0.0000 4 165 1035 6525 4500 now(current)\001 38 | 4 0 0 50 -1 0 12 0.0000 4 180 3045 7425 3150 get a list of callback and invoke them\001 39 | 4 0 0 50 -1 0 12 0.0000 4 135 1185 1800 3150 lastEventTime\001 40 | 4 0 0 50 -1 0 12 0.0000 4 135 1260 5850 3150 nextEventTime\001 41 | 4 0 0 50 -1 0 12 0.0000 4 180 885 5850 3375 targetTime\001 42 | 4 0 0 50 -1 0 12 0.0000 4 180 2070 6975 3825 wakeupLatency <= 0.5ms\001 43 | 4 0 0 50 -1 0 12 0.0000 4 180 2310 6975 4050 Linux real-time performance\001 44 | 4 0 0 50 -1 0 12 0.0000 4 180 2040 2925 3375 waked up by other signal\001 45 | -------------------------------------------------------------------------------- /document/general-design/DispSync-04.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 19 | 20 | 22 | 23 | 25 | 26 | 28 | 29 | 31 | 32 | 34 | 35 | 37 | 38 | 39 | 40 | 43 | 44 | 45 | 47 | 48 | 50 | 51 | 53 | 54 | 55 | 56 | 59 | 60 | 61 | 63 | 64 | 66 | 67 | 69 | 70 | SW VSYNC 71 | 72 | Time 73 | 74 | now(last) 75 | 76 | if now < nextEventTime 77 | 78 | goto sleep until targetTime 79 | 80 | now(current) 81 | 82 | get a list of callback and invoke them 83 | 84 | lastEventTime 85 | 86 | nextEventTime 87 | 88 | targetTime 89 | 90 | wakeupLatency <= 0.5ms 91 | 92 | Linux real-time performance 93 | 94 | waked up by other signal 95 | 96 | 97 | -------------------------------------------------------------------------------- /document/general-design/DispSync-05.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7b 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 11 | 1 1 1.00 60.00 120.00 12 | 1125 3600 9900 3600 13 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 14 | 2925 2700 2925 3600 15 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 16 | 7425 2700 7425 3600 17 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 18 | 3600 2700 3600 3600 19 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 20 | 6075 2700 6075 3600 21 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 22 | 1 1 1.00 60.00 120.00 23 | 1 1 1.00 60.00 120.00 24 | 2925 2925 3600 2925 25 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 26 | 9225 2700 9225 3600 27 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 28 | 2925 1800 2925 2250 29 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 30 | 9225 1800 9225 2250 31 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 32 | 1 1 1.00 60.00 120.00 33 | 1 1 1.00 60.00 120.00 34 | 2925 2025 9225 2025 35 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 36 | 1 1 1.00 60.00 120.00 37 | 1125 4950 9900 4950 38 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 39 | 8775 4050 8775 4950 40 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 41 | 2475 4050 2475 4950 42 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 43 | 2925 3825 2925 4275 44 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 45 | 1 1 1.00 60.00 120.00 46 | 1 1 1.00 60.00 120.00 47 | 2475 4185 2925 4185 48 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 49 | 1 1 1.00 60.00 120.00 50 | 1 1 1.00 60.00 120.00 51 | 6075 2925 7425 2925 52 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 53 | 2925 2925 1800 2925 54 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 55 | 1 1 1.00 60.00 120.00 56 | 1 1 1.00 60.00 120.00 57 | 2475 4500 8775 4500 58 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 59 | 1800 4185 2475 4185 60 | 4 0 0 50 -1 0 12 0.0000 4 180 1350 7200 2700 mPendingPeriod\001 61 | 4 0 0 50 -1 0 12 0.0000 4 135 1395 3375 2700 mIntendedPeriod\001 62 | 4 0 0 50 -1 0 12 0.0000 4 135 675 2475 2700 mPeriod\001 63 | 4 0 0 50 -1 0 12 0.0000 4 135 1425 5625 2700 observed VSYNC\001 64 | 4 0 0 50 -1 0 12 0.0000 4 135 675 9000 2700 mPeriod\001 65 | 4 0 0 50 -1 0 12 0.0000 4 180 975 5400 2025 ideal period\001 66 | 4 0 0 50 -1 0 16 0.0000 4 180 570 9900 4950 Time\001 67 | 4 0 0 50 -1 0 16 0.0000 4 180 570 9900 3600 Time\001 68 | 4 0 0 50 -1 0 16 0.0000 4 180 1395 225 3600 SW VSYNC\001 69 | 4 0 0 50 -1 0 16 0.0000 4 180 1440 225 4950 HW VSYNC\001 70 | 4 0 0 50 -1 0 12 0.0000 4 180 4680 3600 3825 When the observed vsync is closed to the pending period,\001 71 | 4 0 0 50 -1 0 12 0.0000 4 180 6600 3600 4050 then we detected a period change, so reset the model, mPeriod = mPendingPeriod.\001 72 | 4 0 0 50 -1 0 12 0.0000 4 135 1155 1800 2925 observed error\001 73 | 4 0 0 50 -1 0 12 0.0000 4 135 615 1845 4140 mPhase\001 74 | 4 0 0 50 -1 0 12 0.0000 4 180 1575 5400 4500 HW VSYNC period\001 75 | -------------------------------------------------------------------------------- /document/general-design/dispsync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/general-design/dispsync.png -------------------------------------------------------------------------------- /document/general-design/general-design.md: -------------------------------------------------------------------------------- 1 | # Android 的图形系统的总体设计 2 | * * * 3 | 4 | 应用程序有自己的绘图节拍,它可以在任意时间向图形服务器提交绘图内容。图形服务器,surfaceflinger,基于 VSYNC,定期收集应用程序提交的绘图内容,合成并显示出去。于是 Android 图形系统里存在两类节拍:应用程序绘图节拍和图形显示节拍。所以 Android 图形系统的流水线是两阶段模型,每个阶段都是一个 Producer-Consumer 流程。应用程序渲染窗口,生产了新内容,交给了图形服务器。图形服务器收集多个程序提交的内容,基于 z-order,合成最终屏幕图像,实际上也生产了新内容,最终交给 HWC,显示到屏幕上。于是基于 Producer-Consumer 模式,每一类节拍对应一类 BufferQueue。 5 | 6 | 应用程序绘图节拍,每一对 Surface-Layer 存在一个 BufferQueue。图形显示节拍,每一对 RenderSurface-DisplaySurface,对应一个显示设备,存在一个 BufferQueue,只在 surfaceflinger service 内部存在, 7 | 8 | 图形显示节拍,基于 VSYNC 设计。所以首先要理解 VSYNC 模块的设计。 9 | 10 | # [VSYNC 模块的设计](VSYNC.md) 11 | 12 | # [基于接口(interface)的对称设计](symmetrical-design.md) 13 | 14 | # [两阶段(2-stage)流水线设计](2-stage.md) 15 | 16 | # 多进程协作的设计 17 | 18 | Android 图形系统,原本是简单的 C/S 架构,surfaceflinger 是图形合成显示服务器。引入 HIDL 以后,情况变得复杂,变成了多进程协作式设计。surfaceflinger 更像是居中调度的中间件,不再直接管理硬件,而是委托 HIDL 层的服务器进行管理。 19 | 20 | Android 图形系统通用的服务器位于 /system/bin/ 目录: 21 | * gpuservice - GPU 状态服务器,graphicsenv 库使用。最终是应用程序所使用的 OpenGLES 和 Vulkan 使用到。 22 | * surfaceflinger - 图形合成显示服务器。 23 | 24 | Android 图形系统的 HIDL 服务器位于 /vendor/bin/hw/ 目录: 25 | * android.hardware.graphics.allocator@2.0-service 26 | * android.hardware.graphics.composer@2.1-service 27 | 28 | Android 图形系统的 HIDL 服务器动态加载的模块位于 /system/lib64/ 目录: 29 | * android.frameworks.displayservice@1.0.so 30 | * android.frameworks.vr.composer@1.0.so 31 | * android.hardware.graphics.allocator@2.0.so 32 | * android.hardware.graphics.bufferqueue@1.0.so 33 | * android.hardware.graphics.common@1.0.so 34 | * android.hardware.graphics.common@1.1.so 35 | * android.hardware.graphics.composer@2.1.so 36 | * android.hardware.graphics.composer@2.2.so 37 | * android.hardware.graphics.mapper@2.0.so 38 | * android.hardware.graphics.mapper@2.1.so 39 | 40 | 厂商提供的本硬件定制的动态加载的模块位于 /system/lib64/vndk-*/ 目录。总的说来,HIDL 服务器管理使用 HAL 模块,是实际与硬件驱动打交道的地方。 41 | 42 | 对于应用而言,以前是向 surfaceflinger 服务器申请 GraphicBuffer,后来是向 android.hardware.graphics.allocator@2.0-service 申请。同样的,原本是 surfaceflinger 服务器管理 HWC 驱动接口并进行合成操作,后来是由 android.hardware.graphics.composer@2.1-service 进行实际的合成操作。 43 | 44 | 由此看,应用绘制画面并显示的动作,涉及到很多次跨进程的操作。于是 Android 图形系统极其依赖 OS 的 Soft-Realtime 特性。所以 Android Linux Kernel 打过 Realtime 补丁(Preempt RT patches),打开了 “PREEMPT” 特性,是完全的可抢占式内核(fully preemptible (real-time) kernel)。进程切换时间,大多数情况 < 1ms,但极限不会 < 0.1ms。 45 | 46 | 但是,函数调用切换的时间是大大小于进程切换时间好几个数量级。加上 HIDL 的引入,调用 Binder Interface 会增加调用延时。这时候需要从全局考虑多进程协作设计的优劣。 47 | 48 | Android 应用程序,最耗时的动作是对大尺寸图像的渲染。假如渲染一帧需要 5ms,而进程切换回来需要 0.5ms,则应用还需要等待 4.5ms。在这 4.5ms 中,应用可以切换到其它线程上做很多事情了。 49 | 50 | 所以,Android 图形系统是针对多核异构式的硬件系统进行设计。通过多进程多线程模式,使得 GPU / HWC / codec 这些独占硬件能批量地满负荷运行。虽然接口调用有损耗,但系统总体运行效率是大大提高了。 51 | 52 | 另外,分布式多进程协作模式,使得系统更容易升级了,并且系统健壮性更好。 53 | 54 | # 小结 55 | 56 | 图形和媒体管道可以认为是一条挂载着多个摆弄缓冲区(Buffer)的设备的流水线。同时,Android 图形系统根据驱动节拍的划分,将整个图形处理的流水线划分为多个阶段(stage),并且可以组合。每个阶段的核心,就是 BufferQueue。从应用软件生产显示内容(Content)到 SurfaceFlinger 消费内容,通常的操作,就是一个两阶段(2-stage)的生产-消费循环。 57 | 58 | 生产循环,将一个窗口某个时段的内容从应用软件,也就是客户端(Client side),送达服务端(Server side),也就是 SurfaceFlinger。从 Surface 类开始,最后到达 Layer 类。每一对 Surface-Layer 对应一个 BufferQueue。因为系统中有多个应用软件,每个软件有多个 Surface。每个进程/线程不可能协调一致,所以每个承载着内容(Content)的 GraphicBuffer,也就是帧(Frame)的到达,是异步和随机的。 59 | 60 | 消费循环,将所有在显示区域能看到内容的 Layer 进行合成。从 RenderSurface 接口(Interface)开始,最后到达 DisplaySurface 接口(Interface)。每个显示设备对应一个 BufferQueue。这阶段的工作节拍就是定时的 VSYNC 信号。FramebufferSurface 类是 DisplaySurface 接口(Interface)的一个实现。LCD 显示设备就是用 RenderSurface-FramebufferSurface 这一对生产-消费关系来表达。 61 | 62 | 因为内容的生产是随机和异步的,而内容消费,也就是显示设备的工作原理是基于 VSYNC 信号的,是定时的。如果生产和消费在一个循环里,则有可能内容的到达会打断合成操作,从而造成显示内容的撕裂;也有可能耗时的合成操作阻塞了内容的到达,从而阻塞了生产。所以为了显示顺滑,将生产-消费分成了两个阶段。同时为了显示更顺滑,生产循环和消费循环的工作节拍要用 VSYNC 信号协调,如同大马路上的红绿灯要协调一样。这就是编舞者(Choreographer)框架要解决的问题。 63 | 64 | 为了在多核异构系统中提高并行的效率,Android 系统引入了显式同步机制。在图形系统中,主要有这3类同步栅栏(Fence): 65 | * 获取栅栏(Acquire fence)。每层(Layer)一个。代表着该 GraphicBuffer 承载的内容生成结束,HWComposer 可以进行读取。 66 | * 释放栅栏(Release fence)。每层(Layer)一个。代表着 HWComposer 对内容读取完毕,该 GraphicBuffer 可以交给应用进行写入。 67 | * 退出栅栏(Retire fence)。整个图形框架就一个。代表着当前合成完的 framebuffer 已经由 HWComposer 显示到屏幕上。该信号在新版本中改名为显示栅栏(Present fence)。 68 | 69 | 所以合成服务器(HWComposer)是内容汇总的地方,同时也是同步栅栏(Fence)集中处理的地方。 70 | 71 | | No. | Fence | Producer | Consumer | 72 | |:---:|---------------|--------------------------------------------------------|---------------------------------------------------------| 73 | | 1 | Acquire fence | eglSwapBuffers() / before ANativeWindow::queueBuffer() | HWComposer::commit() / hwc_composer_device_1::set() | 74 | | 2 | Release fence | HWComposer::commit() / hwc_composer_device_1::set() | eglSwapBuffers() / after ANativeWindow::dequeueBuffer() | 75 | | 3 | Retire fence | HWComposer::commit() / hwc_composer_device_1::set() | DispSync::addPresentFence() | 76 | 77 | 所以从总的架构看,客户端(Client side)和服务端(Server side)互为 Producer-Consumer 关系。 78 | 79 | # 参考文件 80 | 1. [The Android Graphics microconference](https://lwn.net/Articles/569704/) 81 | 1. [Graphics](https://source.android.com/devices/graphics/index.html) 82 | 83 | 84 | -------------------------------------------------------------------------------- /document/general-design/symmetrical-design.md: -------------------------------------------------------------------------------- 1 | # 基于接口(interface)的对称设计 2 | * * * 3 | 4 | 从 HAL 到 Framework,Android 系统就是围绕着接口(interface)进行设计与实现。接口(interface)如同工业管线里的管道阀门,控制着数据的流量和流向。理解了接口(interface)的功能和作用,基本上就理解了系统的运作模式。 5 | 6 | # 基于接口(interface)的设计 7 | 8 | ## 跨越进程/线程的接口(Interface) 9 | 10 | 相关接口(interface)的定义,位于"frameworks/native/include/gui/"目录。前面已经做过说明。这里再次回顾以下,因为 SurfaceFlinger 都有应用到这些接口: 11 | * IConsumerListener 12 | - onFrameAvailable() 13 | - onFrameReplaced() 14 | - onBuffersReleased() 15 | - onSidebandStreamChanged() 16 | * IDisplayEventConnection 17 | - getDataChannel() 18 | - setVsyncRate() 19 | - requestNextVsync() 20 | * IGraphicBufferConsumer 21 | - acquireBuffer() 22 | - releaseBuffer() 23 | * IGraphicBufferProducer 24 | - dequeueBuffer() 25 | - queueBuffer() 26 | * IProducerListener 27 | - onBufferReleased() 28 | * ISurfaceComposerClient 29 | - createSurface() 30 | - destroySurface() 31 | * ISurfaceComposer 32 | - createConnection() 33 | - createDisplayEventConnection() 34 | - createDisplay() 35 | - destroyDisplay() 36 | 37 | | No. | Interface | Realized | Usage | 38 | |:---:|-------------------------|-------------------------|------------------------| 39 | | 1 | IConsumerListener | ProxyConsumerListener | BufferQueueProducer | 40 | | 2 | IDisplayEventConnection | EventThread::Connection | DisplayEventReceiver | 41 | | 3 | IGraphicBufferConsumer | BufferQueueConsumer | SurfaceFlingerConsumer | 42 | | 4 | IGraphicBufferProducer | BufferQueueProducer | Surface | 43 | | 5 | IProducerListener | DummyProducerListener | | 44 | | 6 | ISurfaceComposerClient | Client | SurfaceFlinger | 45 | | 7 | ISurfaceComposer | SurfaceFlinger | SurfaceFlinger | 46 | 47 | ## BufferQueue 消费端相关的接口(interface) 48 | * ConsumerBase 49 | - SubClass ConsumerListener 50 | - Create ProxyConsumerListener 51 | - Required IGraphicBufferConsumer 52 | - Required FrameAvailableListener 53 | * ConsumerListener 54 | - onFrameAvailable() 55 | - onFrameReplaced() 56 | - onBuffersReleased() 57 | - onSidebandStreamChanged() 58 | * ContentsChangedListener 59 | - SubClass FrameAvailableListener 60 | - onSidebandStreamChanged() 61 | * FrameAvailableListener 62 | - onFrameAvailable() 63 | - onFrameReplaced() 64 | 65 | | No. | Interface | Realized | Usage | 66 | |:---:|-------------------------|-------------------------|------------------------| 67 | | 1 | ConsumerBase | SurfaceFlingerConsumer | SurfaceFlinger | 68 | | 2 | ConsumerListener | ConsumerBase | IConsumerListener | 69 | | 3 | ContentsChangedListener | Layer | ConsumerListener | 70 | | 4 | FrameAvailableListener | ContentsChangedListener | ConsumerListener | 71 | | 5 | IConsumerListener | ProxyConsumerListener | BufferQueueProducer | 72 | | 6 | IGraphicBufferConsumer | BufferQueueConsumer | SurfaceFlingerConsumer | 73 | | 7 | IGraphicBufferProducer | BufferQueueProducer | Surface | 74 | | 8 | IProducerListener | DummyProducerListener | | 75 | 76 | ## 与 Display 相关的接口(interface) 77 | * DisplaySurface 78 | - beginFrame() 79 | - prepareFrame() 80 | - compositionComplete() 81 | - advanceFrame() 82 | - onFrameCommitted() 83 | * RenderEngine 84 | * hwc_composer_device_1 (v1) 85 | - prepare() 86 | - set() 87 | * hwc_procs (v1) 88 | - invalidate() 89 | - vsync() 90 | - hotplug() 91 | * hwc2_device_t (v2) 92 | - validateDisplay() 93 | - presentDisplay() 94 | 95 | | No. | Interface | Realized | Usage | 96 | |:---:|-----------------------|--------------------|----------------| 97 | | 1 | DisplaySurface | FramebufferSurface | SurfaceFlinger | 98 | | 2 | RenderEngine | GLES20RenderEngine | SurfaceFlinger | 99 | | 3 | hwc_composer_device_1 | HAL plugin | HWComposer | 100 | | 4 | hwc_procs | HWComposer | SurfaceFlinger | 101 | | 5 | hwc2_device_t | HAL plugin | HWComposer | 102 | 103 | # 对称设计 104 | 105 | ## 基于 Producer-Consumer 模型的对称设计 106 | 107 | BufferQueue 是 Android 图形流水线的中心。上面所列的各个接口都围绕 BufferQueue 来设计。它的设计是对称的。在前面分析 BufferQueue 的章节已经有过说明,这里回顾一下。 108 | 109 | 下图是以 BufferQueue 为中心的接口和类的协作图。 110 | 111 | ![BufferQueue Component Diagram](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/framework-design/gui_BufferQueue%20Component%20Diagram.svg) 112 | 113 | * BufferQueue 的设计是对称的。 114 | - Producer-Consumer 设计模式对应的是2个跨进程接口(interface):IGraphicBufferProducer & IGraphicBufferConsumer。 115 | - Listener 设计模式对应的是2个跨进程接口(interface):IProducerListener & IConsumerListener。 116 | * 为 Producer-Consumer 设计模式所设计的类是对称的。 117 | - 在客户端的接口是 ANativeWindow,对应的服务端的接口是 Layer。 118 | - 在客户端的实现类是 Surface,对应的服务端的实现类是 BufferQueueLayer。 119 | - 也就是,一对 Surface-Layer,就是一对 Producer-Consumer 关系,中间存在一个 BufferQueue。 120 | * 对 BufferQueue 的操控是对称的。 121 | - 在客户端是 Surface 调用 IGraphicBufferProducer 接口操控 BufferQueue。最常用的就是 dequeueBuffer() & queueBuffer() 这 2 个方法。 122 | - 在服务端是 SurfaceFlingerConsumer 侦听 IConsumerListener 接口的消息,然后调用 IGraphicBufferConsumer 接口操控 BufferQueue。最常用的就是 acquireBuffer() & releaseBuffer() 这 2 个方法。 123 | - 类 BufferLayerConsumer 由实现类 BufferQueueLayer 所创建。基于 C/S 模型,一个 Surface 对应一个 BufferLayerConsumer。 124 | 125 | ## 基于 Client / Server 模型的对称设计 126 | 127 | 从 UI 程序的角度看,最先需要理解的是 Client / Server 程序之间的跨进程接口(Interface)的数据流动方向。Android 图形系统,Client / Server 程序之间其实是互为 Producer-Consumer 的模式。具体见下面的类协作图: 128 | 129 | ![ISurfaceComposer Component Diagram](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/framework-design/gui_ISurfaceComposer%20Component%20Diagram.svg) 130 | 131 | 图的上半部分,是 Surface 的 Client / Server 协作图,涉及 3 个跨进程接口(Interface): 132 | * IGraphicBufferProducer 133 | * ISurfaceComposerClient 134 | * ISurfaceComposer 135 | 136 | 这其实就是内容(Content)的 Producer-Consumer 的传输路径,从 Surface 生产,经过 IGraphicBufferProducer 到达 Layer,最后到达 SurfaceFlinger 进行消费。 137 | 138 | 图的下半部分,是 VSYNC 的 Client / Server 协作图,涉及 2 个跨进程接口(Interface): 139 | * ISurfaceComposer 140 | * IDisplayEventConnection 141 | 142 | 这其实就是 VSYNC 信号的 Producer-Consumer 的传输路径,从 SurfaceFlinger 生产,经过 IDisplayEventConnection 到达 Application 进行消费。 143 | 144 | 这张图还体现了 Client / Server 两端类的对称设计。同时各层级类的生成和调用关系也是对称的。 145 | 146 | | No. | Client's Class | Interface | Server's Class | 147 | |:---:|-----------------------|-------------------------|----------------| 148 | | 1 | Surface | IGraphicBufferProducer | Layer | 149 | | 2 | SurfaceComposerClient | ISurfaceComposerClient | Client | 150 | | 3 | ComposerService | ISurfaceComposer | SurfaceFlinger | 151 | | 4 | DisplayEventReceiver | IDisplayEventConnection | EventThread | 152 | 153 | # 参考文件 154 | 1. [BufferQueue and gralloc](https://source.android.com/devices/graphics/arch-bq-gralloc) 155 | 1. [Android's Graphics Buffer Management System (Part II: BufferQueue)](https://www.codeproject.com/Articles/990983/Androids-Graphics-Buffer-Management-System-Part-II) 156 | 157 | 158 | -------------------------------------------------------------------------------- /document/hal-design/VSYNC.md: -------------------------------------------------------------------------------- 1 | # VSYNC 信号的接口与约定 2 | 3 | 对于 VSYNC 信号,在文档[[VSync信号](http://windrunnerlihuan.com/2017/05/21/VSync%E4%BF%A1%E5%8F%B7/)]中有详细的介绍。其实,现在的硬件抽象已经封装得很高级了,在 Linux OS 层面看到的 VSYNC 信号,已经不是当初 VSYNC 信号的含义了,但术语被保留了下来。一个明显的例子就是 VSYNC 信号到达的时候,软件标注为"case INVALIDATE:",其实可以理解为显示器向大家广播:屏幕上的内容已经无效了,你们赶快送新内容过来吧:hamburger:。因此,做为 Android 软件的开发人员,只需要记住,见到了 VSYNC 信号,这就表明抽象的显示屏可以用了,于是各路人马齐欢腾:fist:。 4 | 5 | 实现 VSYNC 的目标很简单:VSYNC 可将某些事件同步到显示设备的刷新周期。应用总是在 VSYNC 边界上开始绘制,而 SurfaceFlinger 总是在 VSYNC 边界上进行合成。这样可以消除卡顿,并提升图形的视觉表现。 6 | 7 | VSYNC 的接口很简单,它归属于显示设备,因此在 Hardware Composer (HWC) 接口中提供。在 HWC 接口(interface)中,VSYNC 接口就是一个函数指针,属于 hwc_procs 接口的一部分,用于指示要为 VSYNC 实现的函数: 8 | ``` 9 | int (waitForVsync*) (int64_t *timestamp) 10 | ``` 11 | 12 | LCD 显示器一般的刷新率为 60Hz,也就是大约 16.67ms 产生硬件 VSYNC 信号。而这个 VSYNC 接口关注点在于可供软件预测的时间戳。在发生 VSYNC 并返回实际 VSYNC 的时间戳之前,这个函数会处于阻塞状态。每次发生 VSYNC 时,都必须发送一条消息。客户端会以指定的间隔收到 VSYNC 时间戳,或者以 "1" 为间隔连续收到 VSYNC 时间戳。你必须实现最大延迟时间为 1ms(建议 0.5ms 或更短)的 VSYNC,因此返回的时间戳必须非常准确。 13 | 14 | 因为打开硬件 VSYNC 信号时,对手机的功耗会有影响。所以一个开发经验就是,只在必要的时候打开硬件 VSYNC 信号,采样并建立模型,预测硬件 VSYNC 信号发生的时间点,然后关闭硬件 VSYNC 信号,只使用软件 VSYNC 信号。这样对于降低手机功耗有好处。 15 | 16 | 另外,在调用 hwcomposer 模块时,还需要注意,hwc_procs 接口是由用户程序实例化并注册的。用户程序必须提供回调函数监听并处理 HWC 上报的 3 个事件: invalidate / vsync / hotplug。否则 hwcomposer 模块有可能会崩溃。 17 | 18 | 到了 hwcomposer2 模块时,用户程序可以选择监听 3 个事件中的任意一个。不监听也不会崩溃。 19 | 20 | -------------------------------------------------------------------------------- /document/hal-design/ape_fwk_graphics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/hal-design/ape_fwk_graphics.png -------------------------------------------------------------------------------- /document/hal-design/bufferqueue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/hal-design/bufferqueue.png -------------------------------------------------------------------------------- /document/hal-design/continuous_capture_activity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/hal-design/continuous_capture_activity.png -------------------------------------------------------------------------------- /document/hal-design/fence.md: -------------------------------------------------------------------------------- 1 | # 同步机制 2 | * * * 3 | 4 | 同步框架明确描述了 Android 图形系统中不同异步操作之间的依赖关系。该框架提供了一个 API,可让组件在缓冲区被释放时进行提示。该框架还允许在驱动程序之间(从内核驱动程序到用户空间驱动程序)以及在用户空间进程本身之间传递同步基元。 5 | 6 | 同步框架还允许实现方在自己的硬件组件中利用同步资源。最后,该框架还可让实现方查看图形管道,以帮助他们进行调试。 7 | 8 | Android 图形系统中的同步框架基于 Linux 的原子同步机制,数据结构和函数声明于 sync.h,实现于 sync.c。我们需要某种 OS 级别的原子同步机制来显式地管理内存缓冲区所有权的转移,从而验证内存“所有者”是否看到了内存的一致视图。 9 | 10 | # 同步栅栏(Fence) 11 | 12 | 在 Android 图形系统里,是一个多进程多线程并发的模型。在 VSYNC 的驱动下,Buffer 与 HWC 的状态和数据流动十分复杂。为了使得图形界面输出正确,而且快速和平滑,系统需要同步机制。这其中,涉及到许多概念、假设和约定。 13 | 14 | ## 问题的由来 15 | 16 | 在文档[[microconference](https://lwn.net/Articles/569704/)]里介绍了 Android 系统中的关于同步的基础设施的一些背景知识,以及为什么它会被引入,为什么对于 Android 系统它十分重要的讨论。 17 | 18 | 同步是很重要的,因为它允许在图形和媒体管道里更好地利用并行性。通常你可以认为管道作为在一个系列上摆弄缓冲区的不同设备的集合。每个步骤都要彻底完成当前任务,在它输出缓冲区到下一步骤之前。然而,在许多情况下,在每个步骤中所需要的一些开销工作,不是严格需要持有要被处理的数据。所以,在缓冲区仍然在被填充的过程中,你可以尝试并行做这些开销的步骤,例如创建缓冲区给显示器。然而,这需要有一些内部锁机制,可以让一个步骤发出信号到下一个步骤,它实际上已经完成任务的时候。步骤之间的这项协议就是“同步契约”。 19 | 20 | ## 显式同步 21 | 22 | 现在的 Android 的“同步契约”是显式同步方式。也就是,如果用户跨进程/线程使用对象,不能假设该对象是进程两端自动同步的。用户要显式地调用同步框架接口,自己确保对象在两端的同步。 23 | 24 | 显式同步是必需的,它提供了一种以同步方式获取和释放 gralloc buffer 的机制。显式同步在内核空间中实现。内核空间对象在用户空间中表示为文件描述符。显式同步允许图形缓冲区的生产方和消耗方在完成对缓冲区的处理时发出信号。这允许 Android 异步地将要读取或写入的缓冲区加入队列,并且确定另一个消耗方或生产方当前不需要它们。有关详细信息,请参阅[[同步框架](https://source.android.com/devices/graphics/index.html#synchronization_framework)]一文。 25 | 26 | 显式同步的优点包括不同设备上的行为差异较小,对调试的支持更好,并且测试指标更完善。例如,同步框架输出可以轻松指出问题区域和根本原因,而集中于 SurfaceFlinger 的演示时间戳可以显示系统的正常流程中发生事件的时间。 27 | 28 | 该通信是通过使用同步栅栏(Fence)来完成的。在请求用于消耗或生产的缓冲区时,必须使用同步栅栏(Fence)。同步框架由三个主要构造块组成:sync_timeline、sync_pt 和 sync_fence。在文档[[implement-vsync](https://source.android.com/devices/graphics/implement-vsync)]和[[Android Sync](https://blog.linuxplumbersconf.org/2014/ocw/system/presentations/2355/original/03%20-%20sync%20&%20dma-fence.pdf)]中,对此有详细的说明。 29 | 30 | 同步栅栏(Fence)是 Android 图形系统的关键部分。栅栏(Fence)允许 CPU 工作与并行的 GPU 工作相互独立进行,仅在存在真正的依赖关系时才会阻塞。 31 | 32 | 例如,当应用提交在 GPU 上生成的缓冲区时,它还将提交一个栅栏(Fence)对象;该栅栏(Fence)仅在 GPU 完成写入缓冲区的操作时才会变为有信号量状态。由于真正需要 GPU 写入完成的唯一系统部分是显示设备硬件(由 HWC HAL 抽象的硬件),因此图形通道能够通过 SurfaceFlinger 将该栅栏(Fence)与缓冲区一起传递到 HWC 设备。只有在即将显示该缓冲区之前,设备才需要实际检查栅栏(Fence)是否已经变为有信号量状态。 33 | 34 | ## 为什么需要显式的“同步契约”? 35 | 36 | Android 早期的同步契约是隐式的,并且没有很好的定义。这造成了问题。因为驱动程序编写者往往误解或着误实现同步契约,导致难以调试的问题。此外,因为契约是隐式的,并且它的实现分散在很多驱动,有些是专有的,这会让它很难修改契约以提高性能。 37 | 38 | 为了解决这些问题,Android 的显式同步机制被实现了。在 Android >= 4.2 版本以后, 使用的是一种被标准化的栅栏(Fence)机制, 这将在所有的驱动上有统一的工作方式。同步栅栏(Fence)是一个同步的框架,允许 SurfaceFlinger 建立一个时间线,并在时间线上设置同步点。其它线程和驱动程序可以阻塞在一个同步点上,并将等待直到时间线计数器已经跨越了这一点。可以有多个时间线,通过各种驱动程序管理;同步接口允许从不同的时间线合并同步点。这就是 SufaceFlinger 和 BufferQueue 流程如何管理跨多个驱动程序和进程的同步契约。 39 | 40 | 最终,显式的“同步契约”,意味着**伴随着的对象的所有权的移交**。 41 | 42 | ## 同步集成 43 | 44 | 如何将低层级同步框架与 Android 框架的不同部分(包括驱动程序)进行集成,以及彼此间如何通信?这方面有一些集成规范和参考约定。 45 | 46 | ### 集成规范 47 | 48 | 用于图形的 Android HAL 接口会遵循统一的规范,因此当文件描述符通过 HAL 接口传递时,始终会传输文件描述符的所有权。这意味着: 49 | * 如果你从同步框架收到栅栏文件描述符,就必须由你将其关闭。 50 | * 如果你将栅栏文件描述符返回到同步框架,将由框架关闭它。 51 | * 要继续使用栅栏文件描述符,你必须复制(dup)该描述符。 52 | 53 | 每当栅栏通过 BufferQueue(例如某个窗口将栅栏传递到 BufferQueue,指明其新内容何时准备就绪)时,该栅栏对象将被重命名。由于 Android 内核栅栏支持允许栅栏使用字符串作为名称,因此同步框架使用正在排队的窗口名称和缓冲区索引来命名栅栏(例如 SurfaceView:0)。这有助于进行调试来找出死锁的来源,因为名称会显示在 /d/sync 的输出和错误报告中。 54 | 55 | ### ANativeWindow 集成 56 | 57 | ANativeWindow 接口(interface)针对栅栏机制进行了升级,在方法 dequeueBuffer、queueBuffer 和 cancelBuffer 都具有栅栏参数。 58 | 59 | ### OpenGL ES 集成 60 | 61 | OpenGL ES 同步集成依赖于两个 EGL 扩展: 62 | 63 | * EGL_ANDROID_native_fence_sync。提供一种在 EGLSyncKHR 对象中包装或创建原生 Android 栅栏文件描述符的方法。 64 | 65 | * EGL_ANDROID_wait_sync。允许 GPU 端停止而不是在 CPU 中停止,使 GPU 等待 EGLSyncKHR。这与 EGL_KHR_wait_sync 扩展基本相同(有关详细信息,请参阅相关规范)。 66 | 67 | 这些扩展可以独立使用,并由 libgui 中的编译标记控制。要使用它们,请首先实现 EGL_ANDROID_native_fence_sync 扩展以及关联的内核支持。接下来,为驱动程序添加对栅栏的 ANativeWindow 支持,然后在 libgui 中启用支持以使用 EGL_ANDROID_native_fence_sync 扩展。 68 | 69 | 其次,在驱动程序中启用 EGL_ANDROID_wait_sync 扩展,并单独打开它。EGL_ANDROID_native_fence_sync 扩展包含完全不同的原生栅栏 EGLSync 对象类型,因此适用于现有 EGLSync 对象类型的扩展不一定适用于 EGL_ANDROID_native_fence 对象,以避免不必要的交互。 70 | 71 | ### Hardware Composer 集成 72 | 73 | Hardware Composer 可处理三种类型的同步栅栏(Fence): 74 | 75 | * 获取栅栏(Acquire fence)。每层(Layer)一个,在调用 HWC::set 之前设置。当 Hardware Composer 可以读取缓冲区时,该栅栏会变为有信号状态。 76 | 77 | * 释放栅栏(Release fence)。每层(Layer)一个,在 HWC::set 中由驱动程序填充。当 Hardware Composer 完成对缓冲区的读取时,该栅栏会变为有信号状态,以便框架可以再次开始将该缓冲区用于特定层。 78 | 79 | * 退出栅栏(Retire fence)。整个图形框架就一个,每次调用 HWC::set 时由驱动程序填充。HWC::set 操作会覆盖所有的层,并且当所有层的 HWC::set 操作完成时会变成有信号状态并通知框架。当在屏幕上进行下一设置操作时,退出栅栏将变为有信号状态。 80 | 81 | 退出栅栏(Retire fence)可用于确定每个帧在屏幕上的显示时长。这有助于识别延迟的位置和来源,例如卡顿的动画。另外,退出栅栏(Retire fence)上的时间戳代表着实际发生 HW VSYNC 信号的时间点。用此时间戳可以校验 SW VSYNC 的偏差。 82 | 83 | 这就是 Android 文档里提到关于 VSYNC 信号的软件锁相回路 (PLL)算法: 84 | * 绘图操作和 HWC 合成都是由 VSYNC 信号驱动。 85 | * HW VSYNC 信号太耗电,所以不常开而需要 SW VSYNC。 86 | * SW VSYNC 和实际硬件情况总是会有偏差,需要校准。 87 | * 退出栅栏(Retire fence)上的时间戳代表着实际发生 HW VSYNC 信号的时间点。用此时间戳可以校验 SW VSYNC 的偏差。 88 | * 当 Fence 时间戳校准的方法发现 SW VSYNC 的模型的误差超出阈值,将启动重新同步流程。 89 | 90 | ## HWC2 中的更改 91 | 92 | 同步栅栏紧密集成到 HWC2 中,并且按以下类别进行划分: 93 | * 获取栅栏(Acquire fence)会与输入缓冲区一起传递到 setLayerBuffer 和 setClientTarget 调用。这些栅栏表示正在等待写入缓冲区,并且必须在 HWC 客户端或设备尝试从关联缓冲区读取数据以执行合成之前变为有信号量状态。 94 | 95 | * 释放栅栏(Release fence)在调用 presentDisplay 之后使用 getReleaseFences 调用进行检索,并与将在下一次合成期间被替换的缓冲区一起传回至应用。这些栅栏表示正在等待从缓冲区读取数据,并且必须在应用尝试将新内容写入缓冲区之前变为有信号量状态。 96 | 97 | * 退出栅栏(Retire fence)作为对 presentDisplay 的调用的一部分返回,每帧一个,说明该帧的合成何时完成,或者何时不再需要上一帧的合成结果。对于物理显示设备,这是当前帧显示在屏幕上之时,而且还可以解释为在其之后可以再次安全写入客户端目标缓冲区(如果适用)的时间。对于虚拟显示设备,这是可以安全地从输出缓冲区读取数据的时间。 98 | 99 | HWC 2.0 中同步栅栏(Fence)的含义相对于以前版本的 HAL 已有很大的改变。 100 | 101 | 在 HWC v1.x 中,释放栅栏(Release fence)和退出栅栏(Retire fence)是推测性的。在帧 N 中检索到的缓冲区的释放栅栏或显示设备的退出栅栏不会先于在帧 N + 1 中检索到的栅栏变为有信号量状态。换句话说,该栅栏的含义是“不再需要你为帧 N 提供的缓冲区内容”。这是推测性的,因为在理论上,SurfaceFlinger 在帧 N 之后的一段不确定的时间内可能无法再次运行,这将使得这些栅栏在该时间段内不会变为有信号量状态。 102 | 103 | 在 HWC 2.0 中,释放栅栏(Release fence)和退出栅栏(Retire fence)是非推测性的。在帧 N 中检索到的释放栅栏或退出栅栏,将在相关缓冲区的内容替换帧 N - 1 中缓冲区的内容后立即变为有信号量状态,或者换句话说,该栅栏的含义是“你为帧 N 提供的缓冲区内容现在已经替代以前的内容”。这是非推测性的,因为在硬件呈现此帧的内容之后,该栅栏应该在 presentDisplay 被调用后立即变为有信号量状态。 104 | 105 | # 同步栅栏(Fence)的使用 106 | 107 | 在上一章里详细介绍了 Fence 的概念和由来,本章对此做个简略小结。BufferQueue,既是使用 Buffer 的通道,也是使用同步栅栏(Fence)的通道。在 BufferQueue 两端周期性使用的4个方法: 108 | * dequeueBuffer() 缓冲区出队。 109 | * queueBuffer() 缓冲区入队。 110 | * acquireBuffer() 帧出队。 111 | * releaseBuffer() 帧入队。 112 | 113 | 4个都带有同步栅栏(Fence)参数。根据参数的进出方向不同,对应到[Hardware Composer 集成](#hardware-composer-%E9%9B%86%E6%88%90)一节里介绍的 HWC 使用的3个同步栅栏(Fence)中的2个:获取栅栏(Acquire fence)和释放栅栏(Release fence)。 114 | 115 | 根据参数的进出方向: 116 | * dequeueBuffer() 缓冲区出队。空闲缓冲区带着的是消费者 HWC 传递过来的释放栅栏(Release fence)。生产者需要等待 Release fence 发信号,才代表着消费者获取内容完毕,该缓冲区可以交给生产者使用。 117 | * queueBuffer() 缓冲区入队。生产者生成获取栅栏(Acquire fence),代表着虽然缓冲区里的内容还在由 GPU 渲染,但生产端的 CPU 已经无事可做,所以提前提交给消费端 CPU 了。 118 | * acquireBuffer() 帧出队。有内容的帧带着的是生产者传递过来的获取栅栏(Acquire fence)。消费者 HWC 需要等待 Acquire fence 发信号,才代表着生产者生成内容完毕,该帧可以交给消费者使用。 119 | * releaseBuffer() 帧入队。消费者 HWC 生成释放栅栏(Release fence),代表着虽然缓冲区里的内容还在等待读取,但消费端的 CPU 已经无事可做,所以提前交还给生产端 CPU 了。 120 | 121 | # 同步栅栏(Fence)的处理节点 122 | 123 | 合成服务器(HWComposer)是内容汇总的地方,所以也是同步栅栏(Fence)集中处理的地方。基于 Producer-Consumer 模式: 124 | * 在读取每层的内容前,合成服务器或 HWC 做为消费者,都会等待生产者的获取栅栏(Acquire fence)信号。 125 | * 为了并发性,合成服务器会尽快地给生产者释放 Buffer,并且附带一个释放栅栏(Release fence)。生产者必须等待该信号,表明合成服务器或 HWC 已经读取内容完毕,生产者才可以生成新的内容。 126 | * 当合成操作真正执行完毕,底层 HWC 会发出退出栅栏(Retire fence)信号,表面内容被真正地消费完成。该信号后来改名为显示栅栏(Present fence)。该信号的完成时间戳可以校验 SW VSYNC。 127 | 128 | Hardware Composer 对三种类型的同步栅栏的处理方式: 129 | * 获取栅栏(Acquire fence)会与输入缓冲区一起传递给 setLayerBuffer 和 setClientTarget 调用。这些栅栏表示正在等待写入缓冲区,并且必须在 SurfaceFlinger 或 HWC 尝试从关联缓冲区读取数据以执行合成之前变为有信号状态。 130 | * 释放栅栏(Release fence)在调用 presentDisplay 之后使用 getReleaseFences 调用进行检索。这些栅栏表示正在等待从同一个图层的上一个缓冲区读取数据。当 HWC 不再使用屏幕的上一个缓冲区时(因为当前缓冲区已经替换了此上一个缓冲区),释放栅栏会变为有信号状态。系统会将释放栅栏与将在当前合成期间被替换的先前缓冲区一起传回给应用。应用必须等到释放栅栏变为有信号状态,才能将新内容写入返回给它们的缓冲区。 131 | * 显示栅栏(Present fence)作为 presentDisplay 调用结果的一部分返回(每帧一个)。当前栅栏表示对应帧的合成何时完成,或者何时不再需要上一帧的合成结果。对于物理屏幕,当屏幕上显示当前帧时,presentDisplay 会返回当前栅栏。返回当前栅栏后,即可安全地再次写入 SurfaceFlinger 目标缓冲区(如果适用)。对于虚拟屏幕,当可以安全地从输出缓冲区中读取数据时,便会返回当前栅栏。 132 | 133 | -------------------------------------------------------------------------------- /document/hal-design/gralloc.md: -------------------------------------------------------------------------------- 1 | # gralloc 模块 2 | * * * 3 | 4 | # 图形系统处理的介质:Buffer 5 | 6 | 在 framework 层,有两个图形系统最重要的概念:Buffer / Window。对应的两个接口(interface)分别是:ANativeWindowBuffer(Android Native Window Buffer) / ANativeWindow(Android Native Window)。 7 | 8 | ANativeWindowBuffer 是实际和 HAL 打交道的接口,最终会调用到 gralloc 接口。gralloc 接口由厂商根据硬件方案做实现,在系统初始化的时候以 plugin 的方式装载进来。 9 | 10 | gralloc 模块的实现,还受限于图形格式(format)、图形变换(transformation)算法、颜色空间(colorspace)的相关定义,声明于 graphics.h。 11 | * system/core/include/system/graphics-base.h 12 | * system/core/include/system/graphics-base-v1.0.h 13 | * system/core/include/system/graphics-base-v1.1.h 14 | * system/core/include/system/graphics-base-v1.2.h 15 | * system/core/include/system/graphics.h 16 | * system/core/include/system/graphics-sw.h 17 | 18 | 由此看出这些信息是系统底层(System)对中间架构层(Framework)的限制。 19 | 20 | gralloc(graphics alloc) 模块管理着 Buffer 资源(buffer_handle_t),声明于 gralloc.h。gralloc 模块就是对硬件级别的 Buffer 的管理模块,参见文档[[gralloc](https://www.codeproject.com/Articles/991640/Androids-Graphics-Buffer-Management-System-Part-I)]。该模块也是很通常地分为两个部分:gralloc_module_t(继承自 hw_module_t) / alloc_device_t(继承自 hw_device_t)。后面对 gralloc 模块的表述,是指整体功能,不区分具体哪个类。 21 | 22 | 本章所说的 Buffer,与 gralloc buffer 是同一概念,是 Android 里常用的术语。 23 | 24 | # Buffer 的底层设计 25 | 26 | ## 管理 Buffer 的基本功能 27 | 28 | 做为 Buffer 的管理模块,gralloc 模块有 6 个基本功能: 29 | * 申请 alloc() / 释放 free() 缓冲区。 30 | * 锁定 lock() / 解锁 unlock() 缓冲区。 31 | - 锁定 lock() 缓冲区,意味着该缓冲区内存对于当前调用者可用。当前调用者将立即在内存中绘制内容。 32 | - 解锁 unlock() 缓冲区,意味着当前调用者结束绘制,该缓冲区可以交给其它设备使用。 33 | * 注册 registerBuffer() / 解除注册 unregisterBuffer() 缓冲区。用于跨进程的操作。 34 | - 当本进程得到一个别的进程已申请好的 Buffer 时,需要向底层系统注册 registerBuffer(),以便底层系统进行相应的操作,例如映射内存,使得本进程能操作相应的 Buffer。 35 | - 反之,当本进程不再需要该 Buffer 时,需要进行解除注册 unregisterBuffer() 操作,以便底层系统进行相应的操作,例如解除映射,对象自减计数等等,使得跨进程的 Buffer 对象状态一致,可以进行自我生命周期管理。 36 | - 在 Android 7.0 及以后的版本中,在 gralloc1 模块中,这两个函数改名为:retain() / release()。一个是增加引用计数,一个是减少引用计数。这样更能体现设计本义。 37 | 38 | 下面是 gralloc v0 模块的类图: 39 | ![gralloc 模块的类图](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/hal-design/hardware_gralloc%20Class%20Diagram.svg) 40 | 41 | 下面是 gralloc v1 模块的类图: 42 | ![gralloc1 模块的类图](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/hal-design/hardware_gralloc1%20Class%20Diagram.svg) 43 | 44 | ## 共享机制 45 | 46 | 由于 gralloc buffer 跨多个进程共享,必须真正地跨进程共享内容和引用计数。这是一个 gralloc buffer 的概念,它基于文件描述符引用计数。 47 | 48 | 把 gralloc buffer 想像为一个文件,存在多个文件描述符共同访问同一个文件。就像 kernel 对待普通文件会发生什么一样,kernel 用打开的文件描述符来跟踪它。要跨进程传输一个 gralloc buffer,你可以使用标准的 kernel 功能,在一个 socket() 带外数据结构中传输一个文件的描述符。 49 | 50 | 因此,在 Android Framebuffer 层的实现里,当一个 gralloc buffer 在两个进程之间共享,每个进程都有它自己的 GraphicBuffer 对象,每个对象都有它自己的引用计数(refcount),这些都是共享同一个底层的 gralloc buffer(但有不同的打开着的描述符)。共享通过:服务端调用 GraphicBuffer::flatten 序列化发送,和客户端调用 GraphicBuffer::unflatten 反序列化接收它。GraphicBuffer::unflatten 将调用 BufferMapper::registerBuffer,以确保 OS 底层的缓存区句柄的引用计数是正确的。 51 | 52 | 当 GraphicBuffer 的引用计数变为零,析构函数会调用 free_handle,名字为 BufferMapper::unregisterBuffer 的方法,它将关闭文件描述符,从而递减 gralloc buffer 的引用计数。 53 | 54 | ## 实现 Buffer 时需要考虑的硬件因素 55 | 56 | ANativeWindowBuffer 最终与 gralloc 模块打交道。它对上层屏蔽了硬件细节。但是如果要做具体实现,则需要了解很多底层的硬件特性。 57 | 58 | ANativeWindowBuffer 的设计,有 5 个基本参数: 59 | * width 60 | * height 61 | * stride 62 | * format 63 | * usage 64 | 65 | 宽度(width)和高度(height),代表图形的 2D 尺寸。当描述图形缓冲区的尺寸时,需要注意两点。首先,我们需要理解维度的单位。如果尺寸用像素表示,那么我们需要理解如何将像素转换为位。为此我们需要知道颜色编码格式。 66 | 67 | 颜色格式(format)就是用于标识颜色编码格式。常用颜色格式有 RGBA_8888,是每像素32位(每个像素有4个组分:红、绿、蓝和 alpha 混合,每个8位),这个与 OpenGL 的常用格式一致。RGB_565 是每个像素 16 位(5位为红色和蓝色,6位为绿色)。此外,还有 YUV 格式。 68 | 69 | 影响图形缓冲区物理尺寸的第二个重要因素是它的步幅(stride)。有些地方也称为 pitch。为了理解步幅,可见下图。 70 | 71 | ![buffer stride 1](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/hal-design/window-01.svg) 72 | 73 | 我们可以把内存缓冲区看作像素行和列的矩阵排列。列组成行。步幅被定义为所需要的从一条缓冲线(扫描线)的开始计数到下一条缓冲线的像素的数量(或字节,取决于描述的单位)。如上图所示,步幅必须至少等于缓冲区的宽度,但是也可以无碍地大于宽度。步幅和宽度(stride-width)之间有差别只是浪费了内存,而由此带来的特性是,用于存储图像或图形的内存可能不是连续的。那么,步幅是从哪里来的呢?由于硬件实现的复杂性、存储器带宽优化和其他限制,访问图形存储器的硬件可能要求缓冲区是若干字节的倍数。例如,如果对于特定的硬件模块,线路地址需要对齐到64字节,那么存储器宽度需要是64字节的倍数。如果此约束导致得到比请求时更长的扫描线,则缓冲步幅与宽度不同。步幅的另一个动机是缓冲区重用:想象一下,你想在另一个图像中引用裁剪图像。在这种情况下,裁剪(内部)图像具有不同于宽度的步幅。见下图。 74 | 75 | ![buffer stride 2](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/hal-design/window-02.svg) 76 | 77 | 已分配的缓冲存储器当然可以通过用户空间的代码,其实就是 CPU,写入或读取,但是首先它可由不同的硬件模块写入或读取,例如 GPU (图形处理单元)、照相机、合成引擎、DMA引擎、显示控制器等。在一个经典的片上系统(SoC)中,这些硬件模块来自不同的厂商,对缓冲存储器有不同的约束,如果它们要共享缓冲区,则需要协调这些约束。例如,被 GPU 写入的缓冲器,对显示控制器应该是可读取的。缓冲区上的不同约束不一定是异构组件供应商的结果,也可能是因为优化点不同。在任何情况下,Buffer 都需要确保图像格式和内存布局对图像生产者和消费者都是一致的。这就是 usage 参数发挥作用的地方。 78 | 79 | 参数 usage 有3个功能:一是描述软件如何读取缓冲区(从不,很少,经常);二是描述软件如何写入缓冲区(从不,很少,经常)。三是描述硬件如何使用缓冲区:作为 OpenGL ES 纹理(texture)或 OpenGL ES 渲染(render)目标;由 2D 硬件位块传送器(blitter)、HWComposer、framebuffer 设备或硬件视频编码器写入;或由硬件相机流水线读取;做为零快门延迟相机队列的一部分;做为 RenderScript 分配缓存;在外部显示器上全屏显示;或用作光标。 80 | 81 | 显然,颜色格式和 usage 标志之间可能存在某种耦合。例如,如果 usage 参数指示缓冲区由相机写入并由视频编码器读取,则格式必须为两个硬件模块所接受。 82 | 83 | 如果软件需要访问缓冲区内容(或读或写),那么 Buffer 需要确保从物理地址空间到CPU的虚拟地址(virtual address)空间的映射以及缓存(cache)保持一致。 84 | 85 | ## 影响图形内存布局的其它因素 86 | 87 | 除了前面介绍的参数以外,还有其他因素影响如何分配图形和图像内存,以及如何存储(内存布局)和访问图像: 88 | 89 | ### 对齐(Alignment) 90 | 91 | 再一次,不同的硬件可能施加或硬或软的内存对齐要求。不遵守硬要求将导致硬件无法执行其功能,而不遵守软要求将导致硬件的不最佳使用(通常体现在功率、发热和性能方面)。 92 | 93 | ### 颜色空间,格式和内存布局(Color Space, Formats and Memory Layout) 94 | 95 | 这里有几种颜色空间,其中最熟悉的是 YCbCr(图像)和 RGB(图形)。在每个颜色空间内,信息可以不同地编码。一些 RGB 编码例子包括 RGB565(16 位;红色和蓝色各 5 位,绿色 6 位)、RGB888(24 位)或ARGB8888(32 位;具有 α 混合通道)。YCbCr 编码格式通常采用色度子采样。参见文档[[gralloc](https://www.codeproject.com/Articles/991640/Androids-Graphics-Buffer-Management-System-Part-I)]的说明。 96 | 97 | ### 堆砌(Tiling) 98 | 99 | 如果片上系统(SoC)的硬件使用访问相邻像素块为主的算法,那么安排图像内存布局,使得相邻像素以线状布局,而不是通常的位置的布局,这可能更有效率。这称为平铺。 100 | 101 | 一些图形/图像硬件使用更精细的拼接,例如支持两种拼接大小:一组小拼接可以以某种扫描顺序排列在较大的拼接内。参见文档[[gralloc](https://www.codeproject.com/Articles/991640/Androids-Graphics-Buffer-Management-System-Part-I)]的说明。 102 | 103 | ### 压缩(Compression) 104 | 105 | 如果生产者和消费者都是同一片上系统(SoC)的硬件组件,则其可以写和读通用的专有压缩数据格式,并动态地解压缩数据(例如,在处理像素数据之前使用芯片内的内存,通常是 SRAM)。 106 | 107 | ### 内存连续性(Memory Contiguity) 108 | 109 | 一些较老的图像硬件模块(相机、显示器等)没有MMU或不支持分散-聚集(scatter-gather)DMA。在这种情况下,设备DMA使用指向一段物理地址连续的内存来编程。这不会影响内存布局,但肯定是 gralloc 在分配内存时需要注意的特定于平台的约束。 110 | 111 | ## 缓冲区所有权管理(Buffer Ownership Management) 112 | 113 | 内存是一个共享资源。它可以在图形硬件模块和 CPU 之间共享,也可以在两个图形模块之间共享。如果 CPU 正在向图形缓冲区渲染,我们必须确保显示控制器在 CPU 开始读取缓冲存储器之前等待 CPU 完成写入。这是使用系统级同步完成的。但是这种同步不足以确保显示控制器将访问存储器的一致视图。在上面的示例中,CPU 写入的缓冲区的最终更新可能尚未从缓存刷新到系统内存。如果发生这种情况,显示器可能会显示图形缓冲区的错误视图。因此,我们需要某种低级的原子同步机制来显式地管理内存缓冲区所有权的转移,从而验证内存“所有者”是否看到了内存的一致视图。 114 | 115 | 对缓冲存储器(不论对于硬件还是软件,不论读还是写)的访问由 Buffer 的用户显式管理(这可以同步或异步完成)。这是通过锁定和解锁缓冲存储器来完成的。可以有多个线程同时具有读锁,但只有一个线程可以持有写锁。关于同步机制,见后面的章节介绍。 116 | 117 | ### 缓存一致性(Cache Coherence) 118 | 119 | 如果软件需要访问图形缓冲区,那么 CPU 的读取和/或写入,需要访问正确的数据。保持缓存一致性是 Buffer 的职责之一。不必要的刷新缓存,或者在一些 SoC 上启用总线侦听,以保持跨图形硬件和 CPU 的内存视图的一致性,这些行为会浪费电力,并且可能增加延迟。因此,Buffer 也需要采用特定于平台的同步机制。见后面章节的介绍。 120 | 121 | ### 在内存中锁定页面(Locking Pages in RAM) 122 | 123 | 在 CPU 和图形硬件之间共享内存的另一个方面是确保在硬件使用内存页时,不会将内存页刷新到交换文件。目前在 Android 设备上的 Linux 没有使能交换文件的配置,但使能该配置确实是可行的。所以,lock() 函数应该在内存中锁定内存页。 124 | 125 | 一个相关的问题是页面重新映射,当分配给一个物理页面的虚拟页面被动态地重新分配到另一个物理页面(页面迁移)时发生。内核可能选择这样做的一个原因是通过重新配置物理内存分配来防止碎片化。从 CPU 的角度来看,只要新的物理页面包含正确的内容,这就是好了。但从一个图形硬件模块的角度来看,这是从它们脚下拖动地毯。所以,与硬件共享的页面应该设计为不可移动的。 126 | 127 | 128 | -------------------------------------------------------------------------------- /document/hal-design/graphics_pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/hal-design/graphics_pipeline.png -------------------------------------------------------------------------------- /document/hal-design/graphics_secure_texture_playback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/hal-design/graphics_secure_texture_playback.png -------------------------------------------------------------------------------- /document/hal-design/hal-module.md: -------------------------------------------------------------------------------- 1 | # Android 的图形系统的 HAL 接口与约定 2 | * * * 3 | 4 | # HAL接口(Interface)的约定 5 | 6 | Android 系统大致可以分成上下两个部分。上部是和硬件无关的抽象的平台,下部则是和硬件相关的、需要移植的底层。之间则是用硬件抽象层(Hardware Abstraction Layer / HAL)来划分: 7 | * Android HAL(硬件抽象层)是硬件和软件之间的桥梁。 8 | * Android HAL 允许 Android 应用程序/框架与设备驱动程序进行通信,并操控硬件。 9 | * Android HAL 提供了 C/C++ 层面的接口(interface),下面是一个基于厂商 Soc 的特定实现。 10 | * 大多数基于特定厂商的硬件的设备操控的实现都是在 Android HAL 中完成,而不是在设备驱动程序中完成,其中一个原因就是:设备驱动程序(开源许可证 GPL)和 HAL(Apache 许可证)之间的许可证差异。所以,HAL 的设计可以为厂商提供更多的抽象级别的接口和知识产权保护。 11 | 12 | 在 Android 系统的进化过程中,HAL 一直尽可能地保持着稳定。旧接口一般不会修改,而是通过扩展新接口方式保证后向兼容。而且,HAL 还要求保证 C/C++ 编程语言兼容。因为从 Linux 设备驱动到底层的接口库,还有 EGL / OpenGLES,都是 C 语言的函数接口。而 Android framework 是用 C++ 编程。所以为了保证从上到下调用无碍,又要体现面向对象的编程思想,HAL 采用了很多 C/C++ 混编的技巧。其中最典型的技巧就是用 C 语言结构(struct)头部一致的特性来实现单继承,再用函数指针做结构成员表达接口(interface)类,而该接口(interface)类在 C++ 的环境里可以被实现类继承,并实现其中的接口。而且该 C++ 的实现类还可以在 C 语言的代码库里,例如 EGL / OpenGLES,被调用到。上下通畅无碍,这是很值得借鉴的编程经验。 13 | 14 | 相比之下,Android framework 层的代码变动就大很多。典型的就是 Graphic 相关的类,例如 GraphicBuffer 类和 Surface 类,为了增加新功能和优化显示效率,基本上 Android 每一个大版本的升级都会有大变动。这为代码复用带来了很大的麻烦。同时,在 Android 的文档库里,经常将 HAL 的接口约定和 Framework 层的实现混杂在一起进行说明。这对于分析和理解 Android 本身的代码没有问题。但是如果要复用 HAL 代码而重新实现一套 Framework 层,要将两者区分开,也是一个挑战。 15 | 16 | 因此,我们不但要知道 HAL 所实现的功能的目标,还需要知道 HAL 完成功能所需要的条件。这些条件,不但包括调用的参数的定义和范围,还包括调用对象的有限状态机,对象间的序列图和协作图,以及各种假设。只有了解了这些,才可以更好地了解 Android 系统的工作方式,以及更好地复用 Android 系统的代码。 17 | 18 | 另外,再怎么强调稳定,HAL 定义的接口(interface)还是会进化,还是会出现以前没有预料的情况。为解决这种问题,Android 采用了两种解决方案。一个是升级接口(interface)风格,采用通用的方法:getCapabilities() / getFunction()。设备所具有的能力和操控 API,就从这两个方法中获得。这种方案,和 UNIX / Linux 的扩展系统调用 ioctl() 的思路一样,就是造一个魔术包裹,什么东西都从里面变出来。 19 | 20 | 第二个方案是提供 HAL Interface Definition Language (HIDL)。因为各个厂商跟进 Android 新版本的状况不一样, HAL 有多版本共存,市面上的 Android 设备出现了碎片化。HIDL 就是要解决这种情况。同时,为了 Android 系统的稳定性,Android 系统从多线程协作模式转向多进程模式。HIDL 可以使得接口和实现可以跨进程分布,并且封装了 binder 编程细节,可以快速开发接口(interface)。 21 | 22 | # HAL 设备通用模型 23 | 24 | 在文件 hardware.h 中,声明了 Android HAL 对设备描述的最通用的模型。设备模型被划分为模块接口(hw_module_t)和设备接口(hw_device_t)。模块接口(hw_module_t)一定会有模块方法(hw_module_methods_t)。模块方法(hw_module_methods_t)至少含有一个 open() 方法,以便能打开硬件设备,获得相应的设备接口(hw_device_t)。设备接口(hw_device_t)至少包含一个 close() 方法,以便能关闭硬件设备。相关的概念和用法,见后面具体各类的类图。 25 | 26 | ![hw_module_t类图](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/hal-design/hardware_hardware%20Class%20Diagram.svg) 27 | 28 | # Android 的图形系统的 HAL 接口(interface)类的代码分布 29 | 30 | 图形系统有关的 HAL Interface 主要分成以下 4 个大类: 31 | * Producer 端:Graphic Alloc (gralloc) 模块。ANativeWindowBuffer 依赖该模块。 32 | * Queue :OS 底层提供的原子级的同步栅栏(Fence)接口。基于多线程/进程的队列管理需要显式同步机制。 33 | * Consumer 端:hwcomposer 模块。硬件合成器(HWC)是整个显示子系统的硬件抽象,包括显示设备,是所有 Android 合成操作(composition)的核心。 34 | * 图形系统的驱动力:VSYNC 信号是 Android 图形系统运转的心跳(heartbeat),或者说是编舞者(Choreographer)。 35 | 36 | 此外,还涉及一个电源管理模块 power。因为显示设备会有开关的需求,所以上层的 ISurfaceComposer 会调用该模块实现休眠/唤醒功能。 37 | 38 | Android 的图形系统的 HAL 接口(interface)类的声明所涉及到的头文件并不多: 39 | * gralloc 模块 40 | + hardware/libhardware/include/hardware/gralloc1.h 41 | + hardware/libhardware/include/hardware/gralloc.h 42 | * Fence 接口 43 | + system/core/libsync/include/android/sync.h 44 | + system/core/libsync/include/ndk/sync.h 45 | + system/core/libsync/include/sync/sync.h 46 | * hwcomposer 模块 47 | + hardware/libhardware/include/hardware/fb.h 48 | + hardware/libhardware/include/hardware/hwcomposer2.h 49 | + hardware/libhardware/include/hardware/hwcomposer_defs.h 50 | + hardware/libhardware/include/hardware/hwcomposer.h 51 | * VSYNC 信号:只是一个函数指针藏在 HWComposer 模块里。 52 | * power 模块 53 | + hardware/libhardware/include/hardware/power.h 54 | 55 | 最终,Producer 端用 gralloc 模块要实现的 Framework Interface 为 ANativeWindowBuffer / ANativeWindow,声明位于这里: 56 | * frameworks/native/libs/nativebase/include/nativebase/nativebase.h 57 | * frameworks/native/libs/nativewindow/include/system/window.h 58 | * system/core/include/cutils/native_handle.h 59 | 60 | 在 Framework 层对应的实现类 GraphicBuffer / Surface,声明位于这里: 61 | * frameworks/native/include/ui/GraphicBuffer.h 62 | * frameworks/native/include/gui/Surface.h 63 | 64 | Consumer 端用 hwcomposer 模块要实现的类为 HWComposer,声明位于这里: 65 | * frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.h 66 | 67 | HWComposer 是 SurfaceFlinger 对于整个硬件显示子系统的抽象,包括显示设备,是所有 Android 合成操作的核心。 68 | 69 | 从系统总体实现的角度看,Interface 是最重要的。它们是功能锚点,定义了系统功能。在图形系统中,目标就是用 HAL Interface 实现 Framework Interface。至于中间层的实现(Implementation),可以各用各的软件包,各有各的实现。Android Framework 只是其中一个经典实现。而 [Sailfish OS](https://sailfishos.org/) 则用 Qt5 做了另外的实现,并且在 Consumer 端没有使用 surfaceflinger service,而是实现了 wayland server。也就是,在执行 queueBuffer() 的时刻,Buffer 被送给了另外的 HWComposer 实现。当然,最终 wayland server 还是调用了 hwcomposer 模块,将应用所绘制的内容交给了显示设备。 70 | 71 | 本章只关注接口(interface)的约定,具体的实现将在后面的文章讨论。下面是这些模块的功能介绍。 72 | 73 | # [gralloc 模块](gralloc.md) 74 | 75 | # [同步栅栏(Fence)](fence.md) 76 | 77 | # [hwcomposer 模块](hwcomposer.md) 78 | 79 | # [VSYNC 信号](VSYNC.md) 80 | 81 | # power 模块 82 | 83 | 显示设备是手机里的用电大户。power 模块相对简单,就是提供给 hwcomposer 模块开关设备。主要就是在休眠/唤醒时被 hwcomposer 模块使用到。 84 | 85 | ![power_module_t类图](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/hal-design/hardware_power%20Class%20Diagram.svg) 86 | 87 | # [代码复用](reuse.md) 88 | 89 | # 小结 90 | 91 | Android HAL 中和图形系统有关的模块,有这几方面: 92 | * Producer 端的支撑为 gralloc 模块。目标是要实现 framework 层的 ANativeWindowBuffer 接口。 93 | * Consumer 端的支撑为 hwcomposer 模块。目标是要实现 SurfaceFlinger 的 HWComposer 模块。硬件合成器(HWC)是整个硬件显示子系统的抽象,包括显示设备,是所有 Android 合成操作的核心。 94 | * 对于 Queue,依靠 OS 底层提供的原子级的 Fence 接口,Android 图形系统采用并实现了显式同步机制。 95 | * VSYNC 信号是 Android 图形系统运转的心跳(heartbeat),或者说是编舞者(Choreographer)。 96 | 97 | # 参考文件 98 | 1. [Android's Graphics Buffer Management System (Part I: gralloc)](https://www.codeproject.com/Articles/991640/Androids-Graphics-Buffer-Management-System-Part-I) 99 | 1. [The Android Graphics microconference](https://lwn.net/Articles/569704/) 100 | 1. [Hardware Composer 2.0](https://blog.linuxplumbersconf.org/2016/ocw//system/presentations/4185/original/LPC%20HWC%202.0%20&%20drm_hwcomposer%20.pdf) 101 | 1. [Android Hwcomposer on KMS](https://www.slideshare.net/linaroorg/kms-hwcomposer) 102 | 1. [Implementing the Hardware Composer HAL](https://source.android.com/devices/graphics/implement-hwc) 103 | 1. [Implementing VSYNC](https://source.android.com/devices/graphics/implement-vsync) 104 | 1. [Synchronization framework](https://source.android.com/devices/graphics/sync) 105 | 1. [Android Sync](https://blog.linuxplumbersconf.org/2014/ocw/system/presentations/2355/original/03%20-%20sync%20&%20dma-fence.pdf) 106 | 1. [VSync信号](http://windrunnerlihuan.com/2017/05/21/VSync%E4%BF%A1%E5%8F%B7/) 107 | 108 | 109 | -------------------------------------------------------------------------------- /document/hal-design/reuse.md: -------------------------------------------------------------------------------- 1 | # 代码复用 2 | * * * 3 | 4 | Android OS 是一个极其成功的项目。Google 公司不但凭着高深的技术,也凭着高超的商业手段,将 Android 系统推广开来。在智能手机的世界里,Android 系统已经是占有率第一。在 Linux 世界里,Android 系统的占有率也是远远超过其它传统的 Linux 系统。在推广传统 Linux 系统时碰到的第一个拦路虎:缺少硬件平台和软件驱动的问题,在 Google 公司手里迎刃而解。以前要推广 Linux 系统,是求着厂商出板子、写驱动。而现在是厂商主动给 Android 系统出板子、写驱动。有了生态系统,什么都好说话。个中滋味,只有经历过的人才能体会。 5 | 6 | 于是有人就想着借着 Android 系统里的板子和驱动,去推广传统 Linux 系统。因为第一个拦路虎没有了,板子和驱动都是现成的,推广传统 Linux 系统的难度大大降低。不过,在这种尝试过程中,也出现了问题。 7 | 8 | # 现有的问题 9 | 10 | Android 系统,不知是有意无意,全部采用了有别于传统 Linux 系统的不同的技术方案。可以说,除了 Linux Kernel 相似之外,其它的地方都不同。这就形成了很高的技术壁垒,让传统 Linux 系统很难复用 Android 系统里的代码模块。 11 | 12 | 首先碰到的问题有2个: 13 | 1. C run-time library。在传统 Linux 系统里,C run-time library 是有名的 glibc。而在 Android 系统里,则是相对不出名的一个轻量级的 C 库:bionic。这就造成了一个问题,在传统 Linux 系统里的程序,既无法链接 Android 系统里的代码库,也无法直接调用代码库里的函数。让人有看着宝山却又无门而入的感觉。 14 | 2. Init scripts。在传统 Linux 系统里,虽然 init 系统有过升级,但脚本概念、程序空间的划分、进程间的通讯等等这些技术是相同的。也就是,可以更换多种 init 程序和脚本,但最后启动的图形工作环境是一样的。在最终的图形工作环境里,用户感觉不到差异。而 Android 系统的 init 程序、脚本概念、程序空间的划分、进程间的通讯等等这些技术和传统 Linux 系统都不一样。两者就没有交换的可能。 15 | 16 | 但是,难度再大也挡不住高手的挑战。这两个难题分别被人突破。于是,进一步的问题:分析 Android HAL 的接口与约定,复用 Android HAL 代码,则不但是有趣的事情,也是必要的事情。于是现在出现了两种解决方案: 17 | 1. [Mer Project](http://www.merproject.org/) 18 | 2. FireFox OS 19 | 20 | # 现有的解决方案 21 | 22 | ## Mer Project 23 | 24 | [Mer Project](http://www.merproject.org/)的解决方案是目前最成功,应用得最广的方案。除了 Mer Project 本身以外,还有这些项目在使用他们的方案: 25 | 1. [Sailfish OS](https://sailfishos.org/) 26 | 2. [Tizen OS](http://www.tizen.org/) 27 | 3. [Asteroid OS](https://asteroidos.org) 28 | 4. [webOS](http://webosose.org/) 29 | 5. 国内外各种号称能复用 Android 驱动的方案,大多也是采用了 Mer Project 的技术。 30 | 31 | 在这些项目里,Sailfish OS 是已经出产品,并且成功量产的项目。因此后面的分析,基本上就是针对他们的技术特点进行分析。 32 | 33 | 对于上述的复用的第一个问题,Mer Project 采用的是 [libhybris](https://github.com/libhybris/libhybris) 技术进行解决。 34 | 35 | 简单地说,glibc 程序之所以不能链接和调用 bionic 代码库,是因为编译系统里的 "linker & loader" 不一致造成的。这是不可调和的矛盾。但是,在 C 代码库里,有一个 "dlopen()/dlsym()" 动态装载和调用代码库的方式。能不能在 glibc 程序里动态装载 bionic 代码库呢?很遗憾,这个问题还是会回到 "linker & loader" 不一致的问题,因此造成装载失败。 36 | 37 | 但是,任何难题总会露有一线生机。用 glibc 版本的 "dlopen()" 不能装载 bionic 代码库,用 bionic 版本的呢?幸运的是,因为 bionic 相当简单,所以 bionic 版本的 "dlopen()" 也相当简单,代码在 "bionic/linker/" 目录里。于是经过一番艰苦的努力,在 glibc 程序里就可以用 bionic 版本的 "dlopen()/dlsym()" 动态装载和调用 bionic 代码库了。 38 | 39 | 这里不讨论 libhybris 技术,总之,第一个问题解决了。如果要想理解其中的奥秘,需要对 "linker & loader" 有一定的了解,还需要一点想象力,理解代码空间、符号解析、函数指针、C run-time library 的实现与参数的差异等等问题。理解 libhybris 技术还是一件蛮有趣的事情,对什么是运行程序这个问题会有更深的理解。 40 | 41 | 第二个问题也比较好解决:就是还是继续保留传统 Linux 系统里的 init 系统和脚本,使用这些脚本启动一些复用 Android HAL 所必须的 service。只要运行环境和参数给对了,这些 service 应该能正常运行。 42 | 43 | 接着,更深的问题出现了,Android HAL 的接口与约定是什么?怎么样从 Android Framework 的代码里推测出相应的知识,然后复用 Android HAL?经过各位高手的努力,这个工程也有很大的进展。 44 | 45 | 在 Mer Project 的图形系统里: 46 | 1. 直接采用 gralloc module,重新实现了 ANativeWindow / ANativeWindowBufer 接口,使得 glibc 程序可以复用 EGL / GLES 库。 47 | 2. 用 libhybris 技术重新封装了 EGL / GLES 库,使之实现了 wayland protocol。 48 | 3. 整个图形系统采用 qt5 / wayland。 49 | 4. 直接采用 HWC module,实现了 [qt5 / hwc qpa plugin](https://github.com/mer-hybris/qt5-qpa-hwcomposer-plugin)。 50 | 5. 可以说:gralloc module / HWC module / VSYNC / Fence 这些接口都复用到了,然后实现了一个和 Android 不一样的图形系统。 51 | 52 | 但是,在实践中,libhybris 技术也出现了一些问题: 53 | 1. 毕竟是采用 hack 技术,而不是正规的调用方式,bionic 代码运行时有可能会有诡异的崩溃。BUG 很难定位,定位了也很难理解,理解了也很难解决。 54 | 2. Android 每次大的升级,编译系统和代码库也会升级。libhybris 技术也许也需要随之升级。但是,bionic linker 每次的变动都是比较大的,移植到 libhybris 库里,工作量比较大。 55 | 3. 现在 libhybris 技术,也只是在高通的几个芯片方案里得到比较充分的验证。在其它平台和方案里,可靠性还有待验证。 56 | 57 | 但是,不管怎么样,在技术上,Mer Project 还是一个很成功的项目。差不多是复用 Android HAL 的唯一选择。 58 | 59 | ## FireFox OS 60 | 61 | 因为在 glibc 程序里复用 Android HAL 首先会碰到那两个问题。解决起来,不但费时费力,还会有可靠性问题。于是 FireFox OS 采用了另外的方案:就是将自己移植到 Android 的运行环境里,全部的代码都用 Android 的编译器编译一遍。这样,那两个问题就消失了,FireFox OS 也就可以直接调用 Android HAL 的接口了。 62 | 63 | FireFox OS 之所以能这么做,是因为: 64 | 1. FireFox Browser 原本就可以运行在很多不同的、差异很大的 OS 里。于是 FireFox 本身的代码可移植性就很好,交叉编译脚本也很完善。 65 | 2. 为了做到上面一点,FireFox 差不多就是自包含的系统,例如有自己的图形系统和输入系统,只需要实现一个相对薄层的移植层,就可以运行在新的环境里。也就是,FireFox 离一个独立的 OS 已经很接近了。 66 | 67 | 其实,将大型软件系统移植到 也是Android 的运行环境里,是很普遍的事情。例如大型的视频系统,Kodi / VLC / Gstreamer,都有 Android 版本。只是这些程序是想让自己成为一个合格的 Android 程序,所以是尽量调用 Android 高层的接口。而 FireFox OS 是要抛开 Android 高层,只留下 Android Framework / C++ 层以及下面的 Android HAL,然后自己做 OS。 68 | 69 | FireFox OS 复用 Android 代码库,也有自己的特色,就是尽可能复用 Android Framework / C++ 层的接口。例如,FireFox OS 复用的是 GraphicBuffer 类来使用 ANativeWindowBuffer 接口(interface),而不是从 gralloc module 上面重新实现。这样可以减少工作量,也有利于提高可靠性。但是,他们为了不在 FireFox OS 的 C++ 代码里引入 Android C++ namespace,也采用了 C 语言级别的 hack 方式去调用 GraphicBuffer 类的代码。该方式相当的野蛮粗暴,也影响了可移植性。 70 | 71 | 接着,他们再实现自己的 ANativeWindow 接口(interface)以及背后的 BufferQueue,这是因为他们有他们自己的图形系统和跨进程协作方式。也正是因为这点,他们也遇到了麻烦。因为他们在进程中使用了多个 Texture ID 及其绑定的 EGLImage,这样可以并发渲染图形。但是因为 GLES 没有直接从 Texture ID 中解除绑定 EGLImage 的接口,从而也影响了并发的效率。 72 | 73 | 不管怎么样,FireFox OS 也是已经出产品,并且成功量产的项目。可惜因为商业的原因,该项目已经停止开发。现在回过头来看,类似复用 GraphicBuffer 类的方式,会有很大的可移植的问题。因为 Android 每次大的升级,Android Framework 都会有较大的改动,原来的方法就消失不见了,取而代之的是重新设计的新的方法。这是因为 Android 保证的是上下两层接口的兼容性。对上,保证的是 JAVA 层的兼容性,因为它们面对的是现有的应用程序。对下,保证的是 Android HAL 的兼容性,因为它们面对的是厂商现有的实现。而中间的 Android Framework,功能和性能是优先的,兼容性不是优先考虑的问题。 74 | 75 | 但是不管怎么样,这种技术路线可以带来工作量小,可靠性高的好处。不过有一点值得注意,采用这种技术路线可能会带来法律问题。这个问题不在这里讨论。 76 | 77 | # 其它的可能性 78 | 79 | ## 复用的层次 80 | 81 | 现在复用 Android 代码,基本上都是从 HAL 层的代码开始。然后根据 Android 的实现,推测上层的接口所需要的功能,以及相应的有限状态机,然后做新的实现。 82 | 83 | 其实从编译器和编译依赖系统的角度看,整个 Android 公开的代码,去除最底层的 C run-time library : bionic,是完全可以用 gcc / glibc 重新编译的。但是是什么东西阻止了 Android 代码的复用?其实就是 HAL 层中的那些厂商的 close-module。就是因为闭源代码的存在,整个 HAL 层必须被原封不动地复用。 84 | 85 | 如果再想在更高层复用 Android 代码,则会碰到修改编译依赖系统 ninjia 的配置文件的问题。这也是一个庞大的工程。另外,Android 代码里复杂的 C++ namespace,也是令人头痛的问题。 86 | 87 | ## Binder Interface 的复用 88 | 89 | 如果是 glibc 空间的程序,想从高层,如 HIDL 或 Framework 层复用 Android 代码,有一种方法就是重新编译 Binder Interface 中的 Bp 类这一半。这样从远程调用 HAL 模块,这也是一种可能。这样一直到 Framework 层的代码再用 gcc / glibc 重新编译,glibc 空间的程序就可以复用 Android 系统而没有任何冲突。不过修改编译依赖系统 ninjia 的配置文件的工作量实在太大了。所有现在可行的方案还是复用 [Mer Project](http://www.merproject.org/) 方案。 90 | 91 | -------------------------------------------------------------------------------- /document/hal-design/window-01.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 11 | 7425 2610 7425 2925 12 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 13 | 7875 2385 7875 2925 14 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 15 | 0 0 1.00 60.00 120.00 16 | 0 0 1.00 60.00 120.00 17 | 4500 2700 7425 2700 18 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 19 | 7875 2925 8190 2925 20 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 21 | 7875 4500 8190 4500 22 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 23 | 0 0 1.00 60.00 120.00 24 | 0 0 1.00 60.00 120.00 25 | 8100 2925 8100 4500 26 | 2 2 0 1 0 7 50 -1 45 0.000 0 0 -1 0 0 5 27 | 7425 2925 7875 2925 7875 4500 7425 4500 7425 2925 28 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 29 | 0 0 1.00 60.00 120.00 30 | 0 0 1.00 60.00 120.00 31 | 4500 2475 7875 2475 32 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 33 | 4500 2385 4500 2925 34 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 35 | 4500 1575 7425 1575 7425 2250 4500 2250 4500 1575 36 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 37 | 4500 2925 7425 2925 7425 4500 4500 4500 4500 2925 38 | 4 0 0 50 -1 0 12 0.0000 4 135 510 5400 2700 Width\001 39 | 4 0 0 50 -1 0 12 4.7124 4 180 555 8100 3375 Height\001 40 | 4 0 0 50 -1 0 12 0.0000 4 135 480 5400 2475 Stride\001 41 | 4 0 0 50 -1 0 12 0.0000 4 180 2835 4725 4725 Usage: Who uses it? How to use it?\001 42 | 4 0 0 50 -1 0 12 0.0000 4 135 630 4725 3825 Format:\001 43 | 4 0 0 50 -1 0 12 0.0000 4 180 2565 4725 4275 RGBA8888 -> 1 pixel = 4 bytes\001 44 | 4 0 0 50 -1 0 12 0.0000 4 180 2550 4725 4050 RGB565 -> 1 pixel = 2 bytes\001 45 | 4 0 0 50 -1 0 12 0.0000 4 135 1365 5400 2025 ANativeWindow\001 46 | 4 0 0 50 -1 0 12 0.0000 4 135 1875 5400 3375 ANativeWindowBuffer\001 47 | -------------------------------------------------------------------------------- /document/hal-design/window-01.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 26 | 27 | 29 | 30 | 32 | 33 | 35 | 36 | 38 | 39 | 40 | 41 | 44 | 45 | 46 | 48 | 49 | 51 | 52 | 54 | 55 | 56 | 57 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 67 | 68 | 69 | 70 | 73 | 74 | 75 | 77 | 78 | 80 | 81 | 83 | 84 | 86 | 87 | 89 | 90 | 92 | 93 | Width 94 | 95 | 96 | Height 97 | 98 | Stride 99 | 100 | Usage: Who uses it? How to use it? 101 | 102 | Format: 103 | 104 | RGBA8888 -> 1 pixel = 4 bytes 105 | 106 | RGB565 -> 1 pixel = 2 bytes 107 | 108 | ANativeWindow 109 | 110 | ANativeWindowBuffer 111 | 112 | 113 | -------------------------------------------------------------------------------- /document/hal-design/window-02.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 11 | 7425 2610 7425 2925 12 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 13 | 7875 2385 7875 2925 14 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 15 | 0 0 1.00 60.00 120.00 16 | 0 0 1.00 60.00 120.00 17 | 4500 2700 7425 2700 18 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 19 | 7875 2925 8190 2925 20 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 21 | 7875 4500 8190 4500 22 | 2 2 0 1 0 7 50 -1 45 0.000 0 0 -1 0 0 5 23 | 7425 2925 7875 2925 7875 4500 7425 4500 7425 2925 24 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 25 | 0 0 1.00 60.00 120.00 26 | 0 0 1.00 60.00 120.00 27 | 4500 2475 7875 2475 28 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 29 | 4500 2385 4500 2925 30 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 31 | 4500 1575 7425 1575 7425 2250 4500 2250 4500 1575 32 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 33 | 4500 2925 7425 2925 7425 4500 4500 4500 4500 2925 34 | 2 2 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 5 35 | 4725 3150 7200 3150 7200 4275 4725 4275 4725 3150 36 | 2 2 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 5 37 | 5400 5175 7875 5175 7875 6300 5400 6300 5400 5175 38 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 39 | 0 0 1.00 60.00 120.00 40 | 5400 5175 4725 3150 41 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 42 | 7875 6300 7875 6615 43 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 44 | 5400 6300 5400 6615 45 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 46 | 7875 6300 8190 6300 47 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 48 | 7875 5175 8190 5175 49 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 50 | 0 0 1.00 60.00 120.00 51 | 0 0 1.00 60.00 120.00 52 | 5400 6525 7875 6525 53 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 54 | 4500 6750 7425 6750 7425 7425 4500 7425 4500 6750 55 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 56 | 0 0 1.00 60.00 120.00 57 | 4500 6750 3600 3600 58 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 59 | 0 0 1.00 60.00 120.00 60 | 4500 2250 3600 3150 61 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 62 | 0 0 1.00 60.00 120.00 63 | 0 0 1.00 60.00 120.00 64 | 8100 5175 8100 6300 65 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 66 | 0 0 1.00 60.00 120.00 67 | 0 0 1.00 60.00 120.00 68 | 8100 2925 8100 4500 69 | 4 0 0 50 -1 0 12 0.0000 4 135 480 5400 2475 Stride\001 70 | 4 0 0 50 -1 0 12 0.0000 4 180 1005 4950 4950 Start pointer\001 71 | 4 0 0 50 -1 0 12 0.0000 4 135 1620 5400 2025 ANativeWindow 1#\001 72 | 4 0 0 50 -1 0 12 0.0000 4 135 1620 5400 7200 ANativeWindow 2#\001 73 | 4 0 0 50 -1 0 12 0.0000 4 135 930 3150 3375 same buffer\001 74 | 4 0 0 50 -1 0 12 0.0000 4 135 900 3150 3600 same stride\001 75 | 4 0 0 50 -1 0 12 0.0000 4 135 660 6300 6525 Width 2\001 76 | 4 0 0 50 -1 0 12 0.0000 4 135 660 5400 2700 Width 1\001 77 | 4 0 0 50 -1 0 12 4.7124 4 180 705 8100 3375 Height 1\001 78 | 4 0 0 50 -1 0 12 4.7124 4 180 705 8100 5400 Height 2\001 79 | -------------------------------------------------------------------------------- /document/original-design/01-server-side-drawing.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7b 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 6 3150 1350 4950 2025 11 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 12 | 4950 2025 4950 1350 3150 1350 3150 2025 4950 2025 13 | 4 0 0 50 -1 0 12 0.0000 4 180 1425 3375 1800 Window manager\001 14 | -6 15 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 16 | 4950 3375 4950 2700 3150 2700 3150 3375 4950 3375 17 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 18 | 8100 3375 8100 2700 6300 2700 6300 3375 8100 3375 19 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 20 | 11025 3375 11025 2700 9225 2700 9225 3375 11025 3375 21 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 22 | 13950 3375 13950 2700 12150 2700 12150 3375 13950 3375 23 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 24 | 0 0 1.00 60.00 120.00 25 | 4950 3150 6300 3150 26 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 27 | 8100 4950 8100 4275 6300 4275 6300 4950 8100 4950 28 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 29 | 11025 4950 11025 4275 9225 4275 9225 4950 11025 4950 30 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 31 | 13950 4950 13950 4275 12150 4275 12150 4950 13950 4950 32 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 33 | 0 0 1.00 60.00 120.00 34 | 7200 3375 7200 4275 35 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 1 36 | 7200 4275 37 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 38 | 0 0 1.00 60.00 120.00 39 | 10125 3375 10125 4275 40 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 41 | 0 0 1.00 60.00 120.00 42 | 13050 3375 13050 4275 43 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 44 | 0 0 1.00 60.00 120.00 45 | 8100 4725 9225 4725 46 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 47 | 0 0 1.00 60.00 120.00 48 | 11025 4725 12150 4725 49 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 50 | 5625 900 5625 5175 51 | 3 0 0 1 0 7 50 -1 -1 0.000 0 1 0 4 52 | 0 0 1.00 60.00 120.00 53 | 4950 1800 8325 1800 8334 3284 9225 3150 54 | 0.000 1.000 1.000 0.000 55 | 4 0 0 50 -1 0 12 0.0000 4 135 510 3825 3150 Client\001 56 | 4 0 0 50 -1 0 12 0.0000 4 180 1230 6525 3150 Graphic library\001 57 | 4 0 0 50 -1 0 12 0.0000 4 180 1365 12375 3150 Display manager\001 58 | 4 0 0 50 -1 0 12 0.0000 4 180 1680 9315 3105 Clip-region manager\001 59 | 4 0 0 50 -1 0 12 0.0000 4 135 690 6750 4725 Window\001 60 | 4 0 0 50 -1 0 12 0.0000 4 180 1005 9675 4725 Background\001 61 | 4 0 0 50 -1 0 12 0.0000 4 180 1560 12375 4725 Displayer hardware\001 62 | 4 0 0 50 -1 0 12 0.0000 4 180 690 5175 3150 Drawing\001 63 | 4 0 0 50 -1 0 12 0.0000 4 180 570 5175 3375 require\001 64 | 4 0 0 50 -1 0 12 0.0000 4 180 690 6750 3825 Drawing\001 65 | 4 0 0 50 -1 0 12 0.0000 4 180 960 9675 3825 Cut & paste\001 66 | 4 0 0 50 -1 0 12 0.0000 4 135 630 12600 3825 Control\001 67 | 4 0 0 50 -1 0 12 0.0000 4 135 660 8325 4725 Content\001 68 | 4 0 0 50 -1 0 16 0.0000 4 135 150 8550 3150 +\001 69 | 4 0 0 50 -1 0 16 0.0000 4 135 150 11475 3150 +\001 70 | 4 0 0 50 -1 0 12 0.0000 4 180 1230 3375 2025 (Special client)\001 71 | 4 0 0 50 -1 0 12 0.0000 4 180 1740 6525 1800 size, position, z-order\001 72 | 4 0 0 50 -1 0 12 0.0000 4 135 885 6525 1125 Server side\001 73 | 4 0 0 50 -1 0 12 0.0000 4 135 885 3375 1125 Client side\001 74 | 4 0 0 50 -1 0 12 0.0000 4 135 240 5535 900 OS\001 75 | 4 0 0 50 -1 0 12 0.0000 4 180 2520 5175 450 Server side drawing / rendering\001 76 | 4 0 0 50 -1 0 12 0.0000 4 135 660 11250 4725 Content\001 77 | -------------------------------------------------------------------------------- /document/original-design/02-client-side-drawing.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7b 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 11 | 4950 3375 4950 2700 3150 2700 3150 3375 4950 3375 12 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 13 | 13950 3375 13950 2700 12150 2700 12150 3375 13950 3375 14 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 1 15 | 7200 4275 16 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 17 | 0 0 1.00 60.00 120.00 18 | 10125 3375 10125 4500 19 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 20 | 0 0 1.00 60.00 120.00 21 | 13050 3375 13050 4500 22 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 23 | 4950 4275 4950 3600 3150 3600 3150 4275 4950 4275 24 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 25 | 8100 5175 8100 4500 6300 4500 6300 5175 8100 5175 26 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 27 | 11025 5175 11025 4500 9225 4500 9225 5175 11025 5175 28 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 29 | 0 0 1.00 60.00 120.00 30 | 8100 4950 9225 4950 31 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 32 | 0 0 1.00 60.00 120.00 33 | 11025 4950 12150 4950 34 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 35 | 13950 5175 13950 4500 12150 4500 12150 5175 13950 5175 36 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 37 | 0 0 1.00 60.00 120.00 38 | 4050 3375 4050 4500 39 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 40 | 4950 5175 4950 4500 3150 4500 3150 5175 4950 5175 41 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 42 | 0 0 1.00 60.00 120.00 43 | 0 0 1.00 60.00 120.00 44 | 4950 4950 6300 4950 45 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 46 | 11025 3375 11025 2700 9225 2700 9225 3375 11025 3375 47 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 48 | 4950 2250 4950 1575 3150 1575 3150 2250 4950 2250 49 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 50 | 5625 900 5625 5400 51 | 3 0 0 1 0 7 50 -1 -1 0.000 0 1 0 4 52 | 0 0 1.00 60.00 120.00 53 | 4950 2025 8325 2025 8325 3150 9225 3150 54 | 0.000 1.000 1.000 0.000 55 | 4 0 0 50 -1 0 12 0.0000 4 135 510 3825 3150 Client\001 56 | 4 0 0 50 -1 0 12 0.0000 4 180 1365 12375 3150 Display manager\001 57 | 4 0 0 50 -1 0 12 0.0000 4 135 630 12600 3825 Control\001 58 | 4 0 0 50 -1 0 16 0.0000 4 135 150 11475 3150 +\001 59 | 4 0 0 50 -1 0 12 0.0000 4 180 1230 3375 4050 Graphic library\001 60 | 4 0 0 50 -1 0 12 0.0000 4 135 690 6750 4950 Window\001 61 | 4 0 0 50 -1 0 12 0.0000 4 180 1005 9675 4950 Background\001 62 | 4 0 0 50 -1 0 12 0.0000 4 135 660 8325 4950 Content\001 63 | 4 0 0 50 -1 0 12 0.0000 4 180 1560 12375 4950 Displayer hardware\001 64 | 4 0 0 50 -1 0 12 0.0000 4 180 690 3825 4500 Drawing\001 65 | 4 0 0 50 -1 0 12 0.0000 4 135 690 3825 4950 Window\001 66 | 4 0 0 50 -1 0 12 0.0000 4 135 660 5175 4950 Content\001 67 | 4 0 0 50 -1 0 12 0.0000 4 165 525 5175 5175 (same)\001 68 | 4 0 0 50 -1 0 12 0.0000 4 180 1065 9675 3825 Compositing\001 69 | 4 0 0 50 -1 0 12 0.0000 4 180 825 9675 3150 Composer\001 70 | 4 0 0 50 -1 0 12 0.0000 4 180 1230 3375 2250 (Special client)\001 71 | 4 0 0 50 -1 0 12 0.0000 4 180 1425 3375 2025 Window manager\001 72 | 4 0 0 50 -1 0 12 0.0000 4 135 885 6525 1125 Server side\001 73 | 4 0 0 50 -1 0 12 0.0000 4 180 2280 6525 2025 size, position, z-order, alpha\001 74 | 4 0 0 50 -1 0 12 0.0000 4 135 885 3375 1125 Client side\001 75 | 4 0 0 50 -1 0 12 0.0000 4 135 240 5535 900 OS\001 76 | 4 0 0 50 -1 0 12 0.0000 4 180 2520 5175 675 Client side drawing / rendering\001 77 | 4 0 0 50 -1 0 12 0.0000 4 135 660 11250 4950 Content\001 78 | -------------------------------------------------------------------------------- /document/original-design/03-window.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 6 4500 2925 7425 4500 11 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 12 | 4500 2925 7425 2925 7425 4500 4500 4500 4500 2925 13 | 4 0 0 50 -1 0 12 0.0000 4 135 630 4725 3825 Format:\001 14 | 4 0 0 50 -1 0 12 0.0000 4 180 2565 4725 4275 RGBA8888 -> 1 pixel = 4 bytes\001 15 | 4 0 0 50 -1 0 12 0.0000 4 180 2550 4725 4050 RGB565 -> 1 pixel = 2 bytes\001 16 | 4 0 0 50 -1 0 12 0.0000 4 135 510 5400 3375 Buffer\001 17 | -6 18 | 6 4500 1575 7425 2250 19 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 20 | 4500 1575 7425 1575 7425 2250 4500 2250 4500 1575 21 | 4 0 0 50 -1 0 12 0.0000 4 165 1260 5400 2025 Window(struct)\001 22 | -6 23 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 24 | 7425 2610 7425 2925 25 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 26 | 7875 2385 7875 2925 27 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 28 | 0 0 1.00 60.00 120.00 29 | 0 0 1.00 60.00 120.00 30 | 4500 2700 7425 2700 31 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 32 | 7875 2925 8190 2925 33 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 34 | 7875 4500 8190 4500 35 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 36 | 0 0 1.00 60.00 120.00 37 | 0 0 1.00 60.00 120.00 38 | 8100 2925 8100 4500 39 | 2 2 0 1 0 7 50 -1 45 0.000 0 0 -1 0 0 5 40 | 7425 2925 7875 2925 7875 4500 7425 4500 7425 2925 41 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 42 | 0 0 1.00 60.00 120.00 43 | 0 0 1.00 60.00 120.00 44 | 4500 2475 7875 2475 45 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 46 | 4500 2385 4500 2925 47 | 4 0 0 50 -1 0 12 0.0000 4 135 510 5400 2700 Width\001 48 | 4 0 0 50 -1 0 12 4.7124 4 180 555 8100 3375 Height\001 49 | 4 0 0 50 -1 0 12 0.0000 4 135 480 5400 2475 Stride\001 50 | 4 0 0 50 -1 0 12 0.0000 4 180 2835 4725 4725 Usage: Who uses it? How to use it?\001 51 | -------------------------------------------------------------------------------- /document/original-design/03-window.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 13 | 14 | Format: 15 | 16 | RGBA8888 -> 1 pixel = 4 bytes 17 | 18 | RGB565 -> 1 pixel = 2 bytes 19 | 20 | Buffer 21 | 22 | 24 | 25 | Window(struct) 26 | 27 | 29 | 30 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 42 | 43 | 45 | 46 | 48 | 49 | 51 | 52 | 54 | 55 | 56 | 57 | 60 | 61 | 62 | 64 | 65 | 67 | 68 | 70 | 71 | 72 | 73 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 83 | 84 | 85 | 86 | 89 | 90 | 91 | 93 | 94 | 96 | 97 | 99 | 100 | 102 | 103 | Width 104 | 105 | 106 | Height 107 | 108 | Stride 109 | 110 | Usage: Who uses it? How to use it? 111 | 112 | 113 | -------------------------------------------------------------------------------- /document/original-design/04-two-stage-copy.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 11 | 5625 2475 5625 4275 12 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 13 | 4050 3825 4050 2700 2250 2700 2250 3825 4050 3825 14 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 15 | 9000 3825 9000 2700 7200 2700 7200 3825 9000 3825 16 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 17 | 0 0 1.00 60.00 120.00 18 | 4050 3375 4950 3375 19 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 20 | 6300 3600 6300 2925 4950 2925 4950 3600 6300 3600 21 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 22 | 0 0 1.00 60.00 120.00 23 | 6300 3375 7200 3375 24 | 3 0 0 1 0 7 50 -1 -1 0.000 0 1 1 4 25 | 0 0 1.00 60.00 120.00 26 | 0 0 1.00 60.00 120.00 27 | 4050 3825 4950 4050 6300 4050 7200 3825 28 | 0.000 1.000 1.000 0.000 29 | 4 0 0 50 -1 0 16 0.0000 4 180 345 5400 2475 OS\001 30 | 4 0 0 50 -1 0 16 0.0000 4 240 1740 4725 2025 Two-stage copy\001 31 | 4 0 0 50 -1 0 16 0.0000 4 180 1440 2475 3375 Client Buffer\001 32 | 4 0 0 50 -1 0 16 0.0000 4 180 1485 7425 3375 Server Buffer\001 33 | 4 0 0 50 -1 0 16 0.0000 4 240 915 4050 3375 1st copy\001 34 | 4 0 0 50 -1 0 16 0.0000 4 180 1125 5175 3375 OS Buffer\001 35 | 4 0 0 50 -1 0 16 0.0000 4 240 1005 6300 3375 2nd copy\001 36 | 4 0 0 50 -1 0 16 0.0000 4 180 1050 5175 4050 same size\001 37 | -------------------------------------------------------------------------------- /document/original-design/04-two-stage-copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 31 | 32 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 43 | 44 | 46 | 47 | 48 | 49 | 52 | 53 | 54 | 66 | 67 | 69 | 70 | 72 | 73 | OS 74 | 75 | Two-stage copy 76 | 77 | Client Buffer 78 | 79 | Server Buffer 80 | 81 | 1st copy 82 | 83 | OS Buffer 84 | 85 | 2nd copy 86 | 87 | same size 88 | 89 | 90 | -------------------------------------------------------------------------------- /document/original-design/05-zero-copy.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 11 | 5625 900 5625 5400 12 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 13 | 7875 5175 7875 4500 6075 4500 6075 5175 7875 5175 14 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 15 | 5175 2025 5175 1350 3375 1350 3375 2025 5175 2025 16 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 17 | 5175 3150 5175 2475 3375 2475 3375 3150 5175 3150 18 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 19 | 0 0 1.00 60.00 120.00 20 | 4275 2025 4275 4500 21 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 22 | 5175 4275 5175 3600 3375 3600 3375 4275 5175 4275 23 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 24 | 5175 5175 5175 4500 3375 4500 3375 5175 5175 5175 25 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 26 | 0 0 1.00 60.00 120.00 27 | 5175 4725 6075 4725 28 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 29 | 0 0 1.00 60.00 120.00 30 | 5175 4950 6075 4950 31 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 32 | 0 0 1.00 60.00 120.00 33 | 12600 2025 12600 4500 34 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 35 | 13500 5175 13500 4500 11700 4500 11700 5175 13500 5175 36 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 37 | 0 0 1.00 60.00 120.00 38 | 10575 4950 11700 4950 39 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 40 | 10575 5175 10575 4500 8775 4500 8775 5175 10575 5175 41 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 42 | 13500 2025 13500 1350 11700 1350 11700 2025 13500 2025 43 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 44 | 0 0 1.00 60.00 120.00 45 | 7875 4725 8775 4725 46 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 47 | 0 0 1.00 60.00 120.00 48 | 7875 4950 8775 4950 49 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 50 | 0 0 1.00 60.00 120.00 51 | 5175 1575 11700 1575 52 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 53 | 0 0 1.00 60.00 120.00 54 | 5175 1800 11700 1800 55 | 2 4 1 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 56 | 9675 3150 7875 3150 7875 2475 9675 2475 9675 3150 57 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 58 | 0 0 1.00 60.00 120.00 59 | 8550 2475 8550 1890 60 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 61 | 0 0 1.00 60.00 120.00 62 | 7875 3150 5850 4500 63 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 64 | 0 0 1.00 60.00 120.00 65 | 8550 3150 8325 4500 66 | 4 0 0 50 -1 0 12 0.0000 4 135 240 5535 900 OS\001 67 | 4 0 0 50 -1 0 12 0.0000 4 135 510 4050 1800 Client\001 68 | 4 0 0 50 -1 0 12 0.0000 4 180 1230 3600 2925 Graphic library\001 69 | 4 0 0 50 -1 0 12 0.0000 4 180 690 4050 2250 Drawing\001 70 | 4 0 0 50 -1 0 12 0.0000 4 135 690 4050 4050 Window\001 71 | 4 0 0 50 -1 0 12 0.0000 4 135 945 3825 4950 Back buffer\001 72 | 4 0 0 50 -1 0 12 0.0000 4 180 720 5400 4725 Dequeue\001 73 | 4 0 0 50 -1 0 12 0.0000 4 180 720 5400 4950 Enqueue\001 74 | 4 0 0 50 -1 0 12 0.0000 4 180 1005 12150 4950 Background\001 75 | 4 0 0 50 -1 0 12 0.0000 4 135 660 10800 4950 Content\001 76 | 4 0 0 50 -1 0 12 0.0000 4 135 960 9225 4950 Front buffer\001 77 | 4 0 0 50 -1 0 12 0.0000 4 180 825 12150 1800 Composer\001 78 | 4 0 0 50 -1 0 12 0.0000 4 180 1065 12150 2250 Compositing\001 79 | 4 0 0 50 -1 0 12 0.0000 4 180 645 8100 4725 Acquire\001 80 | 4 0 0 50 -1 0 12 0.0000 4 135 630 8100 4950 Release\001 81 | 4 0 0 50 -1 0 12 0.0000 4 135 1290 8100 1575 FrameAvailable\001 82 | 4 0 0 50 -1 0 12 0.0000 4 135 1245 8100 1800 BufferReleased\001 83 | 4 0 0 50 -1 0 12 0.0000 4 165 1035 6525 4950 BufferQueue\001 84 | 4 0 0 50 -1 0 12 0.0000 4 135 885 4050 1125 Client side\001 85 | 4 0 0 50 -1 0 12 0.0000 4 135 885 6300 1125 Server side\001 86 | 4 0 0 50 -1 0 12 0.0000 4 180 1695 8100 2925 IPC(binder) Message\001 87 | 4 0 0 50 -1 0 12 0.0000 4 180 2520 5175 675 Client side drawing / rendering\001 88 | -------------------------------------------------------------------------------- /document/original-design/original-design.md: -------------------------------------------------------------------------------- 1 | # 基本原理与设计思路 2 | * * * 3 | 4 | # 旧的设计的问题 5 | 6 | 在设计 X11 的年代,网络刚刚兴起,大型主机配上图形终端是用户使用计算机的普遍模式,所以采用 Client / Server 架构是很自然的事情。但是随着 PC 的兴起和大型主机的没落,在 PC 本地采用 C/S 架构设计图形系统,不但是多此一举的事情,而且还会影响性能。因此受到诸多人的指责。 7 | 8 | 原始的 X Server 的设计,可以简单的总结为客户端请求绘图/服务端执行绘图并显示这样的模式。见下面的示意图1。 9 | ![server side drawing](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/original-design/01-server-side-drawing.svg) 10 | 11 | 在这种模式中,客户端软件是不知道自己绘图的效果的,除非它向图形服务器发出请求,要求服务器回传当前的图形缓冲区回来。因此,有些功能就很难实现。例如,如果应用软件想录制当前的操作画面,需要操作完成后再要服务器回传回来才知道效果,就会很影响效率。 12 | 13 | 因为绘图算法库存在于图形服务器一端,还带来了几个问题: 14 | * X Server 会又大又复杂,很难优化,又容易造成系统崩溃。并且,X Server 是直接操作设备驱动的程序,这往往意味着它具有 root 特权。而大而复杂的 X Server 的安全问题,一直是大家的诟病之一。 15 | * 用户对图形库一直不满意。因为每天都会有新的需求,而绘图算法本身也在进化。而服务器本身又要求稳定,所以新的绘图效果很难进入到 X Server 中。例如,反锯齿算法和新的字体解析库,就很难进入到 X Server 中。 16 | * 更进一步的,新的模块就更难加入到 X Server 中。例如,视频解码库,进入到 X Server 中是不可能的事情。所以,在早期的 X Window 系统里,要播放视频,在客户端,软件解码一帧视频,当成一张图像传送给 X Server 显示,接着再来。如此反复循环,效率极低。 17 | 18 | # 新的设计的想法 19 | 20 | 于是有人针对上述问题提出了客户端绘图方案。见下面的示意图2。 21 | ![client side drawing](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/original-design/02-client-side-drawing.svg) 22 | 23 | 在新方案中,出现了两个大的变化。 24 | 25 | 一是将绘图算法库移动到客户端,由应用软件选择和自行调用。这样的好处有: 26 | * Grahpic Server 可以变小而易于维护,而绘图算法库可以单独升级而不影响服务器。 27 | * 应用软件可以按照需求,选择合适的图形库,例如,选择 cairo / skia / hwui 等图形库。 28 | 29 | 二是剪切域(clip-region)管理器变成了合成器(composer)。这意味着窗口间相互作用的算法有了增强: 30 | * 原本的剪切域(clip-region)算法,就是在窗口重叠遮盖的情况下,看看哪个窗口暴露出哪些矩形,然后如同剪报一样,把那些暴露出来的矩形剪出(cut)并粘贴(paste)到同一个背景里,最后显示出来。 31 | * 合成器(composer)处理的窗口,增加了一个alpha参数。窗口合成(compositing)算法增加了三大类: 32 | * 窗口本身增加了缩放、旋转、剪切变形等矩阵变换算法。 33 | * 窗口间合成增加了Porter-Duff的[合成算法](https://en.wikipedia.org/wiki/Alpha_compositing)。 34 | * 合成结果,增加了颜色空间转换的算法。 35 | 36 | 简单一句话,在新方案中,只由客户端生产内容,服务端只读取内容并不做修改,而是在显示路径上对内容进行修饰并显示出来。新方案的好处,除了增强了显示效果,提高了显示效率,还有一个好处,就是保证了显示的一致性。 37 | 38 | 在原始的 X Window 方案中,假如把本文在屏幕上显示、送到打印机打印,或者制作成 PDF 文档这些操作,可能会有不同的显示效果,因为在不同的系统里,所自带的字体和字体引擎不一样。而在新方案里,会有一致的效果,因为只是对同一个渲染(render)后的原稿选择不同的显示后端(backend)而已。另外,这也容易实现在玩游戏中常用的边显示边录制游戏画面的功能,对应用来说,只是同时选择了两个显示后端,一个是硬件显示后端,一个是带视频编码和保存功能的虚拟显示后端。 39 | 40 | 这种客户端绘图方案,最早是在 Plan9 OS 系统里的 8½ 的图形系统中得以实现。后来在 MS Windows 中也得到了实现。最后,过了不少年,终于在 Xorg 的 X Server 中,以[X Composite Extension](http://www.talisman.org/~erlkonig/misc/x11-composite-tutorial/)扩展的方式得以实现。但是,X Server 为了后向兼容,内部始终保留着原始的绘图算法代码。所以 X Server 的代码始终还是又大又复杂。而 Android 从一开始就选择了客户端绘图的方案,所以服务端的代码相对精简和易于理解。 41 | 42 | # 新的设计需要注意的第一个问题 43 | 44 | 但是,在上图中有一个细节需要注意,就是在客户端和服务端的对应同一个窗口的内容是如何传输或同步的。 45 | 46 | 我们先看在图形系统中一个窗口的抽象设计。见下图。 47 | 48 | ![窗口抽象示意图](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/original-design/03-window.svg) 49 | 50 | 一个窗口一般会分成两个部分:一个窗口本身的管理结构(struct),一个是可以存放绘图内容的内存块,一般称为缓冲区(buffer)。在习惯上,一般在讨论这块内存本身的特性和功能时,会称之为缓冲区(buffer);如果内存上面已经带有内容,则称之为帧(frame)。 51 | 52 | 一个窗口的设计,一般会有三个基本参数:width / height / format,还有两个和硬件相关的参数:stride / usage,在后面进行讨论。从这三个基本参数,我们可以大致估计出一帧图形所需要的内存块大小。 53 | 54 | 在这里我们可以估计一下,如果要在 RGBA8888 的颜色格式的窗口上以 25Hz 的速率播放 1080P 电影。则: 55 | ``` 56 | 1920 * 1080 * 4 * 25 = 207360000 bytes 57 | ``` 58 | 59 | 也就是一秒钟要生产 200MB 的内容。 60 | 61 | 如果我们采用类似 X Window 的原始的 C/S 架构设计,见下图: 62 | 63 | ![two stage copy](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/original-design/04-two-stage-copy.svg) 64 | 65 | 这样的设计简单,但是会造成对同一个内容占用两块内存,并且会有两次拷贝的问题。这既浪费内存又浪费时间。于是有人提出了零拷贝(zero-copy)方案。 66 | 67 | 零拷贝(zero-copy)的设计思路相当简单:就是 Client 端和 Server 端共享同一块内存。Client 端在本地绘制完成后,用某种同步机制通知 Server 端,Server 端就把同一块内存的内容显示到屏幕上。要实现在进程间共享内存,在 UNIX/Linux 世界里就需要 OS 提供的文件句柄传输功能。 68 | 69 | # 内存共享机制的底层基础 70 | 71 | 文件句柄传输在 UNIX/Linux 进程间通信方式中是共享信息效率最高的方式。它的思路很简单,就是由一个进程打开某个文件,然后将文件句柄通过 OS 提供的机制传输给有需要的进程。虽然在各个进程里句柄号不一样,但是都是对应到 OS 里的同一个文件系统中的数据结构,操作的是同一个文件。这样,如果有一个进程写了文件,其它进程就可以读到修改内容。 72 | 73 | 再进一步,在各个进程里,都可以使用"Memory Map(mmap)"系统调用将文件映射到内存里。这样,如果有一个进程修改了映射内存,其它进程也可以在其相应的映射内存里读到修改内容。再加上一些进程间的同步机制,进程间的大块数据就可以高效共享了。 74 | 75 | 更进一步的,如果这个文件句柄并没有关联到某个具体的磁盘文件上,而只是内存中某段地址的映射,比如 Linux 中著名的"FrameBuffer(fbdev)",打开文件就提供了显示内存的起始地址和大小,经过内存映射后,进程间就共享了同一块内存。 76 | 77 | 现在 UNIX/Linux 在用户空间提供共享内存功能的软件,大多数都采用这种方法实现。在《UNIX环境高级编程》(APUE)一书的第17章"高级进程间通信"中的"17.4 传送文件描述符"节,对这种机制有详细的描述。网上有一个共享软件"libancillary",对此也有经典的实现。如果对此感兴趣,也可以查看 glibc 里的"Shared Memory(shm)"模块,也是用类似的方法实现共享内存。 78 | 79 | 简单一句话,零拷贝(zero-copy)方案就是用文件句柄传输功能来实现共享内存机制。在标准的 UNIX/Linux 系统里,进程间传输文件句柄,都是采用 socket 带外数据传输的方式。在 Android 系统里,也可以采用专有的 binder 系统调用传输文件句柄。这两者的效果都一样。 80 | 81 | 另外,为了实现完整可用的共享内存机制,还需要 Linux 提供操作系统级别的原子同步机制,就是 Linux Fence 机制。后面会讨论这方面的内容。 82 | 83 | # 新的设计需要注意的第二个问题 84 | 85 | 因为现代 CPU 大多具有多核,因此多线程的程序在性能上更有优势。因为客户端绘图和服务端合成的代码分别运行在不同的进程/线程上,如果在一个窗口只包含一个缓冲区(Buffer),当客户端渲染时,服务端只能等待,当服务端合成时,客户端也只能等待。这很容易就造成阻塞,从而影响显示效果,也浪费 CPU 的能力。 86 | 87 | 所以,在窗口对象的设计中,采用双缓冲(double-buffer)是很自然的事情。在双缓冲(double-buffer)方案里: 88 | * 一个窗口的有两个缓冲区(Buffer):front buffer & back buffer。 89 | * 客户端把刚刚渲染完的帧(Frame)标记为 front buffer,另一个 buffer 等服务端合成完以后则为 back buffer。客户端在 back buffer 进行新的渲染。 90 | * 服务端发现有新的 front buffer,则取过来进行合成并显示出去。 91 | * 这样,在生产者和消费者两端的速度一致的情况下,客户端和服务端就很少发生竞争资源的情况,因此就很少发生阻塞,显示就会平滑。这也是经典的以空间换时间的方案。 92 | 93 | 既然能有双缓冲(double-buffer)方案,为什么没有三缓冲(triple-buffer)方案?更进一步的,既然能有三缓冲(triple-buffer)方案,各种软件的需求不同,为什么没有多缓冲(multi-buffer)方案?于是,Android 图形系统里著名的 BufferQueue 类就产生了。 94 | 95 | BufferQueue 类在 Android 图形系统里是核心类,管理着一个可变长队列的缓冲池(Buffer Pool)。如其名字所言,它本质上就是管理缓冲区队列(Buffer Queue),按照需求对外提供缓冲区(Buffer)。BufferQueue 类在后面的章节里会有详细的分析和讨论。 96 | 97 | # 新的窗口方案设计 98 | 99 | 因此,窗口对象新的设计示意图如下: 100 | 101 | ![zero-copy & BufferQueue](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/original-design/05-zero-copy.svg) 102 | 103 | 在新的设计里: 104 | * Client Window 从 BufferQueue 得到的永远是 back buffer。客户端软件将在上面生成新的内容。 105 | * Server Composer 从 BufferQueue 得到的永远 是 front buffer。服务端软件将从中得到客户已经生成的内容。 106 | * Client / BufferQueue / Server 三方,分别处于不同的进程/线程中。三方之间的状态同步,使用 IPC(binder) 进行通信。同时,尽管跨越了进程,zero-copy 的技术保证了一份内容只有一个拷贝。这极大地减少了内存消耗也极大地提高了效率。 107 | * Buffer & Pool本身的管理,包括 size / count / status 等,将由 BufferQueue 管理。这样减轻了两端的工作量。 108 | 109 | # 小结 110 | 111 | 最终,Android 图形系统在设计上最基本的思路和功能就是: 112 | * 客户端完成绘图或渲染功能。特点是采用 GPU 绘图或渲染,为此在 EGL / OpenGLES 方面提供了基于 Android 的扩展。经典的实现是 skia 和 hwui 库。 113 | * 服务端实现完整的合成功能。标志是提供了完整的矩阵变换、Porter-Duff 合成算法、颜色空间转换功能。 114 | * C/S 架构之间采用 zero-copy 方式同步数据。就是用文件句柄传输功能、IPC(binder) 和 Fence 功能来实现共享内存机制。 115 | * Client / BufferQueue / Server 三方协同工作,在设计模式中就是一个经典的 Producer-Consumer 模式。我们将在下一章简单回顾在 Android 图形系统中常用的设计模式。 116 | 117 | -------------------------------------------------------------------------------- /document/pattern-design/01-bufferqueue-01.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 11 | 7875 2250 7875 1575 6075 1575 6075 2250 7875 2250 12 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 13 | 0 0 1.00 60.00 120.00 14 | 5175 1800 6075 1800 15 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 16 | 0 0 1.00 60.00 120.00 17 | 5175 2025 6075 2025 18 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 19 | 10575 2250 10575 1575 8775 1575 8775 2250 10575 2250 20 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 21 | 0 0 1.00 60.00 120.00 22 | 7875 1800 8775 1800 23 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 24 | 0 0 1.00 60.00 120.00 25 | 7875 2025 8775 2025 26 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 27 | 5175 2250 5175 1575 3375 1575 3375 2250 5175 2250 28 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 29 | 5625 900 5625 5625 30 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 31 | 7875 3825 7875 3150 6075 3150 6075 3825 7875 3825 32 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 33 | 7875 5400 7875 4725 6075 4725 6075 5400 7875 5400 34 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 35 | 5175 5400 5175 4725 3375 4725 3375 5400 5175 5400 36 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 37 | 5175 3825 5175 3150 3375 3150 3375 3825 5175 3825 38 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 39 | 0 0 1.00 60.00 120.00 40 | 4275 3825 4275 4725 41 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 42 | 0 0 1.00 60.00 120.00 43 | 5175 3375 6075 3375 44 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 45 | 0 0 1.00 60.00 120.00 46 | 6975 3825 6975 4725 47 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 48 | 0 0 1.00 60.00 120.00 49 | 5175 5175 6075 5175 50 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 51 | 0 0 1.00 60.00 120.00 52 | 5175 3600 6075 3600 53 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 54 | 3150 2700 10800 2700 55 | 4 0 0 50 -1 0 12 0.0000 4 135 240 5535 900 OS\001 56 | 4 0 0 50 -1 0 12 0.0000 4 135 885 6300 1125 Server side\001 57 | 4 0 0 50 -1 0 12 0.0000 4 180 720 5400 1800 Dequeue\001 58 | 4 0 0 50 -1 0 12 0.0000 4 180 720 5400 2025 Enqueue\001 59 | 4 0 0 50 -1 0 12 0.0000 4 180 645 8100 1800 Acquire\001 60 | 4 0 0 50 -1 0 12 0.0000 4 135 630 8100 2025 Release\001 61 | 4 0 0 50 -1 0 12 0.0000 4 165 1035 6525 2025 BufferQueue\001 62 | 4 0 0 50 -1 0 12 0.0000 4 135 720 3825 2025 Producer\001 63 | 4 0 0 50 -1 0 12 0.0000 4 135 825 9225 2025 Consumer\001 64 | 4 0 0 50 -1 0 12 0.0000 4 135 885 4050 1125 Client side\001 65 | 4 0 0 50 -1 0 12 0.0000 4 135 1785 4950 450 Resource Pool Pattern\001 66 | 4 0 0 50 -1 0 12 0.0000 4 180 825 3825 3600 Dequeued\001 67 | 4 0 0 50 -1 0 12 0.0000 4 180 825 3825 5175 Enqueued\001 68 | 4 0 0 50 -1 0 12 0.0000 4 180 750 6525 5175 Acquired\001 69 | 4 0 0 50 -1 0 12 0.0000 4 135 345 6525 3600 Free\001 70 | 4 0 0 50 -1 0 12 0.0000 4 180 720 5400 3375 Dequeue\001 71 | 4 0 0 50 -1 0 12 0.0000 4 135 570 5400 3600 Cancel\001 72 | 4 0 0 50 -1 0 12 0.0000 4 180 720 4050 4275 Enqueue\001 73 | 4 0 0 50 -1 0 12 0.0000 4 180 645 5400 5175 Acquire\001 74 | 4 0 0 50 -1 0 12 0.0000 4 135 630 6750 4275 Release\001 75 | 4 0 0 50 -1 0 12 0.0000 4 135 1200 4950 5850 Resource State\001 76 | -------------------------------------------------------------------------------- /document/pattern-design/02-bufferqueue-02.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 11 | 7875 2250 7875 1575 6075 1575 6075 2250 7875 2250 12 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 13 | 0 0 1.00 60.00 120.00 14 | 5175 1800 6075 1800 15 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 16 | 0 0 1.00 60.00 120.00 17 | 5175 2025 6075 2025 18 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 19 | 0 0 1.00 60.00 120.00 20 | 7875 1800 8775 1800 21 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 22 | 0 0 1.00 60.00 120.00 23 | 7875 2025 8775 2025 24 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 25 | 5175 2250 5175 1575 3375 1575 3375 2250 5175 2250 26 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 27 | 7875 3825 7875 3150 6075 3150 6075 3825 7875 3825 28 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 29 | 7875 5400 7875 4725 6075 4725 6075 5400 7875 5400 30 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 31 | 5175 5400 5175 4725 3375 4725 3375 5400 5175 5400 32 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 33 | 5175 3825 5175 3150 3375 3150 3375 3825 5175 3825 34 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 35 | 0 0 1.00 60.00 120.00 36 | 4275 3825 4275 4725 37 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 38 | 0 0 1.00 60.00 120.00 39 | 5175 3375 6075 3375 40 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 41 | 0 0 1.00 60.00 120.00 42 | 6975 3825 6975 4725 43 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 44 | 0 0 1.00 60.00 120.00 45 | 5175 5175 6075 5175 46 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 47 | 0 0 1.00 60.00 120.00 48 | 5175 3600 6075 3600 49 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 50 | 3150 2700 10800 2700 51 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 52 | 10575 1125 10575 450 8775 450 8775 1125 10575 1125 53 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 54 | 10575 2250 10575 1575 8775 1575 8775 2250 10575 2250 55 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 56 | 1 0 1.00 150.00 150.00 57 | 9675 1125 9675 1575 58 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 59 | 5625 225 5625 5625 60 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 3 61 | 0 0 1.00 60.00 120.00 62 | 6975 1575 6975 675 8775 675 63 | 4 0 0 50 -1 0 12 0.0000 4 180 720 5400 1800 Dequeue\001 64 | 4 0 0 50 -1 0 12 0.0000 4 180 720 5400 2025 Enqueue\001 65 | 4 0 0 50 -1 0 12 0.0000 4 180 645 8100 1800 Acquire\001 66 | 4 0 0 50 -1 0 12 0.0000 4 135 630 8100 2025 Release\001 67 | 4 0 0 50 -1 0 12 0.0000 4 165 1035 6525 2025 BufferQueue\001 68 | 4 0 0 50 -1 0 12 0.0000 4 135 720 3825 2025 Producer\001 69 | 4 0 0 50 -1 0 12 0.0000 4 135 825 9225 2025 Consumer\001 70 | 4 0 0 50 -1 0 12 0.0000 4 180 825 3825 3600 Dequeued\001 71 | 4 0 0 50 -1 0 12 0.0000 4 180 825 3825 5175 Enqueued\001 72 | 4 0 0 50 -1 0 12 0.0000 4 180 750 6525 5175 Acquired\001 73 | 4 0 0 50 -1 0 12 0.0000 4 135 345 6525 3600 Free\001 74 | 4 0 0 50 -1 0 12 0.0000 4 180 720 5400 3375 Dequeue\001 75 | 4 0 0 50 -1 0 12 0.0000 4 135 570 5400 3600 Cancel\001 76 | 4 0 0 50 -1 0 12 0.0000 4 180 720 4050 4275 Enqueue\001 77 | 4 0 0 50 -1 0 12 0.0000 4 180 645 5400 5175 Acquire\001 78 | 4 0 0 50 -1 0 12 0.0000 4 135 630 6750 4275 Release\001 79 | 4 0 0 50 -1 0 12 0.0000 4 135 1200 4950 5850 Resource State\001 80 | 4 0 0 50 -1 0 12 0.0000 4 135 885 6075 225 Server side\001 81 | 4 0 0 50 -1 0 12 0.0000 4 135 1485 9000 900 ConsumerListener\001 82 | 4 0 0 50 -1 0 12 0.0000 4 135 2640 4950 -225 Resource Pool + Listener Pattern\001 83 | 4 0 0 50 -1 0 12 0.0000 4 135 240 5535 180 OS\001 84 | 4 0 0 50 -1 0 12 0.0000 4 135 885 4275 225 Client side\001 85 | 4 0 0 50 -1 0 12 0.0000 4 135 1290 7425 675 FrameAvailable\001 86 | -------------------------------------------------------------------------------- /document/pattern-design/03-bufferqueue-03.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 11 | 7875 2250 7875 1575 6075 1575 6075 2250 7875 2250 12 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 13 | 0 0 1.00 60.00 120.00 14 | 7875 1800 8775 1800 15 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 16 | 0 0 1.00 60.00 120.00 17 | 7875 2025 8775 2025 18 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 19 | 900 2700 10800 2700 20 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 21 | 10575 1125 10575 450 8775 450 8775 1125 10575 1125 22 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 23 | 10575 2250 10575 1575 8775 1575 8775 2250 10575 2250 24 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 25 | 1 0 1.00 150.00 150.00 26 | 9675 1125 9675 1575 27 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 28 | 5625 2250 5625 1575 4950 1575 4950 2250 5625 2250 29 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 30 | 6975 4050 6975 3375 5175 3375 5175 4050 6975 4050 31 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 32 | 6975 5625 6975 4950 5175 4950 5175 5625 6975 5625 33 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 34 | 4275 5625 4275 4950 2475 4950 2475 5625 4275 5625 35 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 36 | 4275 4050 4275 3375 2475 3375 2475 4050 4275 4050 37 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 38 | 0 0 1.00 60.00 120.00 39 | 3375 4050 3375 4950 40 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 41 | 0 0 1.00 60.00 120.00 42 | 4275 3600 5175 3600 43 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 44 | 0 0 1.00 60.00 120.00 45 | 6075 4050 6075 4950 46 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 47 | 0 0 1.00 60.00 120.00 48 | 4275 5400 5175 5400 49 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 50 | 0 0 1.00 60.00 120.00 51 | 4275 3825 5175 3825 52 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 53 | 0 0 1.00 60.00 120.00 54 | 2925 1800 3825 1800 55 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 56 | 0 0 1.00 60.00 120.00 57 | 2925 2025 3825 2025 58 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 59 | 2925 2250 2925 1575 1125 1575 1125 2250 2925 2250 60 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 61 | 0 0 1.00 60.00 120.00 62 | 6075 1800 5625 1800 63 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 64 | 0 0 1.00 60.00 120.00 65 | 4500 2025 4950 2025 66 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 67 | 0 0 1.00 60.00 120.00 68 | 5625 2025 6075 2025 69 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 70 | 4500 2250 4500 1575 3825 1575 3825 2250 4500 2250 71 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 72 | 4725 450 4725 5850 73 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 74 | 0 0 1.00 60.00 120.00 75 | 4500 1800 4950 1800 76 | 2 4 1 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 77 | 5625 1350 5625 2475 3825 2475 3825 1350 5625 1350 78 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 3 79 | 0 0 1.00 60.00 120.00 80 | 6975 1575 6975 675 8775 675 81 | 4 0 0 50 -1 0 12 0.0000 4 180 645 8100 1800 Acquire\001 82 | 4 0 0 50 -1 0 12 0.0000 4 135 630 8100 2025 Release\001 83 | 4 0 0 50 -1 0 12 0.0000 4 165 1035 6525 2025 BufferQueue\001 84 | 4 0 0 50 -1 0 12 0.0000 4 135 825 9225 2025 Consumer\001 85 | 4 0 0 50 -1 0 12 0.0000 4 135 1485 9000 900 ConsumerListener\001 86 | 4 0 0 50 -1 0 12 0.0000 4 135 240 5175 2025 Bn\001 87 | 4 0 0 50 -1 0 12 0.0000 4 180 240 4050 2025 Bp\001 88 | 4 0 0 50 -1 0 12 0.0000 4 135 885 3375 225 Client side\001 89 | 4 0 0 50 -1 0 12 0.0000 4 135 885 5175 225 Server side\001 90 | 4 0 0 50 -1 0 12 0.0000 4 180 825 2925 3825 Dequeued\001 91 | 4 0 0 50 -1 0 12 0.0000 4 180 825 2925 5400 Enqueued\001 92 | 4 0 0 50 -1 0 12 0.0000 4 180 750 5625 5400 Acquired\001 93 | 4 0 0 50 -1 0 12 0.0000 4 135 345 5625 3825 Free\001 94 | 4 0 0 50 -1 0 12 0.0000 4 180 720 4500 3600 Dequeue\001 95 | 4 0 0 50 -1 0 12 0.0000 4 135 570 4500 3825 Cancel\001 96 | 4 0 0 50 -1 0 12 0.0000 4 180 720 3150 4500 Enqueue\001 97 | 4 0 0 50 -1 0 12 0.0000 4 180 645 4500 5400 Acquire\001 98 | 4 0 0 50 -1 0 12 0.0000 4 135 630 5850 4500 Release\001 99 | 4 0 0 50 -1 0 12 0.0000 4 135 1200 4050 6075 Resource State\001 100 | 4 0 0 50 -1 0 12 0.0000 4 135 240 4635 405 OS\001 101 | 4 0 0 50 -1 0 12 0.0000 4 180 720 3150 1800 Dequeue\001 102 | 4 0 0 50 -1 0 12 0.0000 4 180 720 3150 2025 Enqueue\001 103 | 4 0 0 50 -1 0 12 0.0000 4 135 720 1575 2025 Producer\001 104 | 4 0 0 50 -1 0 12 0.0000 4 180 3315 3375 -225 Resource Pool + Listener + Proxy Pattern\001 105 | 4 0 0 50 -1 0 12 0.0000 4 180 480 4500 1575 Proxy\001 106 | 4 0 0 50 -1 0 12 0.0000 4 135 1290 7425 675 FrameAvailable\001 107 | -------------------------------------------------------------------------------- /document/pattern-design/04-bufferqueue-04.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 11 | 7875 2250 7875 1575 6075 1575 6075 2250 7875 2250 12 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 13 | 0 0 1.00 60.00 120.00 14 | 7875 2025 8775 2025 15 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 16 | 900 2700 10800 2700 17 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 18 | 10575 1125 10575 450 8775 450 8775 1125 10575 1125 19 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 20 | 10575 2250 10575 1575 8775 1575 8775 2250 10575 2250 21 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 22 | 1 0 1.00 150.00 150.00 23 | 9675 1125 9675 1575 24 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 3 25 | 0 0 1.00 60.00 120.00 26 | 6975 1575 6975 675 8775 675 27 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 28 | 5625 2250 5625 1575 4950 1575 4950 2250 5625 2250 29 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 30 | 6975 4050 6975 3375 5175 3375 5175 4050 6975 4050 31 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 32 | 6975 5625 6975 4950 5175 4950 5175 5625 6975 5625 33 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 34 | 4275 5625 4275 4950 2475 4950 2475 5625 4275 5625 35 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 36 | 4275 4050 4275 3375 2475 3375 2475 4050 4275 4050 37 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 38 | 0 0 1.00 60.00 120.00 39 | 3375 4050 3375 4950 40 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 41 | 0 0 1.00 60.00 120.00 42 | 6075 4050 6075 4950 43 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 44 | 0 0 1.00 60.00 120.00 45 | 4275 5400 5175 5400 46 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 47 | 0 0 1.00 60.00 120.00 48 | 4275 3825 5175 3825 49 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 50 | 0 0 1.00 60.00 120.00 51 | 2925 2025 3825 2025 52 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 53 | 2925 2250 2925 1575 1125 1575 1125 2250 2925 2250 54 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 55 | 0 0 1.00 60.00 120.00 56 | 6075 1800 5625 1800 57 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 58 | 0 0 1.00 60.00 120.00 59 | 4500 2025 4950 2025 60 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 61 | 0 0 1.00 60.00 120.00 62 | 5625 2025 6075 2025 63 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 64 | 4500 2250 4500 1575 3825 1575 3825 2250 4500 2250 65 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 66 | 4725 450 4725 5850 67 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 68 | 0 0 1.00 60.00 120.00 69 | 4500 1800 4950 1800 70 | 2 4 1 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 71 | 5625 1350 5625 2475 3825 2475 3825 1350 5625 1350 72 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 73 | 0 0 1.00 60.00 120.00 74 | 4275 3600 5175 3600 75 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 76 | 0 0 1.00 60.00 120.00 77 | 7875 1800 8775 1800 78 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 79 | 0 0 1.00 60.00 120.00 80 | 2925 1800 3825 1800 81 | 4 0 0 50 -1 0 12 0.0000 4 135 630 8100 2025 Release\001 82 | 4 0 0 50 -1 0 12 0.0000 4 165 1035 6525 2025 BufferQueue\001 83 | 4 0 0 50 -1 0 12 0.0000 4 135 825 9225 2025 Consumer\001 84 | 4 0 0 50 -1 0 12 0.0000 4 135 1485 9000 900 ConsumerListener\001 85 | 4 0 0 50 -1 0 12 0.0000 4 135 240 5175 2025 Bn\001 86 | 4 0 0 50 -1 0 12 0.0000 4 180 240 4050 2025 Bp\001 87 | 4 0 0 50 -1 0 12 0.0000 4 135 885 3375 225 Client side\001 88 | 4 0 0 50 -1 0 12 0.0000 4 135 885 5175 225 Server side\001 89 | 4 0 0 50 -1 0 12 0.0000 4 180 825 2925 3825 Dequeued\001 90 | 4 0 0 50 -1 0 12 0.0000 4 180 825 2925 5400 Enqueued\001 91 | 4 0 0 50 -1 0 12 0.0000 4 180 750 5625 5400 Acquired\001 92 | 4 0 0 50 -1 0 12 0.0000 4 135 345 5625 3825 Free\001 93 | 4 0 0 50 -1 0 12 0.0000 4 135 570 4500 3825 Cancel\001 94 | 4 0 0 50 -1 0 12 0.0000 4 180 720 3150 4500 Enqueue\001 95 | 4 0 0 50 -1 0 12 0.0000 4 180 645 4500 5400 Acquire\001 96 | 4 0 0 50 -1 0 12 0.0000 4 135 630 5850 4500 Release\001 97 | 4 0 0 50 -1 0 12 0.0000 4 135 1200 4050 6075 Resource State\001 98 | 4 0 0 50 -1 0 12 0.0000 4 135 240 4635 405 OS\001 99 | 4 0 0 50 -1 0 12 0.0000 4 180 720 3150 2025 Enqueue\001 100 | 4 0 0 50 -1 0 12 0.0000 4 135 720 1575 2025 Producer\001 101 | 4 0 0 50 -1 0 12 0.0000 4 180 480 4500 1575 Proxy\001 102 | 4 0 0 50 -1 0 12 0.0000 4 180 3990 3375 -225 Resource Pool + Listener + Proxy + Fnece Pattern\001 103 | 4 0 0 50 -1 0 12 0.0000 4 165 1380 7875 2250 (with new Fence)\001 104 | 4 0 0 50 -1 0 12 0.0000 4 180 720 4500 3375 Dequeue\001 105 | 4 0 0 50 -1 0 12 0.0000 4 165 1170 4275 3600 (Check Fence)\001 106 | 4 0 0 50 -1 0 12 0.0000 4 165 1380 5625 4725 (with new Fence)\001 107 | 4 0 0 50 -1 0 12 0.0000 4 135 1290 7425 675 FrameAvailable\001 108 | 4 0 0 50 -1 0 12 0.0000 4 180 645 8100 1575 Acquire\001 109 | 4 0 0 50 -1 0 12 0.0000 4 165 1380 2925 2250 (with new Fence)\001 110 | 4 0 0 50 -1 0 12 0.0000 4 165 1170 7875 1800 (Check Fence)\001 111 | 4 0 0 50 -1 0 12 0.0000 4 165 1380 2925 4725 (with new Fence)\001 112 | 4 0 0 50 -1 0 12 0.0000 4 165 1170 4275 5625 (Check Fence)\001 113 | 4 0 0 50 -1 0 12 0.0000 4 165 1170 2925 1800 (Check Fence)\001 114 | 4 0 0 50 -1 0 12 0.0000 4 180 720 3150 1575 Dequeue\001 115 | -------------------------------------------------------------------------------- /document/pattern-design/05-bufferqueue-05.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.7a 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 11 | 7875 2250 7875 1575 6075 1575 6075 2250 7875 2250 12 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 13 | 0 0 1.00 60.00 120.00 14 | 7875 2025 8775 2025 15 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 16 | 900 2700 10800 2700 17 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 18 | 10575 1125 10575 450 8775 450 8775 1125 10575 1125 19 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 20 | 1 0 1.00 150.00 150.00 21 | 9675 1125 9675 1575 22 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 3 23 | 0 0 1.00 60.00 120.00 24 | 6975 1575 6975 675 8775 675 25 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 26 | 5625 2250 5625 1575 4950 1575 4950 2250 5625 2250 27 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 28 | 6975 4050 6975 3375 5175 3375 5175 4050 6975 4050 29 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 30 | 6975 5625 6975 4950 5175 4950 5175 5625 6975 5625 31 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 32 | 4275 5625 4275 4950 2475 4950 2475 5625 4275 5625 33 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 34 | 0 0 1.00 60.00 120.00 35 | 3375 4050 3375 4950 36 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 37 | 0 0 1.00 60.00 120.00 38 | 6075 4050 6075 4950 39 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 40 | 0 0 1.00 60.00 120.00 41 | 4275 5400 5175 5400 42 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 43 | 0 0 1.00 60.00 120.00 44 | 4275 3825 5175 3825 45 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 46 | 0 0 1.00 60.00 120.00 47 | 2925 2025 3825 2025 48 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 49 | 2925 2250 2925 1575 1125 1575 1125 2250 2925 2250 50 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 51 | 0 0 1.00 60.00 120.00 52 | 6075 1800 5625 1800 53 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 54 | 0 0 1.00 60.00 120.00 55 | 4500 2025 4950 2025 56 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 57 | 0 0 1.00 60.00 120.00 58 | 5625 2025 6075 2025 59 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 60 | 4500 2250 4500 1575 3825 1575 3825 2250 4500 2250 61 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 62 | 0 0 1.00 60.00 120.00 63 | 4500 1800 4950 1800 64 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 65 | 0 0 1.00 60.00 120.00 66 | 2925 1800 3825 1800 67 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 68 | 10575 0 10575 -675 8775 -675 8775 0 10575 0 69 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 70 | 4725 -900 4725 5850 71 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 72 | 7875 0 7875 -675 6075 -675 6075 0 7875 0 73 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 3 74 | 0 0 1.00 60.00 120.00 75 | 2025 1575 2025 -450 6075 -450 76 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 77 | 0 0 1.00 60.00 120.00 78 | 7875 -450 8775 -450 79 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 80 | 12825 0 12825 -675 11025 -675 11025 0 12825 0 81 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 82 | 0 0 1.00 60.00 120.00 83 | 11025 -450 10575 -450 84 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 4 85 | 0 0 1.00 60.00 120.00 86 | 10575 -225 10800 -225 10800 2025 10575 2025 87 | 2 4 1 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5 88 | 5625 -675 5625 2475 3825 2475 3825 -675 5625 -675 89 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 90 | 10575 2250 10575 1575 8775 1575 8775 2250 10575 2250 91 | 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 92 | 4275 4050 4275 3375 2475 3375 2475 4050 4275 4050 93 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 94 | 0 0 1.00 60.00 120.00 95 | 7875 1800 8775 1800 96 | 2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2 97 | 0 0 1.00 60.00 120.00 98 | 4275 3600 5175 3600 99 | 4 0 0 50 -1 0 12 0.0000 4 135 630 8100 2025 Release\001 100 | 4 0 0 50 -1 0 12 0.0000 4 165 1035 6525 2025 BufferQueue\001 101 | 4 0 0 50 -1 0 12 0.0000 4 135 825 9225 2025 Consumer\001 102 | 4 0 0 50 -1 0 12 0.0000 4 135 1485 9000 900 ConsumerListener\001 103 | 4 0 0 50 -1 0 12 0.0000 4 135 240 5175 2025 Bn\001 104 | 4 0 0 50 -1 0 12 0.0000 4 180 240 4050 2025 Bp\001 105 | 4 0 0 50 -1 0 12 0.0000 4 180 825 2925 3825 Dequeued\001 106 | 4 0 0 50 -1 0 12 0.0000 4 180 825 2925 5400 Enqueued\001 107 | 4 0 0 50 -1 0 12 0.0000 4 180 750 5625 5400 Acquired\001 108 | 4 0 0 50 -1 0 12 0.0000 4 135 345 5625 3825 Free\001 109 | 4 0 0 50 -1 0 12 0.0000 4 135 570 4500 3825 Cancel\001 110 | 4 0 0 50 -1 0 12 0.0000 4 180 720 3150 4500 Enqueue\001 111 | 4 0 0 50 -1 0 12 0.0000 4 180 645 4500 5400 Acquire\001 112 | 4 0 0 50 -1 0 12 0.0000 4 135 630 5850 4500 Release\001 113 | 4 0 0 50 -1 0 12 0.0000 4 135 1200 4050 6075 Resource State\001 114 | 4 0 0 50 -1 0 12 0.0000 4 180 720 3150 2025 Enqueue\001 115 | 4 0 0 50 -1 0 12 0.0000 4 135 720 1575 2025 Producer\001 116 | 4 0 0 50 -1 0 12 0.0000 4 180 480 4500 1575 Proxy\001 117 | 4 0 0 50 -1 0 12 0.0000 4 165 1380 7875 2250 (with new Fence)\001 118 | 4 0 0 50 -1 0 12 0.0000 4 180 720 3150 1575 Dequeue\001 119 | 4 0 0 50 -1 0 12 0.0000 4 165 1170 2925 1800 (Check Fence)\001 120 | 4 0 0 50 -1 0 12 0.0000 4 165 1380 5625 4725 (with new Fence)\001 121 | 4 0 0 50 -1 0 12 0.0000 4 135 1290 7425 675 FrameAvailable\001 122 | 4 0 0 50 -1 0 12 0.0000 4 135 885 3375 -1125 Client side\001 123 | 4 0 0 50 -1 0 12 0.0000 4 135 885 5175 -1125 Server side\001 124 | 4 0 0 50 -1 0 12 0.0000 4 135 240 4635 -945 OS\001 125 | 4 0 0 50 -1 0 12 0.0000 4 135 750 9225 -225 Schedule\001 126 | 4 0 0 50 -1 0 12 0.0000 4 135 645 11475 -225 VSYNC\001 127 | 4 0 0 50 -1 0 12 0.0000 4 180 1050 2925 -450 postMessage\001 128 | 4 0 0 50 -1 0 12 0.0000 4 180 1230 6300 -225 MessageQueue\001 129 | 4 0 0 50 -1 0 12 0.0000 4 180 540 10575 -450 trigger\001 130 | 4 0 0 50 -1 0 12 0.0000 4 180 1260 7875 -450 handleMessage\001 131 | 4 0 0 50 -1 0 12 0.0000 4 180 720 10575 1575 Dispatch\001 132 | 4 0 0 50 -1 0 12 0.0000 4 180 7095 3375 -1575 Resource Pool + Listener + Proxy + Fnece + Schedule + MessageQueue + trigger Pattern\001 133 | 4 0 0 50 -1 0 12 0.0000 4 165 1380 2925 4725 (with new Fence)\001 134 | 4 0 0 50 -1 0 12 0.0000 4 165 1380 2925 2250 (with new Fence)\001 135 | 4 0 0 50 -1 0 12 0.0000 4 180 645 8100 1575 Acquire\001 136 | 4 0 0 50 -1 0 12 0.0000 4 165 1170 7875 1800 (Check Fence)\001 137 | 4 0 0 50 -1 0 12 0.0000 4 165 1170 4275 5625 (Check Fence)\001 138 | 4 0 0 50 -1 0 12 0.0000 4 165 1170 4275 3600 (Check Fence)\001 139 | 4 0 0 50 -1 0 12 0.0000 4 180 720 4500 3375 Dequeue\001 140 | -------------------------------------------------------------------------------- /document/pattern-design/Active_Object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/pattern-design/Active_Object.png -------------------------------------------------------------------------------- /document/pattern-design/command_implementation_-_uml_class_diagram.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/pattern-design/command_implementation_-_uml_class_diagram.gif -------------------------------------------------------------------------------- /document/pattern-design/observer_implementation_-_uml_class_diagram.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/document/pattern-design/observer_implementation_-_uml_class_diagram.gif -------------------------------------------------------------------------------- /document/server-algorithm/compositing-path.md: -------------------------------------------------------------------------------- 1 | # 合成流程中的路径 2 | 3 | 这里简单回顾在 Main thread 中合成操作相关的消息处理流程,就是为了处理这 2 个消息: 4 | * INVALIDATE 5 | * REFRESH 6 | 7 | ```C++ 8 | 00) SurfaceFlinger::run() - Main thread 9 | 01) SurfaceFlinger::waitForEvent() 10 | 02) MessageQueue::waitMessage() 11 | 03) Looper::pollOnce(-1) 12 | 04) epoll_wait 13 | 04) MessageQueue::Handler::handleMessage(MessageType) 14 | 05) case INVALIDATE: 15 | 05) case REFRESH: 16 | ``` 17 | 18 | VSYNC 信号到达后,会进行 INVALIDATE 消息处理,接着会触发 REFRESH 消息,在下一个循环中会进行 REFRESH 消息处理: 19 | ```C++ 20 | 00) MessageQueue::cb_eventReceiver() - Binder thread 21 | 01) MessageQueue::eventReceiver(DISPLAY_EVENT_VSYNC) 22 | 02) MessageQueue::Handler::dispatchInvalidate() 23 | 03) Looper::sendMessage(MessageQueue::INVALIDATE) 24 | 25 | next loop: - Main thread 26 | case INVALIDATE: 27 | 03) Looper::pollOnce(-1) 28 | 04) epoll_wait 29 | 04) MessageQueue::Handler::handleMessage(MessageQueue::INVALIDATE) 30 | 05) SurfaceFlinger::onMessageReceived(MessageQueue::INVALIDATE) 31 | 06) SurfaceFlinger::handleMessageTransaction() 32 | 07) SurfaceFlinger::handleTransaction() 33 | 08) SurfaceFlinger::handleTransactionLocked() 34 | 06) SurfaceFlinger::handleMessageInvalidate() 35 | 06) SurfaceFlinger::signalRefresh() 36 | 07) // sends REFRESH message immediately 37 | 07) MessageQueue::refresh() 38 | 08) MessageQueue::Handler::dispatchRefresh() 39 | 09) Looper::sendMessage(MessageQueue::REFRESH) 40 | 41 | next loop: - Main thread 42 | case REFRESH: 43 | 03) Looper::pollOnce(-1) 44 | 04) epoll_wait 45 | 04) MessageQueue::Handler::handleMessage(MessageQueue::REFRESH) 46 | 05) SurfaceFlinger::onMessageReceived(MessageQueue::REFRESH) 47 | 06) SurfaceFlinger::handleMessageRefresh() 48 | 07) SurfaceFlinger::preComposition(); 49 | 07) SurfaceFlinger::rebuildLayerStacks(); 50 | 07) SurfaceFlinger::calculateWorkingSet(); 51 | 07) SurfaceFlinger::beginFrame(); 52 | 07) SurfaceFlinger::prepareFrame(); 53 | 07) SurfaceFlinger::doDebugFlashRegions(); 54 | 07) SurfaceFlinger::doComposition(); 55 | 07) SurfaceFlinger::postFrame(); 56 | 07) SurfaceFlinger::postComposition(); 57 | ``` 58 | 59 | 在后面我们主要关注页面更新流程算法和合成操作流程算法: 60 | * handleMessageInvalidate() 61 | * handleMessageRefresh() 62 | 63 | 相应的操作流程见前面[ 两阶段流水线设计 ](../general-design/2-stage.md)章节的内容。 64 | 65 | -------------------------------------------------------------------------------- /document/server-design/component-pattern.md: -------------------------------------------------------------------------------- 1 | # 架构设计与组合模式 2 | 3 | 在 SurfaceFlinger 程序里应用了 Active Object 设计模式,主要是考虑到以下几点: 4 | * 在 SurfaceFlinger 程序里最主要的功能就是合成各层的内容。同时这也是最耗时的功能。在操作过程中不可打断,否则显示内容会出问题。 5 | * 同时客户端软件提交的事务请求也需要尽快响应。这些请求数量大,同时又大多是耗时不长的功能。 6 | * 在现代的 SoC 大多是多核异构解决方案,为并发设计提供了可能。同时,GPU 和 HWComposer 硬件的操作特点,最好是批量和同步完成。 7 | 8 | Active Object 模式属于并发设计模式(Design Patterns for Concurrency),对应到并发架构模式(Architectural Patterns for Concurrency),就是半同步/半异步(Half-sync / Half-async)模式。Active Object 模式和 Half-sync / Half-async 模式,它们两个是对同一件事情不同视角的描述。半同步/半异步(Half-sync / Half-async)模式是一个分层架构。它包含三个层次:异步任务层、同步任务层和队列层。半同步/半异步(Half-sync / Half-async)模式的核心思想是如何将系统中的任务进行恰当的分解,使各个子任务落入合适的层次中。在 SurfaceFlinger 里,Surface 发送来的请求,数量大,又是轻量级,所以需要异步处理,以提高响应度。对合成操作,要求一致性高,又是重量级,所以在同步任务里完成。 9 | 10 | 再回到设计模式。Android 图形系统最根本的就是 Producer-Consumer 模式。而 Active Object 模式就是 Producer-Consumer 模式的一种变种。同样的, Thread Pool 模式也是 Producer-Consumer 模式的一种变种。在 SurfaceFlinger 程序里同样应用了 Thread Pool 设计模式。 11 | 12 | | No. | Thread | Count | 13 | |:---:|----------------------|------:| 14 | | 1 | Binder thread | 4 | 15 | | 2 | HW VSYNC Thread | 1 | 16 | | 3 | DispSyncThread | 1 | 17 | | 4 | EventControlThread | 1 | 18 | | 5 | EventThread | 2 | 19 | | 6 | Main thread | 1 | 20 | | 7 | IdleTimer | 1 | 21 | | 8 | RegionSamplingThread | 1 | 22 | | | | | 23 | | | Total | 12 | 24 | 25 | 由此可见,SurfaceFlinger 里面的角色就是采用 Thread Pool 模式来实现。跨进程交互的 Binder 接口被限定为 4 个线程。此外的其它角色都对应一个线程,每个线程从自己的任务队列里顺序处理任务请求。这样既提高了业务吞吐量又提高了任务的响应能力。 26 | 27 | 所有这一切,都是为了利用多核异构方案,增加并行的可能。例如: 28 | * 不直接涉及 SurfaceFlinger 类中方法的事务请求,例如生产端循环的 dequeueBuffer / queueBuffer 操作,就是在 Binder thread 中随机到达并完成返回。而消费端循环的 acquireBuffer / releaseBuffer 操作,则是在 Main thread 中定时完成。 29 | * 同样的,直接涉及 SurfaceFlinger 类中方法的事务请求,则是在 Binder thread 中随机到达,在 Main thread 中定时完成。 30 | * 能延后处理的任务就要延后处理,让事务请求尽快返回,尽可能不在 Main thread 中执行与合成无关的操作。例如对 MessageCreateLayer 消息的处理,返回时,并没有为对应的 BufferQueue 申请 GraphicBuffer。只有在需要时,BufferQueue 才会为 Surface-Layer 申请 GraphicBuffer。这时是在 Binder thread 中完成,不会影响 Main thread 中的操作。 31 | * 另外,根据显示是由 VSYNC 信号驱动的特点,协调生产端和消费端的速率,使得两端趋向于同步错位运行。这就是编舞者(Choreographer)框架的目标。 32 | 33 | 从这里也可以看到[[相位偏移量的设置](../general-design/VSYNC.md#相位偏移的设置)]一节中所讨论的 SurfaceFlinger 程序的合成操作与 Application 程序的渲染操作错位运行的合理性: 34 | * N# HW_VSYNC 信号到达,HWComposer 模块底层将 Loop N-1 中合成好的 framebuffer N-1 送到显示设备上。 35 | * HW_VSYNC 信号过了 sfVsyncPhaseOffsetNs 纳秒,SurfaceFlinger 程序收到 VSYNC-sf 消息,开始 Loop N,进行合成操作。 36 | + 从 Loop N-1 看,大多数 Application 程序已经完成了上一帧的渲染操作,在 Binder thread 中开始提交新帧。所以没有多少用户在竞争 GPU。 37 | + 从当前看,HWComposer 模块底层应该已经向底层硬件提交了显示申请,不会多用 CPU。 38 | + 合成分成两个阶段。第一阶段是部分 Layer 采用 GPU 进行合成。这时候 SurfaceFlinger 程序的 Main thread 是最主要的 CPU 和 GPU 的用户。 39 | * HW_VSYNC 信号过了 vsyncPhaseOffsetNs 纳秒,各个 Application 程序收到 VSYNC-app 消息,开始进行渲染操作。 40 | + 因为 vsyncPhaseOffsetNs 不等于 sfVsyncPhaseOffsetNs,错位启动,所以这时候 SurfaceFlinger 程序采用 GPU 进行合成的任务应该完成了部分,Application 程序可以竞争到一些 GPU 资源。 41 | + 接着,SurfaceFlinger 程序的合成任务进入第二阶段,采用 HWComposer 模块合成剩下的 Layer。 42 | + 这时候 GPU 资源主要由 Application 程序使用。而 HWComposer 模块应该完成了显示工作,可以交给 Main thread 用来进行合成工作。 43 | * SurfaceFlinger 程序必须在 N+1# HW_VSYNC 信号到达前完成 framebuffer N 的合成工作。如果工作频率为 60Hz,则它的合成时间为 44 | + `16666667 - sfVsyncPhaseOffsetNs` 纳秒 45 | + 需要让这个值尽可能的大,以便 SurfaceFlinger 程序有更多的时间进行合成。 46 | * 对于 Application 程序程序来说,当前渲染的 frame 要想在 Loop N+1 时能提交合成,如果工作频率为 60Hz,则它的渲染时间为 47 | + `16666667 - (vsyncPhaseOffsetNs - sfVsyncPhaseOffsetNs)` 纳秒 48 | + 需要让这个值尽可能的大,以便 Application 程序有更多的时间进行渲染。 49 | * 但是这两个相位偏移量又不能为"0",否则显示、合成与渲染任务在同一时间爆发,会让系统负荷更糟糕。所以这两个相位偏移量的选择真是煞费苦心。需要选择很多场景做很多实验,然后要通盘考虑才行。 50 | * 所以,在一个 VSYNC 事件中,显示操作、合成操作、渲染操作错位运行,显示设备开始显示帧 N,SurfaceFlinger 开始为帧 N+1 合成窗口,应用处理等待的输入并生成帧 N+2。这是一个负载均衡的、合理的、可长期运转的方案。 51 | 52 | 另外,在 surfaceflinger 程序的实现细节上,还应用了几种设计模式: 53 | * 跨进程接口(Interface)的实现,应用了 Proxy 模式和 Observer 模式。 54 | * 对 VSYNC 信号的处理,应用了命令模式(Command Pattern)。 55 | * 在 Active Object 模式中,为获取异步任务的结果,应用了 Promise 模式。 56 | * 对应 Active Object 模式,一般同时会应用 Monitor Object 模式。在 surfaceflinger 程序里,这个模式并不明显,但也通过 Mutex 类来保护危险区域的代码。保证在多核条件下,在任一时间内,只有唯一的公共的成员方法,被唯一的线程所执行。 57 | * 对于 Thread Pool 模式的结束,应用了 Two-phase Termination 模式。 58 | 59 | 总之,像 surfaceflinger 这样有着复杂需求的大程序里,要根据应用特点,需要同时应用多种设计模式,才能可靠高效地实现需求。 60 | 61 | -------------------------------------------------------------------------------- /document/server-design/module.md: -------------------------------------------------------------------------------- 1 | # SurfaceFlinger 模块划分 2 | * * * 3 | 4 | 因为 surfaceflinger 程序本身的代码很复杂,依赖很多。为便于管理,开发者将其进行了模块划分。子模块以子目录存在,有: 5 | * CompositionEngine 6 | * DisplayHardware 7 | * Effects 8 | * EventLog 9 | * Scheduler 10 | * TimeStats 11 | * layerproto 12 | * sysprop 13 | 14 | 需要重点关注的是 CompositionEngine / DisplayHardware / Scheduler 这 3 个模块。其中 Scheduler 模块已经在前面的[ VSYNC 模块的设计 ](../general-design/VSYNC.md)章节描述过,这里不再重复。 15 | 16 | surfaceflinger 程序所依赖的库,需要重点关注的是: 17 | * renderengine 18 | 19 | 另外,SurfaceFlinger 类极其复杂,参与开发提交代码的人都超过 20 人之多。所以开发者也对其进行了内部模块划分,以便于理解和维护: 20 | * main loop / main thread 21 | * IBinder interface implement 22 | * ISurfaceComposer interface implement 23 | * DeathRecipient interface implement 24 | * RefBase interface implement 25 | * HWC2::ComposerCallback interface / HWComposer::EventHandler interface implement 26 | * Message handling 27 | * Transactions 28 | * Layer management 29 | * Boot animation 30 | * Properties 31 | * EGL 32 | * Display and layer stack management 33 | * H/W composer 34 | * Compositing 35 | * Display management 36 | * VSync 37 | * Display identification 38 | * Debugging & dumpsys 39 | * VrFlinger 40 | * Attributes 41 | * Feature prototyping 42 | * Scheduler 43 | 44 | 下面将对一些重点的模块进行分析。 45 | 46 | # 显示硬件抽象 47 | 48 | 这个模块主要是定义并实现显示硬件(Display Hardware)接口: 49 | * HWComposer - 封装 Hardware Composer 的接口与实现。 50 | * DisplaySurface - 实现在合成引擎中定义的显示后端接口。 51 | * PowerAdvisor - 电源管理顾问。屏幕开关,刷新率变更,需要这个接口。 52 | 53 | HWComposer 关系组合图如下: 54 | ![HWComposer Component Diagram](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/server-design/services_surfaceflinger_DisplayHardware_ComposerHal%20Component%20Diagram.svg) 55 | 56 | 其中的封装层次相当多。从 C++ namespace 划分: 57 | * android::hardware::graphics::composer - HIDL 接口 58 | + IComposer 59 | + IComposerClient 60 | + IComposerCallback 61 | * android::Hwc2 - 调用 HIDL 接口的接口 62 | + Composer 63 | * HWC2 - Hardware Composer V2 的抽象 64 | + Device 65 | + ComposerCallback 66 | * android - SurfaceFlinger 所在的名字空间 67 | + HWComposer 68 | 69 | 显示后端接口的实现,指的是 FramebufferSurface & VirtualDisplaySurface 这两个类。它们即实现了在 framework/gui 中定义的 ConsumerBase 接口,表明它们是 BufferQueue 的消费端,也实现了在合成引擎中定义的显示后端接口 DisplaySurface,表明了它们是图形流水线第二阶段的 BufferQueue 的消费端。这些内容已经在前面的[ 两阶段流水线的设计 ](../general-design/2-stage.md)的章节已讨论,这里不再重复。 70 | 71 | PowerAdvisor 关系组合图如下,最终调用了 HIDL 接口: 72 | ![PowerAdvisor 接口的关系组合图](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/server-design/services_surfaceflinger_DisplayHardware_PowerAdvisor%20Class%20Diagram.svg) 73 | 74 | # 合成引擎 75 | 76 | 在合成引擎里定义并实现很多接口: 77 | * CompositionEngine 78 | * Display 79 | * DisplaySurface 80 | * LayerFE 81 | * Layer 82 | * Output 83 | * OutputLayer 84 | * RenderSurface 85 | 86 | 如果以 CompositionEngine 为中心看关系组合图: 87 | ![CompositionEngine Component Diagram](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/server-design/services_surfaceflinger_CompositionEngine_include_compositionengine_CompositionEngine%20Component%20Diagram.svg) 88 | 89 | 在图中可以看到: 90 | * 合成引擎 CompositionEngine 最终使用硬件合成器 HWComposer 与渲染引擎 RenderEngine 这两种方式完成合成操作。 91 | * 显示设备 DisplayDevice 管理着 Display 与 Layer,并将两者联系在一起。 92 | * Layer 是图形流水线第一阶段的消费端。RenderSurface 是第二阶段的生产端,由 Display 创建。DisplaySurface 是第二阶段的消费端。 93 | * RenderSurface-DisplaySurface 流水线围绕合成引擎 CompositionEngine 设计。 94 | 95 | 上图的关系太杂乱。如果我们以 Layer 的概念为中心重新整理关系组合图,则有下图: 96 | ![Layer Component Diagram](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/server-design/services_surfaceflinger_Layer%20Component%20Diagram.svg) 97 | 98 | 前面说过,Surface-Layer 是图形流水线的第一阶段。但是 Layer 的概念很通用,在很多地方也会使用到。于是设计者对 Layer 的概念做了细分。从 C++ namespace 划分: 99 | * android::compositionengine::LayerFE - Layer 前端。属于合成引擎的概念。定义 2 个方法,功能如其名: 100 | + latchCompositionState 101 | + onLayerDisplayed 102 | * android::Layer - 就是 Surface-Layer 流水线中的 Layer,SurfaceFlinger 所使用的 Layer。继承自 LayerFE,表明对于第二阶段的流水线,android::Layer 是前端。它的主要实现有: 103 | + BufferLayer 104 | - BufferQueueLayer 105 | - BufferStateLayer 106 | + ColorLayer 107 | + ContainerLayer 108 | * android::compositionengine::OutputLayer - 输出设备相关的 Layer,包含与输出设备相关的合成状态。属于合成引擎的概念。OutputLayer 将下面 3 种 Layer 绑定在一起: 109 | + android::Layer 110 | + android::compositionengine::Layer 111 | + HWC2::Layer 112 | * android::compositionengine::Layer - 输出设备无关的 Layer。属于合成引擎的概念。主要是对于前端 Layer,也就是 android::Layer,包含与输出设备无关的合成状态。 113 | * HWC2::Layer - HWComposer 所使用的 Layer。属于硬件底层的概念。 114 | 115 | 于是就有了下面的一些概念的相互关系: 116 | * OutputLayer 的所有者是 Output,并且 OutputLayer 由 Output 提供。 117 | * Display 是一种 Output,对外提供 RenderSurface。 118 | * 最终是 DisplayDevice 创建了 Display。 119 | * android::Layer 代表着应用程序生成的帧,由 WindowManager 管理生成 z-order 关系。RenderSurface 获取的 Buffer 插入到 z-order 的最底层。这样经过 CompositionEngine 的合成操作,该 Buffer 就承载了所有可见帧的合成结果。 120 | 121 | # 渲染引擎 122 | 123 | 渲染引擎代码位于 frameworks/native/libs/renderengine/ 目录。关系组合图如下: 124 | 125 | ![RenderEngine Component Diagram](https://raw.github.com/shuyong/Design-Of-Android-10.0-Graphic-System/master/document/server-design/renderengine_include_renderengine_RenderEngine%20Component%20Diagram.svg) 126 | 127 | 渲染引擎由 OpenGLES 来实现。Surface-Layer 所拥有的 Buffer,就绑定为 GL Texture,由 GPU 做渲染。这种实现具有更大的灵活性。在 C/S 两端都会应用到。 128 | 129 | # 内部模块 130 | 131 | 本文关注的 SurfaceFlinger 类的内部模块如下: 132 | * main loop / main thread - 合成和显示功能所在的线程。其它模块大都运行在其它线程,都是围绕这个主功能进行配置和控制。 133 | * ISurfaceComposer interface - 在[ 基于 Client / Server 模型的对称设计 ](../general-design/symmetrical-design.md#基于-Client--Server-模型的对称设计)章节中已讨论。不再重复。 134 | * HWC2::ComposerCallback interface - VSYNC Path。在[ VSYNC 信号的生成与传播 ](../general-design/VSYNC.md#VSYNC-信号的生成与传播)章节中已讨论。不再重复。 135 | * Message handling - 主线程接收消息并进行处理的代码。以及其它线程向主线程发送消息的工具类:LambdaMessage & MessageQueue。发送消息和处理消息的流程在后面的章节讨论。 136 | + 异常处理 - 如果合成速度太慢,在一次 VSYNC 周期中不能完成合成动作,会造成 VSYNC 信号积压。在下一次事件处理循环中,MessageQueue::eventReceiver() 方法会取出事件队列中所有 VSYNC 信号,但只给 SurfaceFlinger 发送一次 VSYNC 信号,其余都抛弃。这样就避免了多余的合成操作。 137 | * Compositing - 在[ 两阶段流水线的设计 ](../general-design/2-stage.md)的章节中已讨论。不再重复。 138 | * VSync - 获取和设置 VSYNC 周期。属于 VSYNC Path 的一部分。 139 | * Scheduler - 在[ VSYNC 模块的设计 ](../general-design/VSYNC.md)章节中已讨论。不再重复。 140 | 141 | -------------------------------------------------------------------------------- /document/server-design/server-design.md: -------------------------------------------------------------------------------- 1 | # Android 的图形系统服务端的设计 2 | * * * 3 | 4 | 如果有谁研读 SurfaceFlinger 程序的代码,不被里面众多庞杂臃肿的类,还有类与类之间迷宫一样相互调用的关系所迷惑,那他就没有认真读代码。 5 | 6 | 要想分析 SurfaceFlinger 程序的设计,从进程/线程间的消息流动,以及基于模式(pattern)的设计这两方面入手,也许能找到一条出路。 7 | 8 | # [SurfaceFlinger 模块划分](module.md) 9 | 10 | # [SurfaceFlinger 中的消息与传递路径](message.md) 11 | 12 | # [基于 Active Object 模式进行设计](active-object.md) 13 | 14 | # [架构设计与组合模式](component-pattern.md) 15 | 16 | # 小结 17 | 18 | 分析 Android 图形系统,最大的收获就是在软件层次与设计模式方面: 19 | * 为了最大保证兼容性和灵活性,纵向采用访问者模式(Visitor Pattern)实现 HIDL。间接也保证了 Android 系统的健壮性。 20 | * Android 图形系统本质上就是 Producer-Consumer 模式。为了保证性能,横向采用活动对象模式(Active Object Pattern)。这是 Producer-Consumer 模式的一个变种。可以利用多核异构的特点提高并发性。 21 | * 最终 Android 图形系统就在性能、兼容性、健壮性等方面寻找平衡点。于是程序就复杂无比,层次多,模式复杂,失去了易读性。 22 | 23 | # 参考文件 24 | 1. [SurfaceFlinger and Hardware Composer](https://source.android.com/devices/graphics/arch-sf-hwc) 25 | 1. [SurfaceTexture](https://source.android.com/devices/graphics/arch-st) 26 | 1. [Android graphic system (SurfaceFlinger) : Design Pattern's perspective](https://www.slideshare.net/BinChen3/android-graphic-system-surface-flinger-patternsperspective-external-version) 27 | 1. [Java多线程编程实战指南(设计模式篇)](http://www.broadview.com.cn/book/506) 28 | 29 | -------------------------------------------------------------------------------- /notes/4+1.md: -------------------------------------------------------------------------------- 1 | # 软件架构的 4+1 视角模型简介 2 | * * * 3 | 4 | # 概念介绍 5 | 6 |   软件架构是针对软件高层结构的实现和设计,它是组织一定数量的架构元素以一定形式来满足系统功能和性能的主要需求,如可靠性、可扩展性、可移植性和可用性。 7 | 8 |   ** 软件架构 = {元素, 形式, 原理/约束} ** 9 | 10 |   软件架构是抽象处理的分解和组合的风格和美学。我们使用一个多视图的模型来描述软件体系架构。为了解决大型的和有挑战性的架构,我们提出的模型是由五个主要的视角: 11 | 1. 逻辑视图 12 | 2. 处理视图 13 | 3. 开发视图 14 | 4. 物理视图 15 | 5. 场景 16 | 17 | 对于这四种视图每个视图我们都使用元素组件 component, 容器 container, 和连接器 connector 来描述他们。 18 | 19 | # 逻辑视图 20 | 21 |   使用面向对象的分解方法,逻辑架构主要支持功能需求,也就是系统应该提供怎样的服务给用户。系统分解为一组关键抽象,如问题域的对象或对象类的形式。利用封装和继承的抽象原则。分解不仅是为了功能分析,也为了识别常见的服务机制和跨系统的设计元素。我们可以使用UML类图和类模板代表逻辑架构的方法。 22 | 23 | # 处理视图 24 | 25 |   处理视图是考虑一些非功能性的需求,例如性能和可用性可扩展性 Scalable。它可以解决并发性和分布系统的完整性与容错性等问题,主要指导如何从逻辑视图的抽象融入处理架构之中,比如哪个线程来控制对象的实际执行。 26 | 27 |   延迟和吞吐量是衡量处理架构的一对矛盾指标,我们希望获得低延迟和高吞吐量的处理架构。所谓低延迟,也就是用户能感受到的系统响应时间,比如一个网页在几秒内打开,越短表示延迟越低,而吞吐量表示同时有多少用户能够享受到这种低延迟,如果并发用户量很大时,用户感觉网页的打开速度很慢,这意味着处理架构的吞吐量有待提高。 28 | 29 |   处理视图可以描述若干个不同的抽象层次,每个层次解决不同的问题。在最高的层次上,处理视图可以被视为一组独立执行通信程序(称为"流程")的逻辑网络,分布在一组硬件资源上,通过局域网或广域网连接。同时可能存在多个逻辑网络,共享相同的物理资源。例如,可以使用独立的逻辑网络中。 30 | 31 |   处理是一种分组任务,形成一个个可执行的单元。处理视图在战术上有控制、启动、恢复、重新配置和关闭)等。处理可以复制增加与分布负载,改善可用性。软件划分为一组独立的任务。一个任务可以是一个单独的线程控制,可以单独安排在一个处理节点上。 32 | 33 |   任务分为主要任务和次要任务,主要任务是处理架构元素,能够直接被关注定位,次要任何为了实现细节导入的附加任务,比如循环活动、缓冲、或计时等等,他们都可以轻量的线程来执行。 34 | 35 |   主要任务之间通讯是通过一系列内部任务通讯机制:同步或异步,基于消息的通讯服务,远程调用,事件广播等。次要任务主要是通过约定的共享内存通讯。 36 | 37 | # 开发视图 38 | 39 |   开发架构关注实际的软件开发环境中的软件模块组织。软件打包可以小程序库或子系统等形式,子系统是由一个或少量的开发人员开发的系统。子系统有良好的组织层次结构,每一层都提供了一个狭窄的和良好定义的接口层。开发系统是由模块和子系统的架构组成的,表达了"出口"和"进口"的关系。 40 | 41 | # 物理视图 42 | 43 |   物理架构主要考虑系统的非功能性需求,如可用性、可靠性(容错)、性能(吞吐量)和可伸缩性。软件在计算机网络或处理节点上执行,需要确定的各种元素:网络、处理、任务和对象都需要被映射到各个节点。我们预计需要使用几个不同的物理配置:一些在开发和测试阶段,其他在部署阶段配置,系统的各种网站或为不同的客户。软件的映射节点,因此需要高度灵活以及对源代码本身产生最小的影响的运行平台,云计算和 Docker 之类的 Pass 能够满足这样的物理架构。 44 | 45 | # 场景 46 |   四个视图中的元素通过场景能够一起无缝工作,场景对应着用例,它实现上对应相应的脚本(流程),也就是对象之间的序列交互,使用对象场景图和对象交互图来表示。 47 | 48 |   场景作为 4+1 中的 +1 视图,承担着在架构设计时驱动发现架构元素的任务,同时也是架构设计完成后进行验证和假设认证的理论测试。 49 | 50 | -------------------------------------------------------------------------------- /notes/C4-drawio.md: -------------------------------------------------------------------------------- 1 | # 使用 draw.io 绘制 C4 图 2 | * * * 3 | 4 | 使用 https://github.com/kaminzo/c4-draw.io 提供的方法。 5 | 6 | * 打开新文件: 7 | ``` 8 | https://app.diagrams.net/#Uhttps://github.com/kaminzo/c4-draw.io/raw/master/c4.drawio.png 9 | ``` 10 | 11 | * 编辑后另存为其它文件。 12 | 13 | * Loading the shapes library from XML 14 | + File -> Open library from -> GitHub and select the XML file : 15 | + c4.drawio.library.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /notes/C4-model.md: -------------------------------------------------------------------------------- 1 | # 用 C4 模型可视化软件架构 2 | * * * 3 | 4 | # 基本概念 5 | 6 | C4 模型由一系列分层的软件架构图组成,这些架构图用于描述上下文、容器、组件和代码。C4 图的层次结构提供了不同的抽象级别,每种抽象级别都与不同的受众有关。 7 | 8 | C4 代表上下文(Context)、容器(Container)、组件(Component)和代码(Code)—— 一系列分层的图表,可以用这些图表来描述不同缩放级别的软件架构,每种图表都适用于不同的受众。 9 | 10 | C4 模型是一种在不同抽象层次上交流软件架构的简单方法,可以向不同的受众讲述不同的故事。这也是向软件开发团队介绍(通常是重新引入)严谨和轻量级建模的一种方式。 11 | 12 | 要为你的代码创建可视化地图,首先需要一组通用的抽象来创建一种无处不在的语言,用来描述软件系统的静态结构。C4 模型使用容器(应用程序、数据存储、微服务等)、组件和代码来描述一个软件系统的静态结构。它还考虑到使用软件系统的人。 13 | 14 | * 第 1 层:系统上下文。第 1 层是系统上下文图,它显示了你正在构建的软件系统,以及系统与用户及其他软件系统之间的关系。 15 | * 第 2 层:容器。第 2 层是一个容器图,将软件系统放大,显示组成该软件系统的容器(应用程序、数据存储、微服务等)。技术决策也是该图的关键部分。 16 | * 第 3 层:组件。第 3 层是组件图,将单个容器放大,以显示其中的组件。这些组件映射到代码库中的真实抽象(例如一组代码)。 17 | * 第 4 层:代码。第 4 层是以 UML 类图表示的代码,将单个组件放大,以显示该组件的实现方式。 18 | 19 | # 分层用途 20 | 21 | 1. 系统上下文(System Context)用途 22 | 23 | 这样一个简单的图,可以告诉我们,要构建的系统是什么;它的用户是谁,谁会用它,它要如何融入已有的IT环境。这个图的受众可以是开发团队的内部人员、外部的技术或非技术人员。即: 24 | a. 构建的系统是什么 25 | b. 谁会用它 26 | c. 如何融入已有的IT环境 27 | 28 | 2. 系统容器(System Container)用途 29 | 30 | 这个图的受众可以是团队内部或外部的开发人员,也可以是运维人员。用途可以罗列为: 31 | a. 展现了软件系统的整体形态 32 | b. 体现了高层次的技术决策 33 | c. 系统中的职责是如何分布的,容器间的是如何交互的 34 | d. 告诉开发者在哪里写代码 35 | 36 | 3. 组件(Component)用途 37 | 38 | 这个图主要是给内部开发人员看的,怎么去做代码的组织和构建。其用途有: 39 | a. 描述了系统由哪些组件/服务组成 40 | b. 厘清了组件之间的关系和依赖 41 | c. 为软件开发如何分解交付提供了框架 42 | 43 | “组件”一词在软件开发行业中是一个超负荷的术语,但在这里,组件是封装在定义良好的接口后面的一组相关功能。如果使用的是 Java 或 C# 之类的语言,那么考虑组件最简单的方式就是它是接口后面的实现类的集合。这些组件的打包方式(例如,每个 JAR 文件、DLL、共享库等一个组件与多个组件的打包方式)是一个单独的、正交的重要事情。 44 | 45 | 这里需要注意的一点是,容器中的所有组件通常在相同的进程空间中执行。在 C4 模型中,组件不是可单独部署的单元。 46 | 47 | 4. 代码(Code)用途 48 | 49 | 以 UML 类图描述代码,指导开发人员进行实现。 50 | 51 | # 进一步的解释 52 | 53 | C4 分别是上下文(Context)、容器(Container)、组件(Component)和代码(Code)层次的图表,可以用这些图表来描述不同级别的软件架构,每种图表都有着不同的受众。这个就有点像世界地图、国家地图、省地图、市区街道地图,逐层递进,展示里面的内容,而每种地图的关注点也不同。 54 | 55 | ## 语境图/上下文 (Context) 56 | 57 | 语境图(有些参考文章里面翻译的是上下文),它展示的是系统大局景观的广角视图,主要包括关键的系统依赖和参与者,关注的重点是人和系统。 58 | 59 | 在画语境图时,要明确的标出: 60 | * 我们构建的软件系统是什么? 61 | * 谁用这个系统? 62 | * 如何融入已有的IT环境? 63 | 64 | ## 容器图(Container) 65 | 66 | 首先明确容器的概念,容器指的是组成软件系统的逻辑上的可执行文件或者过程。容器之间的通信一般是进程间的通信。 67 | 68 | 所以画一个容器的时候要包含: 69 | * 名称:容器的逻辑名称(如“面向互联网的Web服务器”、“数据库”等)。 70 | * 技术:容器的技术选择(如ApacheTomcat7等)。 71 | * 职责:容器职责的高层次声明或清单。 72 | 73 | 之后就是画各个容器之间的通信: 74 | * 容器之间交互的目的(如“读/写数据”、“发送报告“等); 75 | * 容器之间的通信方法(如Web服务、REST、Java远程方法调用、Java消息服务); 76 | * 容器之间的通信方式(如同步、异步、批量等); 77 | * 容器之间的协议和端口号(如HTTP、HTTPS、SOAP/HTTP、SMTP、FTP等)。 78 | 79 | ## 组件图(Component) 80 | 81 | 组件图就是将单个容器放大,它可以让你清晰的看到容器的关键逻辑组件、组件之间的层级关系和依赖。所以组件图要标明: 82 | * 名称:组件的名称 83 | * 技术:对组件的技术选择 84 | * 职责:对组件职责的高层次的声明 85 | 86 | ## 类图/代码(Code) 87 | 88 | 类图是一个可选的细节层次。如果想解释某个组件被怎样实现,可以画更细层次的 UML 类图。 89 | 90 | ## 补充图 91 | 92 | 一旦对静态结构有了很好的了解,就可以补充 C4 图以显示其它方面。 93 | 94 | ### 系统格局图 95 | 96 | C4 模型提供单个软件系统的静态视图,但是在现实世界中,软件系统永远不会孤立存在。因此,尤其是在用户负责一组软件系统时,了解所有这些软件系统如何在企业范围内融合在一起通常很有用。为此,只需添加另一个 C4 图“顶部”的图,以从 IT 角度显示系统格局。像系统上下文图一样,该图可以显示组织边界,内部/外部用户和内部/外部系统。 97 | 98 | 本质上,这是企业级软件系统的高级映射,其中每个感兴趣的软件系统都有 C4 向下钻取。从实践的角度来看,系统格局图实际上只是系统上下文图,而没有特别关注特定的软件系统。 99 | 100 | * 适用范围:企业。 101 | * 主要元素:范围内与企业相关的人员和软件系统。 102 | * 目标受众:软件开发团队内部和外部的技术人员和非技术人员。 103 | 104 | ### 动态图 105 | 106 | 当用户想显示静态模型中的元素如何在运行时进行协作以实现用户故事,用例,功能等时,动态图可能很有用。该动态图基于UML通讯图 (以前称为“ UML”协作图”)。它类似于UML序列图, 但是它允许带有编号的交互作用的图元素的自由形式排列以指示顺序。 107 | 108 | * 适用范围:企业,软件系统或容器。 109 | * 主要和辅助元素:取决于图的范围;企业(请参阅系统架构图),软件系统(请参阅系统上下文或容器图),容器(请参阅组件图)。 110 | * 目标受众:软件开发团队内部和外部的技术人员和非技术人员。 111 | 112 | ### 部署图 113 | 114 | 部署图使用户能够说明如何将静态模型中的容器映射到基础结构。此部署图基于UML部署图,尽管略微简化以显示容器和部署节点之间的映射。部署节点类似于物理基础架构(例如物理服务器或设备),虚拟化基础架构(例如 IaaS,PaaS,虚拟机),容器化基础架构(例如 Docker 容器),执行环境(例如数据库服务器,Java EE)。 Web /应用程序服务器,Microsoft IIS)等。部署节点可以嵌套。 115 | 116 | 用户可能还希望包括基础结构节点,例如 DNS 服务,负载平衡器,防火墙等。 117 | 118 | * 适用范围:单个软件系统。 119 | * 主要元素:范围内软件系统内的部署节点和容器。 120 | * 支持元素:在软件系统部署中使用的基础结构节点。 121 | * 目标受众:软件开发团队内部和外部的技术人员;包括软件架构师,开发人员,基础架构设计师和运营/支持人员。 122 | 123 | # 小结 124 | 125 | C4 代表上下文(Context)、容器(Container)、组件(Component)和代码(Code): 126 | 127 | 1. 上下文:可以给非技术人员看,画清楚构建什么样的系统、谁使用它,以及如何融入自己已有的东西; 128 | 2. 容器:一般给开发人员看,画清楚软件整体形态、关键决策、职责划分,以及在哪里写代码; 129 | 3. 组件:一般给内部开发人员看,画清楚系统组成部件、部件之间的层级关系和依赖、细化交付的内容; 130 | 4. 代码:同样一般是给内部开发人员看,有时序图、类图、逻辑视图、流程图等等,进入代码细节。 131 | 132 | -------------------------------------------------------------------------------- /notes/README.md: -------------------------------------------------------------------------------- 1 | # SA : Software Architecture 2 | 3 | Software Architecture is how the defining components of a software system are organized and assembled. How the communicate with each other. And the constraints the whole system is ruled by. 4 | 5 | Software Architecture : 6 | 1. Architectural Patterns : How the defining components of a software system are organized and assembled. 7 | 2. Messaging & APIs : How they communicate with each other. 8 | 3. Quality Attributes(-ilities) : The constraints the whole system is ruled by. 9 | 10 | What is the difference between the architecture (architectural pattern) and the design pattern? 11 | 12 | Architectural Pattern 13 | 1. High-level, universal scope. 14 | 2. How components are organized and assembled. 15 | 16 | Design Pattern 17 | 1. Lower-level scope. 18 | 2. How components are built. 19 | 20 | 21 | -------------------------------------------------------------------------------- /notes/SA.md: -------------------------------------------------------------------------------- 1 | # 软件架构(Software Architecture)简介 2 | * * * 3 | 4 | # 架构图的基本概念 5 | 6 | 1. 架构:架构就是对系统中的实体以及实体之间的关系所进行的抽象描述,是一系列的决策。架构是结构和愿景。系统架构是概念的体现,是对物/信息的功能与形式元素之间的对应情况所做的分配,是对元素之间的关系以及元素同周边环境之间的关系所做的定义。 7 | 8 | 2. 架构图:系统架构图是为了抽象的表示软件系统的整体轮廓和各个组件之间的相互关系和约束边界,以及软件系统的物理部署和软件系统的演进方向的整体视图。 9 | 10 | 3. 架构图作用:解决沟通障碍、达成共识、减少歧义。 11 | 12 | # 软件架构的所处阶段 13 | 14 | 软件生命周期的几个阶段: 15 | * 需求分析(Requirement analysis) 16 | * 设计(Design) 17 | * 开发(Development) 18 | * 测试(Testing) 19 | * 验收(Acceptance) 20 | * 部署(Deployment) 21 | * 维护和更新(Maintenance & Update) 22 | 23 | 软件架构设计属于设计(Design)阶段的工作。设计的内容有: 24 | 1. 架构模式(Architectural patterns) 25 | 2. 消息机制(Messaging mechanisms) 26 | 3. 品质属性(Quality Attributes) 27 | 4. API & Interface 28 | 29 | 而在开发(Development)阶段的前期会涉及这些工作: 30 | 1. 编码范例(Coding paradigms) 31 | 2. 设计模式(Design patterns) 32 | 3. 工具(Tooling) 33 | 4. 自动化(Automation) 34 | 35 | 因此,设计输出是开发阶段的输入。架构是开发阶段的输入。 36 | 37 | # 架构模式与设计模式的对比 38 | 39 | 软件架构是如何组织和组装软件系统的定义组件。他们是如何相互沟通的。以及整个系统所受的约束。因此软件架构设计的主要工作有: 40 | 41 | 1. 架构模式:软件系统的定义组件是如何组织和组装的。 42 | 2. 消息和API:它们如何相互通信。 43 | 3. 品质属性:整个系统所受的约束。 44 | 45 | 架构模式(Architectural patterns)是系统的总体结构。架构模式定义了组件的粒度。粒度就是组件的大小。了解架构模式将有助于我们在开发阶段做出正确的决策。而技术上的重要决策由设计模式承担。 46 | 47 | 架构(架构模式)和设计模式之间的区别是什么? 48 | * 架构模式 49 | 1. 高层次、通用范围。 50 | 2. 如何组织和组装部件。 51 | * 设计模式 52 | 1. 低层次范围。 53 | 2. 如何构建组件。 54 | 55 | # 为什么要进行软件架构设计 56 | 57 | 软件架构设计是为了: 58 | * 构建软件架构的目标是创建一个系统,以最简单的方式、最有效的方式解决复杂的问题。 59 | * 设计软件架构是指安排系统的组件,使其最适合系统所需的质量属性。 60 | 61 | 软件架构设计关注的是品质属性(Quality Attributes): 62 | * 性能(Performance) - 在旋转的“加载”图标消失之前,用户需要等待多长时间? 63 | * 可用性(Availability) - 系统运行的时间百分比是多少? 64 | * 易用性(Usability) - 用户能否轻松了解系统的界面? 65 | * 可修改性(Modifiability) - 如果开发人员希望向系统添加功能,那么这容易吗? 66 | * 互操作性(Interoperability) - 系统是否与其他系统配合良好? 67 | * 保护措施(Security) - 系统周围是否有安全堡垒? 68 | * 可移植性(Portability) - 系统能否在多种不同的平台上运行(即Windows、Mac和Linux)? 69 | * 可扩展性(Scalability) - 如果快速地划分用户群,系统能否轻松扩展以满足新流量? 70 | * 可部署性(Deployability) - 将新功能投入生产是否容易? 71 | * 安全性(Safety) - 如果软件控制物理事物,它会对真实的人造成危害吗? 72 | 73 | 你不可能拥有一切,将品质属性与你的系统相匹配。我们更多地关注: 74 | * Performance 75 | * Availability 76 | * Usability 77 | * Security 78 | 79 | 那重点是什么呢? 80 | 1. 架构支持质量属性。 81 | 2. 架构支持利益相关者之间的沟通。 82 | 3. 架构侧重于组装,而不是组件的创建。 83 | 4. 架构限制了设计选择,使其它领域的创造力得以发挥。 84 | 85 | 什么是品质(Quality),什么是功能(Functionality)? 86 | * 直觉上 87 | + 功能是产品所能做的事情。 88 | + 品质就是它做得有多好。 89 | * 最重要的品质是: 90 | + 可用性(Availability) 91 | + 互操作性(Interoperability) 92 | + 可修改性(Modifiability) 93 | + 性能(Performance) 94 | + 保护措施(Security) 95 | + 可测试性(Testability) 96 | + 易用性(Usability) 97 | * 功能性是指系统完成预期工作的能力。 98 | * 功能性与架构有着奇特的的关系: 99 | + 功能不决定架构;给定一组必需的功能,可以创建多种架构以满足这些功能。 100 | + 功能和品质属性是正交的。 101 | 102 | 品质属性注意事项: 103 | * 如果功能要求为“当用户按下绿色按钮时,将显示选项对话框”: 104 | + 性能QA注释可能描述对话框出现的速度; 105 | + 可用性QA注释可能描述此功能失效的频率以及修复的速度; 106 | + 易用性QA注释可能会描述学习此功能有多容易。 107 | * 先前关于QA的讨论存在三个问题: 108 | + 为属性提供的定义不可测试。说一个系统是“可修改的”是毫无意义的。 109 | + 无休止的时间浪费在争论一个问题属于哪一种品质上。 110 | + 每个属性团体都开发了自己的词汇表。 111 | * 前两个问题(不稳定的定义和重叠关注点)的解决方案是使用品质属性场景作为描述品质属性的手段。 112 | * 第三个问题(专业词汇表)的解决方案是对每个QA进行讨论,集中讨论其潜在的关注点,以说明属性团体的基本概念。 113 | 114 | 品质和功能性的正式定义(来自ISO 9126) 115 | * 品质 —— “当在规定条件下使用时,产品满足规定和暗示需求的程度。” 116 | * 功能性 —— “当软件在特定条件下使用时,软件产品提供满足规定和隐含需求的功能的能力。” 117 | 118 | # 常见架构模式 119 | 120 | 常见架构模式有: 121 | 1. Level 1 : Monolithic , Service-based , Distributed 122 | 2. Level 2 : Layered , Microservices , Event-Driven 123 | 124 | 125 | -------------------------------------------------------------------------------- /notes/c4.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/notes/c4.drawio.png -------------------------------------------------------------------------------- /ref/3tier-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/3tier-architecture.png -------------------------------------------------------------------------------- /ref/Introduction-to-Software-Architecture.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/Introduction-to-Software-Architecture.pdf -------------------------------------------------------------------------------- /ref/README.md: -------------------------------------------------------------------------------- 1 | 1. [Introduction to Software Architecture](https://www.codeproject.com/Articles/1064240/Introduction-to-Software-Architecture) 2 | 1. [Understanding Application Architectures](https://www.codeproject.com/Articles/1120421/Understanding-Application-Architectures) 3 | 1. [How to "think" (and design) like a Software Architect](https://www.youtube.com/watch?v=mCM6QVHD08c) 4 | 5 | -------------------------------------------------------------------------------- /ref/SoftwareArchitectLecture.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/SoftwareArchitectLecture.pdf -------------------------------------------------------------------------------- /ref/Understanding-Application-Architectures.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/Understanding-Application-Architectures.pdf -------------------------------------------------------------------------------- /ref/client-server-model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/client-server-model.png -------------------------------------------------------------------------------- /ref/component-based-software-engineering-example-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/component-based-software-engineering-example-1.png -------------------------------------------------------------------------------- /ref/domain-drivel-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/domain-drivel-design.png -------------------------------------------------------------------------------- /ref/layered-architecture-300x217.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/layered-architecture-300x217.png -------------------------------------------------------------------------------- /ref/message-bus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/message-bus.gif -------------------------------------------------------------------------------- /ref/message-bus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/message-bus.png -------------------------------------------------------------------------------- /ref/object-oriented-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/object-oriented-architecture.png -------------------------------------------------------------------------------- /ref/onion-application-architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/onion-application-architecture.jpg -------------------------------------------------------------------------------- /ref/soa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/soa.png -------------------------------------------------------------------------------- /ref/software-architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuyong/Design-Of-Android-10.0-Graphic-System/a52cf05e489f88f7314764aa5614f496aa92c4c1/ref/software-architecture.jpg --------------------------------------------------------------------------------