{"id":695,"date":"2013-08-26T00:56:42","date_gmt":"2013-08-25T16:56:42","guid":{"rendered":"http:\/\/guoh.ai\/lifelog\/?p=695"},"modified":"2013-10-30T09:10:49","modified_gmt":"2013-10-30T01:10:49","slug":"skeleton-of-surfaceflinger","status":"publish","type":"post","link":"https:\/\/guoh.ai\/lifelog\/2013\/08\/skeleton-of-surfaceflinger\/","title":{"rendered":"SurfaceFlinger\u6e90\u7801\u5206\u6790"},"content":{"rendered":"<div class=\"gfmr-markdown-container\"><div class=\"gfmr-markdown-source\" style=\"display: none;\">&lt;p&gt;\u9488\u5bf9Jelly Bean\u7248\u672c\u7684\u4ee3\u7801\u3002&lt;br \/&gt;\nSurfaceFlinger\u662f\u4ec0\u4e48\uff0c\u8fd9\u4e9b\u4ecb\u7ecd\u5927\u5bb6\u53ef\u4ee5\u5728\u7f51\u7edc\u4e0a\u627e\u627e\u770b\uff0c\u8fd9\u91cc\u5c31\u76f4\u63a5\u4e0a\u4ee3\u7801\u3002&lt;\/p&gt;\n&lt;p&gt;\u9996\u5148\u6211\u4eec\u5f97\u4e86\u89e3\u4e00\u79cd\u5e38\u7528\u7684\u7f16\u7a0b\u505a\u6cd5\uff0c\u751f\u4ea7\u8005\/\u6d88\u8d39\u8005\u6a21\u578b\uff0c\u4e5f\u8bb8\u90fd\u4f1a\u89c9\u5f97\u5f88\u7b80\u5355\uff0c\u4f46\u662f\u8fd9\u91cc\u5c31\u7528\u5230\u4e86\u5f88\u591a\u8fd9\u4e9b\u57fa\u672c\u6982\u5ff5\u3002&lt;br \/&gt;\nBufferQueue \u6570\u636e\u90fdqueue\u5230\u8fd9\u91cc\u9762\uff0c\u524d\u63d0\u662f\u5b83\u662f\u5148\u4eceBufferQueue\u53d6\u51fa\u4e00\u4e2a\u7a7a\u7684\u6570\u636e\u5355\u5143\uff0c\u79f0\u4e3a\u4e00\u4e2abuffer\uff0c\u5b9e\u9645\u4e3aGraphicBuffer\u7c7b\u578b\u3002&lt;\/p&gt;\n&lt;p&gt;ConsumerBase \u5b83\u662f\u6d88\u8d39\u8005\u7aef\u4f7f\u7528\u7684\u63a5\u53e3\uff0c\u5b83\u5b9e\u73b0\u4e86BufferQueue::ConsumerListener\u63a5\u53e3\uff0c\u4e5f\u5c31\u662fBufferQueue\u5f53\u4e2d\u6709buffer\u88abqueue\u7684\u65f6\u5019\uff0c\u5b83\u80fd\u88ab\u901a\u77e5\u5230(onFrameAvailable)\u3002\u540c\u7406\u5f53\u751f\u4ea7\u8005disconnect\u4e0eBufferQueue\u7684\u8fde\u63a5\u6216\u8005setBufferCount\u88ab\u8c03\u7528(\u8be5\u65b9\u6cd5\u91ca\u653e\u6389\u6240\u6709buffer\uff0c\u8ba9buffer\u90fd\u5f52BufferQueue\u6240\u6709\uff0c\u5982\u679c\u6709buffer\u5904\u4e8eDEQUEUED\u72b6\u6001\uff0c\u6b64\u65b9\u6cd5\u8fd4\u56de\u9519\u8bef)\uff0c\u5b83\u4e5f\u4f1a\u88ab\u901a\u77e5\u5230(onBuffersReleased)\u3002&lt;\/p&gt;\n&lt;p&gt;BufferItemConsumer\u548cCpuConsumer \u5b83\u4eec\u90fd\u662fConsumerBase\u7684\u5b50\u7c7b\uff0cBufferItemConsumer\u4e00\u6b21\u53ef\u4ee5acquire\u591a\u4e2abuffer\uff0cConsumerBase\u4e00\u6b21\u53ea\u80fd\u4e00\u4e2a\uff0cBufferItemConsumer\u662f\u4fee\u6539\u4e86BufferQueue\u7684mMaxAcquiredBufferCount\u53c2\u6570\uff0cConsumerBase\u4f7f\u7528\u7684\u9ed8\u8ba4\u503c1\u3002CpuBuffer\u53ef\u4ee5\u628abuffer\u9501\u8d77\u6765\u4f9bCPU\u4f7f\u7528\uff0c\u5b83\u4e5f\u662f\u8c03\u7528GRALLOC\u7684\u65b9\u6cd5\u6765\u5b8c\u6210\u8fd9\u4e2a\u529f\u80fd\u7684\u3002&lt;br \/&gt;\nFramebufferSurface ConsumerBase\u7684\u5b50\u7c7b\uff0c\u4f1a\u628a\u6536\u5230\u7684\u6570\u636e\u901a\u8fc7HWComposer\u5f80\u8367\u5e55\u4e0a\u8d34\u3002&lt;br \/&gt;\nSurfaceTexture ConsumerBase\u7684\u5b50\u7c7b\uff0c\u5b83\u53ef\u4ee5\u628aGraphicBuffer\u8f6c\u6362\u6210texture image\uff0c\u7136\u540e\u4ea4\u7ed9OpenGL\u3002&lt;\/p&gt;\n&lt;p&gt;SurfaceTextureLayer\u662f\u4e00\u4e2a\u5b9a\u5236\u5316\u7684BufferQueue\uff0cNATIVE_WINDOW_API_MEDIA\/NATIVE_WINDOW_API_CAMERA\u8fc7\u6765\u7684\u8bf7\u6c42\u4f1a\u628aBufferQueue\u8bbe\u7f6e\u4e3a\u5f02\u6b65\u6a21\u5f0f\u3002&lt;\/p&gt;\n&lt;p&gt;BufferQueue\u5f53\u4e2dbuffer\u7684\u72b6\u6001\uff0c\u8fd9\u4e2a\u5f88\u7b80\u5355\uff0c\u4f46\u662f\u4e5f\u5f88\u91cd\u8981\u3002&lt;\/p&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\/\/ BufferState represents the different states in which a buffer slot\r\n\/\/ can be.\r\nenum BufferState {\r\n    \/\/ FREE indicates that the buffer is not currently being used and\r\n    \/\/ will not be used in the future until it gets dequeued and\r\n    \/\/ subsequently queued by the client.\r\n    \/\/ aka &quot;owned by BufferQueue, ready to be dequeued&quot;\r\n    FREE = 0,\r\n\r\n    \/\/ DEQUEUED indicates that the buffer has been dequeued by the\r\n    \/\/ client, but has not yet been queued or canceled. The buffer is\r\n    \/\/ considered &#039;owned&#039; by the client, and the server should not use\r\n    \/\/ it for anything.\r\n    \/\/\r\n    \/\/ Note that when in synchronous-mode (mSynchronousMode == true),\r\n    \/\/ the buffer that&#039;s currently attached to the texture may be\r\n    \/\/ dequeued by the client.  That means that the current buffer can\r\n    \/\/ be in either the DEQUEUED or QUEUED state.  In asynchronous mode,\r\n    \/\/ however, the current buffer is always in the QUEUED state.\r\n    \/\/ aka &quot;owned by producer, ready to be queued&quot;\r\n    DEQUEUED = 1,\r\n\r\n    \/\/ QUEUED indicates that the buffer has been queued by the client,\r\n    \/\/ and has not since been made available for the client to dequeue.\r\n    \/\/ Attaching the buffer to the texture does NOT transition the\r\n    \/\/ buffer away from the QUEUED state. However, in Synchronous mode\r\n    \/\/ the current buffer may be dequeued by the client under some\r\n    \/\/ circumstances. See the note about the current buffer in the\r\n    \/\/ documentation for DEQUEUED.\r\n    \/\/ aka &quot;owned by BufferQueue, ready to be acquired&quot;\r\n    QUEUED = 2,\r\n\r\n    \/\/ aka &quot;owned by consumer, ready to be released&quot;\r\n    ACQUIRED = 3\r\n};&lt;\/pre&gt;\n&lt;p&gt;BufferQueue\u4e3b\u8981\u65b9\u6cd5&lt;br \/&gt;\ndequeueBuffer\u53d6\u4e00\u4e2abuffer(\u8fd4\u56deslot\uff0c\u8fd9\u4e2abufer\u662f\u4eceState\u4e3aFREE\u7684\u5f53\u4e2d\u53d6\u7684)\u7ed9client\u4f7f\u7528\uff0c\u5fc5\u8981\u65f6\u5019(null\/height\/width\/format\/usage\u4efb\u4f55\u4e00\u70b9\u4e0d\u6ee1\u8db3\u90fd\u4f1a\u89e6\u53d1)\u5b83\u4f1a\u4f7f\u7528GraphicBufferAlloc::createGraphicBuffer()\u53bb\u5206\u914dbuffer&lt;\/p&gt;\n&lt;p&gt;requestBuffer\u6839\u636e\u4e00\u4e2a\u6307\u5b9a\u7684slot\u83b7\u53d6\u5b83\u7684buffer\u7684\u5730\u5740\uff0c\u8fd9\u4e2a\u4e3b\u8981\u7528\u5728\u521a\u521a\u5206\u914dbuffer\u4e4b\u540e(\u6216\u8005\u662f\u610f\u5916\u7684\u53d1\u73b0\u6307\u5b9aslot\u7684buffer\u5730\u5740\u4e3a\u7a7a)\uff0c\u76ee\u524d\u5728SurfaceTextureClient(Surface)\u5f53\u4e2d\u88ab\u4f7f\u7528\u5230&lt;\/p&gt;\n&lt;p&gt;queueBuffer\u901a\u77e5BufferQueue\u538b\u5165\u4e86\u4e00\u4e2a\u88c5\u6ee1\u6570\u636e\u7684buffer\uff0cQueueBufferInput\u662f\u8be5buffer\u7684\u63cf\u8ff0\u6570\u636e\uff0cQueueBufferOutput\u662fBufferQueue\u5f53\u524d\u7684\u72b6\u6001(\u9ed8\u8ba4height\/width\/transformHint\/slot\u7684\u6570\u91cf\uff0c\u8fd9\u4e2aslot\u53ea\u662f\u5f53\u524d\u88ab\u8fd8\u56de\u7ed9BufferQueue)&lt;\/p&gt;\n&lt;p&gt;acquireBuffer\u83b7\u53d6\u4e00\u4e2apending buffer\u7684\u62e5\u6709\u6743\uff0c\u8fd9\u4e2abuffer\u662fmQueue\u5f53\u4e2d\uff0c\u4e5f\u5c31\u662f\u72b6\u6001\u4e3aQUEUED\u7684(\u6709\u6ca1\u6709\u6570\u636e\uff1f)\u3002&lt;\/p&gt;\n&lt;p&gt;releaseBuffer\u653e\u5f03\u6301\u6709\u7684\u6307\u5b9aslot\u7684buffer&lt;\/p&gt;\n&lt;p&gt;freeBuffer\u6216\u8005cancelBuffer\u90fd\u4f1a\u5bfc\u81f4\u8fd9\u4e2abuffer\u5904\u4e8eFREE\u72b6\u6001&lt;\/p&gt;\n&lt;p&gt;ConsumerBase\u7684\u4e3b\u8981\u65b9\u6cd5&lt;br \/&gt;\nacquireBufferLocked\/releaseBufferLocked\/freeBufferLocked\/abandonLocked&lt;\/p&gt;\n&lt;p&gt;\u53e6\u5916\u8fd9\u4e2aprotected\u7684\u6570\u7ec4\u4e5f\u5f88\u91cd\u8981\uff0c\u5b50\u7c7b\u53ef\u4ee5\u76f4\u63a5\u4ece\u5b83\u91cc\u9762\u83b7\u53d6buffer\u7684\u4fe1\u606f\uff0c\u5b83\u5b9e\u9645\u5c31\u76f8\u5f53\u4e8e\u7f13\u5b58\u4e86BufferQueue\u7684\u4e00\u4e9b\u5fc5\u8981\u4fe1\u606f\u3002&lt;\/p&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\/\/ mSlots stores the buffers that have been allocated by the BufferQueue\r\n\/\/ for each buffer slot.  It is initialized to null pointers, and gets\r\n\/\/ filled in with the result of BufferQueue::acquire when the\r\n\/\/ client dequeues a buffer from a\r\n\/\/ slot that has not yet been used. The buffer allocated to a slot will also\r\n\/\/ be replaced if the requested buffer usage or geometry differs from that\r\n\/\/ of the buffer allocated to a slot.\r\nSlot mSlots&#x5B;BufferQueue::NUM_BUFFER_SLOTS];&lt;\/pre&gt;\n&lt;p&gt;SurfaceTextureClient\u662f\u4e00\u4e2aANativeWindow\uff0c\u4e3anative_window_api_*\u548cnative_window_*\u65b9\u6cd5(\u8fd9\u4e9b\u90fd\u5728system\/core\/include\/system\/window.h\u5f53\u4e2d)\u505a\u5177\u4f53\u5b9e\u73b0\uff0c\u53e6\u5916\u5b83\u8fd8\u6301\u6709SurfaceTexture\u3002&lt;\/p&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\/\/ Initialize the ANativeWindow function pointers.\r\nANativeWindow::setSwapInterval  = hook_setSwapInterval;\r\nANativeWindow::dequeueBuffer    = hook_dequeueBuffer;\r\nANativeWindow::cancelBuffer     = hook_cancelBuffer;\r\nANativeWindow::queueBuffer      = hook_queueBuffer;\r\nANativeWindow::query            = hook_query;\r\nANativeWindow::perform          = hook_perform;\r\n\r\nANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;\r\nANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;\r\nANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;\r\nANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;\r\n\r\nconst_cast&lt;int&amp;&gt;(ANativeWindow::minSwapInterval) = 0;\r\nconst_cast&lt;int&amp;&gt;(ANativeWindow::maxSwapInterval) = 1;&lt;\/pre&gt;\n&lt;p&gt;\u4e00\u4e9b\u91cd\u8981\u7684\u547d\u540d\u6539\u52a8&lt;\/p&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\r\n\u65e9\u671f\u7684Jelly Bean\u5f53\u4e2d\uff0c\u6bd4\u5982(4.1\/4.2)                  4.3\r\n================================================================================\r\nSurfaceTextureClient\u548cSurface(\u7ee7\u627f                 \u88ab\u7b80\u5316\u6210\u4e86Surface(ANativeWindow)\r\n\u81eaSurfaceTextureClient)\u5b9e\u9645\u5c31\u662f\u4e00\u4e2a\r\nANativeWindow\r\n\r\n================================================================================\r\nISurfaceTexture                                   IGraphicBufferProducer\uff0c\r\n                                                  Binder IPC\u63a5\u53e3\uff0c\u7528\u6765\u5728\u4e0d\u540c\u7ec4\u4ef6\u4e4b\u95f4\r\n                                                  \u4f20\u8f93\u6570\u636e\u4f7f\u7528(\u8de8\u8fdb\u7a0b\u7684)\uff0cBufferQueue\r\n                                                  \u5b9e\u73b0\u4e86BnGraphicBufferProducer\r\n\r\n================================================================================\r\nSurfaceTexture(ConsumerBase)                      GLConsumer(ConsumerBase)\u5b83\u53d6\r\n                                                  BufferQueue\u91cc\u9762\u7684\u6570\u636e\uff0c\u7136\u540e\u4f5c\u4e3a\u4e00\u4e2a\r\n                                                  texture\u63d0\u4f9b\u7ed9OpenGL\u4f7f\u7528\r\n                                                  \r\n&lt;\/pre&gt;\n&lt;p&gt;\u4e0a\u9762\u662f\u4f1a\u7528\u5230\u7684\u57fa\u672c\u77e5\u8bc6\uff0c\u4e0b\u9762\u57fa\u672c\u624d\u76f4\u63a5\u548cSurfaceFlinger\u76f8\u5173\u3002&lt;br \/&gt;\n\u7bad\u5934\u7684\u65b9\u5411\u4e3a\u7ee7\u627f\u7684\u65b9\u5411&lt;\/p&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\r\n                             BpSurface       ----&gt;&gt;&gt;&gt;      ISurface\r\n                                                           sp&lt;ISurfaceTexture&gt; ISurface::getSurfaceTexture()\r\n\r\nBSurface       ----&gt;&gt;&gt;&gt;      BnSurface       ----&gt;&gt;&gt;&gt;      ISurface\r\nsp&lt;ISurfaceTexture&gt; BSurface::getSurfaceTexture()\r\n        SurfaceTexture::getBufferQueue()\r\n&lt;\/pre&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\r\nLayer       ----&gt;&gt;&gt;&gt;      LayerBaseClient       ----&gt;&gt;&gt;&gt;       LayerBase\r\nsp&lt;ISurface&gt; Layer::createSurface()\r\n        new BSurface\r\n\r\n                          sp&lt;ISurface&gt; LayerBaseClient::getSurface()\r\n                                  sp&lt;ISurface&gt; LayerBaseClient::createSurface() \r\n&lt;\/pre&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\r\n                           BpSurfaceComposerClient       ----&gt;&gt;&gt;&gt;      ISurfaceComposerClient\r\n                                                                       sp&lt;ISurface&gt; ISurfaceComposerClient::createSurface()\r\n\r\nClient       ----&gt;&gt;&gt;&gt;      BnSurfaceComposerClient       ----&gt;&gt;&gt;&gt;      ISurfaceComposerClient\r\nClient::createSurface()\r\n        SurfaceFlinger::createLayer()\r\n                createXXXLayer()\r\n                        new LayerXXX\r\n                Layer::getSurface()\r\n                \tLayer::createSurface()\r\n&lt;\/pre&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\r\nsp&lt;SurfaceControl&gt; SurfaceComposerClient::createSurface()\r\n              ISurfaceComposerClient::createSurface()\r\n              new SurfaceControl(ISurface)\r\n\/\/ SurfaceComposerClient\u53ea\u662f\u4e2a\u666e\u901a\u7684\u5de5\u5177\u7c7b\uff0c\u5b83\u7684createSurface\u4f1a\u53bb\u8c03\u7528ISurfaceComposerClient\u548ccreateSurface\r\n&lt;\/pre&gt;\n&lt;p&gt;\u73b0\u5728\u6765\u770b\u4e00\u79cd\u60c5\u51b5\uff0c\u5047\u8bbe\u5ba2\u6237\u7aef\u8981\u521b\u5efa\u4e00\u4e2aSurfaceView\uff0c\u8fd9\u4e2d\u95f4\u4f1a\u53d1\u751f\u4ec0\u4e48\u6837\u7684\u4e8b\u60c5\u3002&lt;br \/&gt;\n\u5f53\u7136\u4f60\u5148\u5f97\u4e86\u89e3\u5728Java\u5c42\u5f53\u4e2dSurfaceView\/SurfaceHolder\/Surface\u8fd9\u4e09\u8005\u662f\u4ec0\u4e48\u5173\u7cfb\u3002&lt;\/p&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\r\n=================================Java=====================================================\r\nnew SurfaceView\r\n\tsurface = new Surface \/\/ \u8fd9\u4e2a\u662fSurfaceView\u5f53\u4e2d\u7684Surface(\u8fd9\u90fd\u662f\u7a7a\u7684\uff0c\u4e0d\u4f1a\u5728\u670d\u52a1\u7aef\u771f\u6b63\u7684\u53bb\u521b\u5efa\u4e00\u4e2aSurface)\r\n\tnewSurface = new Surface \/\/ \u8fd9\u4e2a\u662f\u65b0\u7684Surface\uff0c\u5f53Surface\u6539\u53d8\/\u88ab\u521b\u5efa\/\u88ab\u9500\u6bc1\/\u9700\u8981\u91cd\u7ed8\uff0c\r\n\t\t\t\t\t\t\t \/\/ \u90fd\u4f1a\u662f\u73b0\u5728\u7cfb\u7edf\u5c42\u51c6\u5907\u597d\uff0c\u7136\u540e\u518d\u590d\u5236\u6765\u66ff\u4ee3\u6211\u4eecSurfaceView\u5f53\r\n\t\t\t\t\t\t\t \/\/ \u4e2d\u7684\u539f\u6765\u7684Surface(\u901a\u8fc7transferFrom\u5b8c\u6210)\r\n&lt;\/pre&gt;\n&lt;p&gt;\u771f\u6b63\u521b\u5efaSurface\u7684\u65b9\u6cd5\u662f\u7cfb\u7edf\u53bb\u8c03\u7528\u7684\uff0capp\u4e0d\u4f1a\u76f4\u63a5\u53bb\u8c03\u7528\uff0c\u4f46\u662f\u4e00\u65e6\u88ab\u8c03\u7528\u4e4b\u540e\u5c31\u4f1a\u8fdb\u5165\u5230JNI\u5c42\u76f8\u5e94\u65b9\u6cd5\u4e4b\u4e2d\uff0c&lt;br \/&gt;\n\u4f1a\u7528\u5230\u4e00\u4e2aSurfaceSession\uff0c\u4e66\u9762\u89e3\u91ca\u662f\u8868\u793a\u5230Surface Flinger\u7684\u4e00\u6b21\u4f1a\u8bdd\uff0c\u56e0\u4e3a\u5ba2\u6237\u7aef\u8981\u540c\u670d\u52a1\u7aef\u6c9f\u901a\uff0c\u5c31\u5b58\u5728\u8fd9\u6837\u4e00\u4e2a\u4f1a\u8bdd\u7684\u6982\u5ff5\uff0c\u8fd9\u4e2a\u5b9e\u9645\u5c31\u662fNative\u5c42SurfaceComposerClient\u7684\u4e00\u4e2a\u5b9e\u4f8b\u3002&lt;\/p&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\r\n=================================JNI&amp;Native========================================\r\nandroid_view_Surface.cpp nativeCreate()\r\n\tandroid_view_SurfaceSession_getClient\r\n\tSurfaceComposerClient-&gt;createSurface\r\n\t\tISurfaceComposerClient-&gt;createSurface \/\/ IPC\r\n\t\t\tClient-&gt;createSurface\r\n\t\t\t\tSurfaceFlinger-&gt;createLayer\r\n\t\t\t\t\tcreateXXXLayer()\r\n\t\t\t\t\t\tnew LayerXXX\r\n\t\t\t\t\tLayer-&gt;getSurface()\r\n\t\tnew SurfaceControl \/\/ SurfaceControl\u5305\u542b\u521b\u5efa\u51fa\u6765\u7684ISurface\r\n\tsetSurfaceControl \/\/ \u4fdd\u5b58\u5230JNI Context\u5f53\u4e2d\r\n&lt;\/pre&gt;\n&lt;p&gt;\u8fd9\u6837Isurface\u5c31\u521b\u5efa\u597d\u4e86&lt;\/p&gt;\n&lt;p&gt;\u518d\u6765\u770b\u53e6\u5916\u4e00\u8def\u53d1\u751f\u4e86\u4ec0\u4e48\u4e8b\u60c5\uff0cWindow\/View System\u9700\u8981\u521d\u59cb\u5316\u6574\u4e2aWindow\uff0c\u8fd9\u6837\u5728SurfaceView\u5f53\u4e2d\u4e00\u4e9bcallback(\u6bd4\u5982resize\/new-surface\/onWindowVisibilityChanged\/setVisibility\/onDetachedFromWindow)\u5c31\u4f1a\u88ab\u8c03\u7528\u5230\uff0c\u8fd9\u4e2a\u65f6\u5019\u6700\u7ec8\u4f1a\u53bb\u8c03\u7528updateWindow\uff0c\u7136\u540eIWindowSession.relayout\u4e4b\u540e\u5c31\u4f1a\u6709\u65b0\u7684Surface\u88ab\u4ea7\u751f\u51fa\u6765\uff0c\u7136\u540e\u901a\u8fc7Surface.transferFrom\u590d\u5236\u5230SurfaceView\u7684Surface\u5f53\u4e2d\u3002&lt;\/p&gt;\n&lt;p&gt;\u8fd8\u6709\u4e00\u70b9\u6ce8\u610f\u7684\u5730\u65b9Java\u5c42\u7684Surface(Surface.java)\u662f\u5982\u4f55\u8f6c\u5316\u4e3aNative\u5c42\u7684Surface(Surface.h|cpp\uff0c\u4e5f\u5c31\u662fSurfaceTextureClient)\u7684\uff0c\u6ce8\u610fSurface.java\u6301\u6709\u4e00\u4e2a\u540d\u4e3amNativeSurface\u7684Surface.h|cpp\u7684\u6307\u9488\uff0c\u7136\u540e\u6bcf\u6b21\u65b0\u521b\u5efaNative\u5c42\u7684Surface\u4e4b\u540e\uff0c\u5c31\u4f1a\u628a\u5b83\u4fdd\u5b58\u5230JNI Context\u5f53\u4e2d\uff0c\u7136\u540eJava\/Native\u5c31\u662f\u901a\u8fc7\u8fd9\u4e48\u6765\u8f6c\u6362\u7684\u3002&lt;\/p&gt;\n&lt;p&gt;\u63a5\u7740\u6211\u4eec\u5c31\u53ea\u770bNative\u5c42Surface\u7684\u7ba1\u7406\uff0candroid_view_Surface.h|cpp\u5f53\u4e2d\u6709\u8fd9\u4e48\u4e2a\u65b9\u6cd5android_view_Surface_getNativeWindow&lt;br \/&gt;\n\u800c\u5b83\u53c8\u53bb\u8c03\u7528\u4e00\u4e2a\u5185\u90e8\u65b9\u6cd5getSurface\uff0c\u5982\u4e0b\uff1a&lt;\/p&gt;\n&lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\r\nstatic sp&lt;Surface&gt; getSurface(JNIEnv* env, jobject surfaceObj) {\r\n    sp&lt;Surface&gt; result(android_view_Surface_getSurface(env, surfaceObj)); \/\/ \u5982\u679c\u53d6\u51fa\u6765\u4e3a\u7a7a\r\n    if (result == NULL) {\r\n        \/*\r\n         * if this method is called from the WindowManager&#039;s process, it means\r\n         * the client is is not remote, and therefore is allowed to have\r\n         * a Surface (data), so we create it here.\r\n         * If we don&#039;t have a SurfaceControl, it means we&#039;re in a different\r\n         * process.\r\n         *\/\r\n\r\n        SurfaceControl* const control = reinterpret_cast&lt;SurfaceControl*&gt;(\r\n                env-&gt;GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl));\r\n        if (control) {\r\n            result = control-&gt;getSurface(); \/\/ \u521b\u5efaSurface(SurfaceTextureClient)\r\n            if (result != NULL) {\r\n                result-&gt;incStrong(surfaceObj);\r\n                env-&gt;SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface, \/\/ Native\u5173\u8054\u53d8\u91cf\uff0cgui\/Surface.h\r\n                        reinterpret_cast&lt;jint&gt;(result.get()));\r\n            }\r\n        }\r\n    }\r\n    return result;\r\n}\r\n\r\nsp&lt;ANativeWindow&gt; android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) { \/\/ \u8fd9\u662f\u4f9bNative Activity\u4f7f\u7528\u7684\r\n    return getSurface(env, surfaceObj);\r\n}\r\n&lt;\/pre&gt;\n&lt;p&gt;\u770b\u4f3c\u8fd9\u5c31\u662f\u521b\u5efaSurface\u7684\u5730\u65b9\uff0c\u5b9e\u5219\u4e0d\u7136\uff0c\u8fd9\u662f\u4f9bNative Activity\u4f7f\u7528\u3002\u6211\u4eec\u666e\u901a\u7684Java Activity\u662fcreateFromParcel\u3002&lt;br \/&gt;\n\u521b\u5efa\u7684\u8fc7\u7a0b\u5f53\u4e2d\u4f1a\u521d\u59cb\u5316ISurface\u53d8\u91cf\uff0c\u8fd9\u4e2a\u662f\u4eceSurfaceFlinger\u7684Layer\u7684\u521b\u5efa\u7684\uff0c\u53e6\u5916\u4e5f\u4f1a\u901a\u8fc7ISurface-&gt;getSurfaceTexture()\u53d6\u5f97BufferQueue\uff0c\u8fd9\u6837(Surface)SurfaceTextureClient\u548cBufferQueue\u4e5f\u5c31\u5efa\u7acb\u8d77\u4e86\u8054\u7cfb\uff0c\u4e5f\u5c31\u80fd\u901a\u8fc7native_window_*\u6216\u8005ANativeWindow\u5f80BufferQueue\u91cc\u538b\u5165\u6570\u636e\u3002&lt;\/p&gt;\n&lt;p&gt;\u4e3e\u4e2aCamera\u7684\u4f8b\u5b50\uff0c\u6211\u4eec\u77e5\u9053\u5728HAL\u5f53\u4e2d\u6bcf\u4e2aStream\u521b\u5efa\u7684\u65f6\u5019\u90fd\u4f1a\u6709\u4e00\u4e2acamera2_stream_ops\u53c2\u6570\u4f20\u8fdb\u53bb\uff0c\u5e76\u4e14\u5728Stream\u7684callback\u5f53\u4e2d\u90fd\u4f1a\u8c03\u7528camera2_stream_ops-&gt;enqueue_buffer\uff0c\u7136\u540e\u8c03\u7528\u5230ANativeWindow-&gt;queueBuffer\uff0c\u6700\u7ec8\u4f1a\u8c03\u7528\u5230BufferQueue\u7684\u65b9\u6cd5\uff0c\u6240\u4ee5\u4f60\u770b\u5982\u679c\u6211\u4eec\u5582\u7ed9Camera HAL\u7684ANativeWindow\u662fSurfaceFlinger\u5f53\u4e2d\u521b\u5efa\u7684\u8bdd\uff0c\u90a3\u4e48Stream\u7684\u6570\u636e\u5c31\u4f1a\u56de\u5230SurfaceFlinger\u5f53\u4e2d\uff0cSurfaceFlinger\u5bf9\u9700\u8981\u7684Layer\u7684\u6570\u636e\u8fdb\u884cmerge\u4e4b\u540e\u5c31\u53ef\u4ee5\u7ed9FB\u663e\u793a\u51fa\u6765\u4e86\uff0c\u8fd9\u5c31\u662fCamera preview\u7684\u539f\u7406\u3002&lt;\/p&gt;\n&lt;p&gt;SurfaceFlinger\u5185\u90e8\u6bd4\u8f83\u91cd\u8981\u7684\u4e00\u4e9b\u529f\u80fd\u6216\u8005\u7c7b\u5206\u6790\uff1a&lt;br \/&gt;\n\u6211\u4eec\u77e5\u9053\u5728Jelly Bean\u5f53\u4e2d\u6709\u9ec4\u6cb9\u8ba1\u5212\uff0c\u4e3b\u8981\u5c31\u662f\u5f15\u5165VSYNC\uff0c Triple Buffer\u8fd9\u4e9b\u4e1c\u897f\uff0cTriple Buffer\u5728Layer.h|cpp\u5f53\u4e2d\u6709\u63d0\u5230\u3002&lt;br \/&gt;\n\u90a3VSYNC\u662f\u4ec0\u4e48\u4e1c\u897f\uff0c\u7b80\u5355\u6765\u8bf4\u5c31\u662f\u4e00\u4e2a\u56fa\u5b9a\u9891\u7387\u7684\u65f6\u949f\uff0c\u901a\u5e38\u7531\u663e\u793a\u5668\u786c\u4ef6\u6765\u63d0\u4f9b\uff0c\u5982\u679c\u786c\u4ef6\u6ca1\u6709\u63d0\u4f9b\uff0c\u90a3Android\u8fd9\u91cc\u81ea\u5df1\u4f1a\u6a21\u62df\u4e00\u4e2a\uff0c\u53c2\u89c1HWComposer.h|cpp\u5f53\u4e2d\u7684VSyncThread\u8fd9\u4e2a\u7c7b\uff0c\u5b9e\u73b0\u4e5f\u662f\u975e\u5e38\u7b80\u6d01\u660e\u4e86\uff0c\u81ea\u5df1\u770b\u770b\u4ee3\u7801\u5c31\u80fd\u660e\u767d\u3002\u5176\u5b9eVSYNC\/Triple Buffer\u8fd9\u4e9b\u4e1c\u897f\u5728PC\u9886\u57df\u5df2\u7ecf\u662f\u5e94\u7528\u591a\u5e74\u7684\u8001\u6280\u672f\u4e86\uff0c\u611f\u5174\u8da3\u7684\u53ef\u4ee5\u81ea\u5df1\u641c\u7d22\u770b\u770b\u3002&lt;\/p&gt;\n&lt;p&gt;\u90a3\u7b80\u5355\u7684\u7406\u89e3\u6765\u770b\uff0c\u786c\u4ef6\u5b9e\u73b0\u5c31\u662f\u6211\u4eec\u6709\u6ce8\u518c\u4e00\u4e2acallback\u7ed9\u786c\u4ef6\uff0c\u5f53\u6709VSYNC\u8fc7\u6765\u7684\u8bdd\u5c31\u4f1a\u88ab\u8c03\u7528\uff0c\u5f53\u7136\u6700\u7ec8\u4f1a\u88ab\u8c03\u7528\u5230onVSyncReceived\u8fd9\u4e2a\u65b9\u6cd5\uff0c\u90a3\u8f6f\u4ef6\u65b9\u5f0f\u5c31\u662f\u5229\u7528\u65f6\u949f\u4e86\uff0c\u6bcf\u95f4\u9694\u56fa\u5b9a\u7684\u65f6\u95f4\u5c31\u8c03\u7528onVSyncReceived\u3002&lt;br \/&gt;\n\u53e6\u5916\u8fd8\u6709\u4e2a\u548cVSYNC\u6ca1\u6709\u5173\u7cfb\uff0c\u4f46\u662f\u5374\u5728\u8fd9\u91cc\u51fa\u73b0\u7684\u4e00\u4e2a\u5c31\u662fonHotplugReceived\uff0c\u5c31\u662f\u4f60\u7684\u5916\u63a5\u6216\u8005\u865a\u62df\u663e\u793a\u5668\u88ab\u62d4\u6389\u6216\u8005\u63a5\u4e0a\u4f1a\u53d1\u751f\u7684\u4e8b\u4ef6\uff0c\u8fd9\u91cc\u7684\u8bdd\u62d4\u6389\u4f1a\u5bfc\u81f4\u4ece\u786c\u4ef6VSYNC\u5207\u6362\u56de\u8f6f\u4ef6\u65b9\u5f0f\uff0c\u63a5\u4e0a\u7684\u8bdd\u53c8\u4f1a\u4ece\u8f6f\u4ef6\u5207\u6362\u56de\u786c\u4ef6\u7684\u65b9\u5f0f\uff0c\u603b\u4e4b\u8fd9\u91cc\u4f18\u5148\u4f7f\u7528\u786c\u4ef6\u65b9\u5f0f\u3002&lt;\/p&gt;\n&lt;p&gt;IDisplayEventConnection\u662f\u5ba2\u6237\u7aef\u7528\u6765\u548cSurfaceFlinger\u505aVSYNC\u6c9f\u901a\u7684\u901a\u9053\uff0c\u5229\u7528Binder\u5b9e\u73b0\uff0c\u6bd4\u5982setVsyncRate\/requestNextVsync\/getDataChannel\u8fd9\u4e9b\u65b9\u6cd5\uff0c\u4ece\u5b57\u9762\u610f\u601d\u5c31\u6bd4\u8f83\u5bb9\u6613\u7406\u89e3\u51fa\u8fd9\u51e0\u4e2a\u65b9\u6cd5\u7684\u542b\u4e49\uff0cset\u5c31\u8bbe\u7f6eVSYNC\u4e8b\u4ef6\u88ab\u901a\u77e5\u7684\u9891\u7387\uff0crequest\u5c31\u662f\u624b\u52a8\u8bf7\u6c42\u4e00\u6b21VSYNC\u4e8b\u4ef6\uff0cdata channel\u5c31\u662f\u83b7\u53d6\u6570\u636e\u4f20\u9012\u7684\u901a\u9053\uff0c\u8fd9\u91cc\u662fBitTube\u5b9e\u73b0\uff0c\u5b83\u662f\u4e00\u4e2a\u5229\u7528Socket\u5b9e\u73b0\u7684\u8de8\u8fdb\u7a0b\u901a\u4fe1\u7684\u7ba1\u9053\uff0c\u5e76\u4e14\u4f60\u53ef\u4ee5\u5728\u5b83\u4e0a\u9762\u6ce8\u518c\u611f\u5174\u8da3\u7684\u4e8b\u4ef6\uff0c\u5f53\u4e8b\u4ef6\u5230\u6765\u65f6\u5019\uff0c\u5b83\u901a\u77e5\u4f60(\u5229\u7528epoll\u5b9e\u73b0)\u3002&lt;br \/&gt;\n\u6240\u4ee5\u6bcf\u4e2a\u5ba2\u6237\u7aef\u53ef\u4ee5\u9009\u62e9\u81ea\u5df1\u8981\u7684VYSNC\u7684\u4e8b\u4ef6\u7684\u9891\u7387\uff0c\u7136\u540e\u5c31\u6536\u542c\u4e8b\u4ef6\u901a\u77e5\u5c31\u53ef\u4ee5\u4e86\uff0cJava\u5c42\u7684Choreographer\u5c31\u662f\u5229\u7528\u8fd9\u4e2a\u5b9e\u73b0\u7684\u3002\u6211\u4eec\u8981\u6307\u5bfc\u8fd9\u4e2aIDisplayEventConnection\u662f\u53ef\u4ee5\u6709\u591a\u4e2a\u7684\uff0c\u6bd4\u5982View\u7cfb\u7edf\u6216\u8005Animation\u7cfb\u7edf\u90fd\u7528\u5230\u8fd9\u4e2a\uff0c\u6bd4\u5982\u4f60\u81ea\u5df1\u5199\u7684App\u5982\u679c\u4e0d\u7528\u7cfb\u7edfView\/Animation\u76f8\u5173\u7684\uff0c\u4f60\u4e5f\u53ef\u4ee5\u81ea\u5df1\u5229\u7528Choreographer\u6765\u6ce8\u518c\u3002&lt;br \/&gt;\n\u90a3\u73b0\u5728SurfaceFlinger\u662f\u5982\u4f55\u7ba1\u7406\u8fd9\u4e9b\u4e8b\u4ef6\u8bf7\u6c42\u6216\u8005\u76d1\u542c\u901a\u77e5\u7684\u5462\uff1f&lt;br \/&gt;\n\u901a\u8fc7EventThread\uff0c\u8fd9\u662f\u4e00\u4e2a\u666e\u901a\u7684Thread\uff0c\u5ba2\u6237\u7aef\u6bcf\u8c03\u7528\u4e00\u6b21SurfaceFlinger\u7684createDisplayEventConnection\u5c31\u4f1a\u521b\u5efa\u4e00\u4e2aConnection\uff0c\u968f\u540e\u88ab\u52a0\u5165\u5230EventThreade\u5f53\u4e2d\u7684mDisplayEventConnections\uff0c\u5e76\u89e6\u53d1\u8fd9\u4e2a\u7ebf\u7a0b\u7684threadLoop\u6765\u6267\u884c(\u6ca1\u6709\u4e8b\u4ef6\u9700\u8981\u6267\u884c\u7684\u65f6\u5019\uff0c\u8be5\u7ebf\u7a0b\u662f\u7761\u7720\u72b6\u6001\uff0c\u56e0\u4e3awaitForEvent\u65b9\u6cd5\u91cc\u9762\u6709wait)\uff0c\u6700\u540e\u5c06\u7ed3\u679c\u901a\u8fc7postEvent\u63d0\u4ea4\u7ed9BitTupe\uff0c\u8fd9\u6837\u4e4b\u524d\u6709\u5728\u4e0a\u9762\u6ce8\u518c\u4e8b\u4ef6\u76d1\u542c\u7684\u5c31\u4f1a\u6536\u5230\u5bf9\u5e94\u7684\u4e8b\u4ef6\u3002&lt;br \/&gt;\n\u8be6\u7ec6\u7684\u4ee3\u7801\u5206\u6790\u8bf7\u53c2\u89c1(&lt;a href=&quot;https:\/\/github.com\/guohai\/and-notes\/tree\/master\/surfaceflinger-jb-4.2&quot; target=&quot;_blank&quot;&gt;https:\/\/github.com\/guohai\/and-notes\/tree\/master\/surfaceflinger-jb-4.2&lt;\/a&gt;)\u4e2d\u6587\u6ce8\u91ca\/\u53ef\u80fd\u4e5f\u6709\u5c11\u90e8\u5206\u662f\u6211\u6dfb\u52a0\u7684\u82f1\u6587\u6ce8\u91ca\u3002&lt;\/p&gt;\n&lt;p&gt;\u6742\u9879\uff1a&lt;br \/&gt;\n\u53e6\u5916FrameBufferNativeWindow\u5df2\u7ecf\u4e0d\u518d\u88ab\u4f7f\u7528\u4e86\u3002&lt;\/p&gt;\n&lt;p&gt;\u6211\u4eec\u901a\u5e38\u8bf4\u5728\u65b0\u7684\u652f\u6301\u786c\u4ef6\u52a0\u901f\u7684\u8bbe\u5907\u548c\u7cfb\u7edf\u4e0a\uff0c\u6211\u4eec\u503e\u5411\u4e8e\u4f7f\u7528TextureView\u6765\u66ff\u4ee3SurfaceView\uff0c\u8fd9\u91cc\u9762\u53c8\u662f\u4ec0\u4e48\u539f\u56e0\u5462\uff1f&lt;br \/&gt;\n\u90fd\u77e5\u9053SurfaceView\u4f1a\u5355\u72ec\u521b\u5efa\u4e00\u4e2aSurface\uff0c\u5728SurfaceFlinger\u5f53\u4e2d\u7684\u4f53\u73b0\u4e5f\u662f\u591a\u521b\u5efa\u4e00\u4e2aLayer\uff0c\u7136\u540e\u4e0e\u539f\u6709\u7684\uff0c\u6bd4\u5982Window\/Status Bar\u7b49\u7b49\u8fd9\u4e9bLayer\u5408\u5e76\u4e4b\u540e\u518d\u5728display\u4e0a\u753b\u51fa\u6765\u3002&lt;br \/&gt;\n\u90a3\u4f7f\u7528TextureView\u5c31\u4e0d\u4f1a\u6709\u8fd9\u4e48\u4e00\u4e2a\u8fc7\u7a0b\u5417\uff1f\u662f\u7684\uff0c\u56e0\u4e3aTextureView\u91cc\u9762\u5229\u7528\u4e86SurfaceTexture\uff0cSurfaceTexture\u7684\u521b\u5efa\u4e0d\u4f1a\u5bfc\u81f4SurfaceFlinger\u4e2d\u591a\u51fa\u6765\u4e00\u4e2aLayer\uff0c\u56e0\u4e3a\u5b83\u662f\u4f7f\u7528\u786c\u4ef6\u6765\u505a\u7684\uff0c\u6240\u4ee5TextureView\u5fc5\u987b\u662f\u652f\u6301\u786c\u4ef6\u52a0\u901f\uff0c\u5e76\u4e14\u5f00\u542f\u7684\u60c5\u51b5\u4e0b\u624d\u80fd\u4f7f\u7528\uff0c\u5426\u5219\u5b83\u4ec0\u4e48\u4e5f\u505a\u4e0d\u4e86\u3002\u4f46\u662f\u5b83\u8fd8\u662f\u4f1a\u521b\u5efa\u4e00\u4e2aLayer\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u4e2aLayer\u662f\u786c\u4ef6\u6765\u521b\u5efa\uff0c\u7ba1\u7406\uff0c\u90a3\u8f6f\u4ef6\u5c42\u9762\u5c31\u4e0d\u7528\u82b1\u8fd9\u4e2a\u529f\u6765\u505a\u8fd9\u4ef6\u4e8b\u60c5\u3002Native\u5c42\u7684SurfaceTexture(ConsumerBase)\u5b83\u8d1f\u8d23\u63a5\u6536\u8fc7\u6765\u7684\u6570\u636e\uff0c\u7136\u540e\u901a\u8fc7JNI\u5f80\u4e0a\u4f20View\u5c42\uff0c\u8f6f\u4ef6\u5c42\u9762\u7684\u5de5\u4f5c\u5c31\u7ed3\u675f\u4e86\u3002&lt;\/p&gt;\n&lt;p&gt;P.S. \u8be6\u7ec6\u4fe1\u606f\u5f85\u8865\u5145&lt;\/p&gt;\n<\/div><div class=\"gfmr-markdown-rendered\"><p>\u9488\u5bf9Jelly Bean\u7248\u672c\u7684\u4ee3\u7801\u3002<br \/>\nSurfaceFlinger\u662f\u4ec0\u4e48\uff0c\u8fd9\u4e9b\u4ecb\u7ecd\u5927\u5bb6\u53ef\u4ee5\u5728\u7f51\u7edc\u4e0a\u627e\u627e\u770b\uff0c\u8fd9\u91cc\u5c31\u76f4\u63a5\u4e0a\u4ee3\u7801\u3002<\/p>\n<p>\u9996\u5148\u6211\u4eec\u5f97\u4e86\u89e3\u4e00\u79cd\u5e38\u7528\u7684\u7f16\u7a0b\u505a\u6cd5\uff0c\u751f\u4ea7\u8005\/\u6d88\u8d39\u8005\u6a21\u578b\uff0c\u4e5f\u8bb8\u90fd\u4f1a\u89c9\u5f97\u5f88\u7b80\u5355\uff0c\u4f46\u662f\u8fd9\u91cc\u5c31\u7528\u5230\u4e86\u5f88\u591a\u8fd9\u4e9b\u57fa\u672c\u6982\u5ff5\u3002<br \/>\nBufferQueue \u6570\u636e\u90fdqueue\u5230\u8fd9\u91cc\u9762\uff0c\u524d\u63d0\u662f\u5b83\u662f\u5148\u4eceBufferQueue\u53d6\u51fa\u4e00\u4e2a\u7a7a\u7684\u6570\u636e\u5355\u5143\uff0c\u79f0\u4e3a\u4e00\u4e2abuffer\uff0c\u5b9e\u9645\u4e3aGraphicBuffer\u7c7b\u578b\u3002<\/p>\n<p>ConsumerBase \u5b83\u662f\u6d88\u8d39\u8005\u7aef\u4f7f\u7528\u7684\u63a5\u53e3\uff0c\u5b83\u5b9e\u73b0\u4e86BufferQueue::ConsumerListener\u63a5\u53e3\uff0c\u4e5f\u5c31\u662fBufferQueue\u5f53\u4e2d\u6709buffer\u88abqueue\u7684\u65f6\u5019\uff0c\u5b83\u80fd\u88ab\u901a\u77e5\u5230(onFrameAvailable)\u3002\u540c\u7406\u5f53\u751f\u4ea7\u8005disconnect\u4e0eBufferQueue\u7684\u8fde\u63a5\u6216\u8005setBufferCount\u88ab\u8c03\u7528(\u8be5\u65b9\u6cd5\u91ca\u653e\u6389\u6240\u6709buffer\uff0c\u8ba9buffer\u90fd\u5f52BufferQueue\u6240\u6709\uff0c\u5982\u679c\u6709buffer\u5904\u4e8eDEQUEUED\u72b6\u6001\uff0c\u6b64\u65b9\u6cd5\u8fd4\u56de\u9519\u8bef)\uff0c\u5b83\u4e5f\u4f1a\u88ab\u901a\u77e5\u5230(onBuffersReleased)\u3002<\/p>\n<p>BufferItemConsumer\u548cCpuConsumer \u5b83\u4eec\u90fd\u662fConsumerBase\u7684\u5b50\u7c7b\uff0cBufferItemConsumer\u4e00\u6b21\u53ef\u4ee5acquire\u591a\u4e2abuffer\uff0cConsumerBase\u4e00\u6b21\u53ea\u80fd\u4e00\u4e2a\uff0cBufferItemConsumer\u662f\u4fee\u6539\u4e86BufferQueue\u7684mMaxAcquiredBufferCount\u53c2\u6570\uff0cConsumerBase\u4f7f\u7528\u7684\u9ed8\u8ba4\u503c1\u3002CpuBuffer\u53ef\u4ee5\u628abuffer\u9501\u8d77\u6765\u4f9bCPU\u4f7f\u7528\uff0c\u5b83\u4e5f\u662f\u8c03\u7528GRALLOC\u7684\u65b9\u6cd5\u6765\u5b8c\u6210\u8fd9\u4e2a\u529f\u80fd\u7684\u3002<br \/>\nFramebufferSurface ConsumerBase\u7684\u5b50\u7c7b\uff0c\u4f1a\u628a\u6536\u5230\u7684\u6570\u636e\u901a\u8fc7HWComposer\u5f80\u8367\u5e55\u4e0a\u8d34\u3002<br \/>\nSurfaceTexture ConsumerBase\u7684\u5b50\u7c7b\uff0c\u5b83\u53ef\u4ee5\u628aGraphicBuffer\u8f6c\u6362\u6210texture image\uff0c\u7136\u540e\u4ea4\u7ed9OpenGL\u3002<\/p>\n<p>SurfaceTextureLayer\u662f\u4e00\u4e2a\u5b9a\u5236\u5316\u7684BufferQueue\uff0cNATIVE_WINDOW_API_MEDIA\/NATIVE_WINDOW_API_CAMERA\u8fc7\u6765\u7684\u8bf7\u6c42\u4f1a\u628aBufferQueue\u8bbe\u7f6e\u4e3a\u5f02\u6b65\u6a21\u5f0f\u3002<\/p>\n<p>BufferQueue\u5f53\u4e2dbuffer\u7684\u72b6\u6001\uff0c\u8fd9\u4e2a\u5f88\u7b80\u5355\uff0c\u4f46\u662f\u4e5f\u5f88\u91cd\u8981\u3002<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\/\/ BufferState represents the different states in which a buffer slot\r\n\/\/ can be.\r\nenum BufferState {\r\n    \/\/ FREE indicates that the buffer is not currently being used and\r\n    \/\/ will not be used in the future until it gets dequeued and\r\n    \/\/ subsequently queued by the client.\r\n    \/\/ aka &quot;owned by BufferQueue, ready to be dequeued&quot;\r\n    FREE = 0,\r\n\r\n    \/\/ DEQUEUED indicates that the buffer has been dequeued by the\r\n    \/\/ client, but has not yet been queued or canceled. The buffer is\r\n    \/\/ considered &#039;owned&#039; by the client, and the server should not use\r\n    \/\/ it for anything.\r\n    \/\/\r\n    \/\/ Note that when in synchronous-mode (mSynchronousMode == true),\r\n    \/\/ the buffer that&#039;s currently attached to the texture may be\r\n    \/\/ dequeued by the client.  That means that the current buffer can\r\n    \/\/ be in either the DEQUEUED or QUEUED state.  In asynchronous mode,\r\n    \/\/ however, the current buffer is always in the QUEUED state.\r\n    \/\/ aka &quot;owned by producer, ready to be queued&quot;\r\n    DEQUEUED = 1,\r\n\r\n    \/\/ QUEUED indicates that the buffer has been queued by the client,\r\n    \/\/ and has not since been made available for the client to dequeue.\r\n    \/\/ Attaching the buffer to the texture does NOT transition the\r\n    \/\/ buffer away from the QUEUED state. However, in Synchronous mode\r\n    \/\/ the current buffer may be dequeued by the client under some\r\n    \/\/ circumstances. See the note about the current buffer in the\r\n    \/\/ documentation for DEQUEUED.\r\n    \/\/ aka &quot;owned by BufferQueue, ready to be acquired&quot;\r\n    QUEUED = 2,\r\n\r\n    \/\/ aka &quot;owned by consumer, ready to be released&quot;\r\n    ACQUIRED = 3\r\n};<\/pre>\n<p>BufferQueue\u4e3b\u8981\u65b9\u6cd5<br \/>\ndequeueBuffer\u53d6\u4e00\u4e2abuffer(\u8fd4\u56deslot\uff0c\u8fd9\u4e2abufer\u662f\u4eceState\u4e3aFREE\u7684\u5f53\u4e2d\u53d6\u7684)\u7ed9client\u4f7f\u7528\uff0c\u5fc5\u8981\u65f6\u5019(null\/height\/width\/format\/usage\u4efb\u4f55\u4e00\u70b9\u4e0d\u6ee1\u8db3\u90fd\u4f1a\u89e6\u53d1)\u5b83\u4f1a\u4f7f\u7528GraphicBufferAlloc::createGraphicBuffer()\u53bb\u5206\u914dbuffer<\/p>\n<p>requestBuffer\u6839\u636e\u4e00\u4e2a\u6307\u5b9a\u7684slot\u83b7\u53d6\u5b83\u7684buffer\u7684\u5730\u5740\uff0c\u8fd9\u4e2a\u4e3b\u8981\u7528\u5728\u521a\u521a\u5206\u914dbuffer\u4e4b\u540e(\u6216\u8005\u662f\u610f\u5916\u7684\u53d1\u73b0\u6307\u5b9aslot\u7684buffer\u5730\u5740\u4e3a\u7a7a)\uff0c\u76ee\u524d\u5728SurfaceTextureClient(Surface)\u5f53\u4e2d\u88ab\u4f7f\u7528\u5230<\/p>\n<p>queueBuffer\u901a\u77e5BufferQueue\u538b\u5165\u4e86\u4e00\u4e2a\u88c5\u6ee1\u6570\u636e\u7684buffer\uff0cQueueBufferInput\u662f\u8be5buffer\u7684\u63cf\u8ff0\u6570\u636e\uff0cQueueBufferOutput\u662fBufferQueue\u5f53\u524d\u7684\u72b6\u6001(\u9ed8\u8ba4height\/width\/transformHint\/slot\u7684\u6570\u91cf\uff0c\u8fd9\u4e2aslot\u53ea\u662f\u5f53\u524d\u88ab\u8fd8\u56de\u7ed9BufferQueue)<\/p>\n<p>acquireBuffer\u83b7\u53d6\u4e00\u4e2apending buffer\u7684\u62e5\u6709\u6743\uff0c\u8fd9\u4e2abuffer\u662fmQueue\u5f53\u4e2d\uff0c\u4e5f\u5c31\u662f\u72b6\u6001\u4e3aQUEUED\u7684(\u6709\u6ca1\u6709\u6570\u636e\uff1f)\u3002<\/p>\n<p>releaseBuffer\u653e\u5f03\u6301\u6709\u7684\u6307\u5b9aslot\u7684buffer<\/p>\n<p>freeBuffer\u6216\u8005cancelBuffer\u90fd\u4f1a\u5bfc\u81f4\u8fd9\u4e2abuffer\u5904\u4e8eFREE\u72b6\u6001<\/p>\n<p>ConsumerBase\u7684\u4e3b\u8981\u65b9\u6cd5<br \/>\nacquireBufferLocked\/releaseBufferLocked\/freeBufferLocked\/abandonLocked<\/p>\n<p>\u53e6\u5916\u8fd9\u4e2aprotected\u7684\u6570\u7ec4\u4e5f\u5f88\u91cd\u8981\uff0c\u5b50\u7c7b\u53ef\u4ee5\u76f4\u63a5\u4ece\u5b83\u91cc\u9762\u83b7\u53d6buffer\u7684\u4fe1\u606f\uff0c\u5b83\u5b9e\u9645\u5c31\u76f8\u5f53\u4e8e\u7f13\u5b58\u4e86BufferQueue\u7684\u4e00\u4e9b\u5fc5\u8981\u4fe1\u606f\u3002<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\/\/ mSlots stores the buffers that have been allocated by the BufferQueue\r\n\/\/ for each buffer slot.  It is initialized to null pointers, and gets\r\n\/\/ filled in with the result of BufferQueue::acquire when the\r\n\/\/ client dequeues a buffer from a\r\n\/\/ slot that has not yet been used. The buffer allocated to a slot will also\r\n\/\/ be replaced if the requested buffer usage or geometry differs from that\r\n\/\/ of the buffer allocated to a slot.\r\nSlot mSlots&#x5B;BufferQueue::NUM_BUFFER_SLOTS];<\/pre>\n<p>SurfaceTextureClient\u662f\u4e00\u4e2aANativeWindow\uff0c\u4e3anative_window_api_*\u548cnative_window_*\u65b9\u6cd5(\u8fd9\u4e9b\u90fd\u5728system\/core\/include\/system\/window.h\u5f53\u4e2d)\u505a\u5177\u4f53\u5b9e\u73b0\uff0c\u53e6\u5916\u5b83\u8fd8\u6301\u6709SurfaceTexture\u3002<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\/\/ Initialize the ANativeWindow function pointers.\r\nANativeWindow::setSwapInterval  = hook_setSwapInterval;\r\nANativeWindow::dequeueBuffer    = hook_dequeueBuffer;\r\nANativeWindow::cancelBuffer     = hook_cancelBuffer;\r\nANativeWindow::queueBuffer      = hook_queueBuffer;\r\nANativeWindow::query            = hook_query;\r\nANativeWindow::perform          = hook_perform;\r\n\r\nANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;\r\nANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;\r\nANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;\r\nANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;\r\n\r\nconst_cast&lt;int&amp;&gt;(ANativeWindow::minSwapInterval) = 0;\r\nconst_cast&lt;int&amp;&gt;(ANativeWindow::maxSwapInterval) = 1;<\/pre>\n<p>\u4e00\u4e9b\u91cd\u8981\u7684\u547d\u540d\u6539\u52a8<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\u65e9\u671f\u7684Jelly Bean\u5f53\u4e2d\uff0c\u6bd4\u5982(4.1\/4.2)                  4.3\r\n================================================================================\r\nSurfaceTextureClient\u548cSurface(\u7ee7\u627f                 \u88ab\u7b80\u5316\u6210\u4e86Surface(ANativeWindow)\r\n\u81eaSurfaceTextureClient)\u5b9e\u9645\u5c31\u662f\u4e00\u4e2a\r\nANativeWindow\r\n\r\n================================================================================\r\nISurfaceTexture                                   IGraphicBufferProducer\uff0c\r\n                                                  Binder IPC\u63a5\u53e3\uff0c\u7528\u6765\u5728\u4e0d\u540c\u7ec4\u4ef6\u4e4b\u95f4\r\n                                                  \u4f20\u8f93\u6570\u636e\u4f7f\u7528(\u8de8\u8fdb\u7a0b\u7684)\uff0cBufferQueue\r\n                                                  \u5b9e\u73b0\u4e86BnGraphicBufferProducer\r\n\r\n================================================================================\r\nSurfaceTexture(ConsumerBase)                      GLConsumer(ConsumerBase)\u5b83\u53d6\r\n                                                  BufferQueue\u91cc\u9762\u7684\u6570\u636e\uff0c\u7136\u540e\u4f5c\u4e3a\u4e00\u4e2a\r\n                                                  texture\u63d0\u4f9b\u7ed9OpenGL\u4f7f\u7528\r\n                                                  \r\n<\/pre>\n<p>\u4e0a\u9762\u662f\u4f1a\u7528\u5230\u7684\u57fa\u672c\u77e5\u8bc6\uff0c\u4e0b\u9762\u57fa\u672c\u624d\u76f4\u63a5\u548cSurfaceFlinger\u76f8\u5173\u3002<br \/>\n\u7bad\u5934\u7684\u65b9\u5411\u4e3a\u7ee7\u627f\u7684\u65b9\u5411<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n                             BpSurface       ----&gt;&gt;&gt;&gt;      ISurface\r\n                                                           sp&lt;ISurfaceTexture&gt; ISurface::getSurfaceTexture()\r\n\r\nBSurface       ----&gt;&gt;&gt;&gt;      BnSurface       ----&gt;&gt;&gt;&gt;      ISurface\r\nsp&lt;ISurfaceTexture&gt; BSurface::getSurfaceTexture()\r\n        SurfaceTexture::getBufferQueue()\r\n<\/pre>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nLayer       ----&gt;&gt;&gt;&gt;      LayerBaseClient       ----&gt;&gt;&gt;&gt;       LayerBase\r\nsp&lt;ISurface&gt; Layer::createSurface()\r\n        new BSurface\r\n\r\n                          sp&lt;ISurface&gt; LayerBaseClient::getSurface()\r\n                                  sp&lt;ISurface&gt; LayerBaseClient::createSurface() \r\n<\/pre>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n                           BpSurfaceComposerClient       ----&gt;&gt;&gt;&gt;      ISurfaceComposerClient\r\n                                                                       sp&lt;ISurface&gt; ISurfaceComposerClient::createSurface()\r\n\r\nClient       ----&gt;&gt;&gt;&gt;      BnSurfaceComposerClient       ----&gt;&gt;&gt;&gt;      ISurfaceComposerClient\r\nClient::createSurface()\r\n        SurfaceFlinger::createLayer()\r\n                createXXXLayer()\r\n                        new LayerXXX\r\n                Layer::getSurface()\r\n                \tLayer::createSurface()\r\n<\/pre>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nsp&lt;SurfaceControl&gt; SurfaceComposerClient::createSurface()\r\n              ISurfaceComposerClient::createSurface()\r\n              new SurfaceControl(ISurface)\r\n\/\/ SurfaceComposerClient\u53ea\u662f\u4e2a\u666e\u901a\u7684\u5de5\u5177\u7c7b\uff0c\u5b83\u7684createSurface\u4f1a\u53bb\u8c03\u7528ISurfaceComposerClient\u548ccreateSurface\r\n<\/pre>\n<p>\u73b0\u5728\u6765\u770b\u4e00\u79cd\u60c5\u51b5\uff0c\u5047\u8bbe\u5ba2\u6237\u7aef\u8981\u521b\u5efa\u4e00\u4e2aSurfaceView\uff0c\u8fd9\u4e2d\u95f4\u4f1a\u53d1\u751f\u4ec0\u4e48\u6837\u7684\u4e8b\u60c5\u3002<br \/>\n\u5f53\u7136\u4f60\u5148\u5f97\u4e86\u89e3\u5728Java\u5c42\u5f53\u4e2dSurfaceView\/SurfaceHolder\/Surface\u8fd9\u4e09\u8005\u662f\u4ec0\u4e48\u5173\u7cfb\u3002<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n=================================Java=====================================================\r\nnew SurfaceView\r\n\tsurface = new Surface \/\/ \u8fd9\u4e2a\u662fSurfaceView\u5f53\u4e2d\u7684Surface(\u8fd9\u90fd\u662f\u7a7a\u7684\uff0c\u4e0d\u4f1a\u5728\u670d\u52a1\u7aef\u771f\u6b63\u7684\u53bb\u521b\u5efa\u4e00\u4e2aSurface)\r\n\tnewSurface = new Surface \/\/ \u8fd9\u4e2a\u662f\u65b0\u7684Surface\uff0c\u5f53Surface\u6539\u53d8\/\u88ab\u521b\u5efa\/\u88ab\u9500\u6bc1\/\u9700\u8981\u91cd\u7ed8\uff0c\r\n\t\t\t\t\t\t\t \/\/ \u90fd\u4f1a\u662f\u73b0\u5728\u7cfb\u7edf\u5c42\u51c6\u5907\u597d\uff0c\u7136\u540e\u518d\u590d\u5236\u6765\u66ff\u4ee3\u6211\u4eecSurfaceView\u5f53\r\n\t\t\t\t\t\t\t \/\/ \u4e2d\u7684\u539f\u6765\u7684Surface(\u901a\u8fc7transferFrom\u5b8c\u6210)\r\n<\/pre>\n<p>\u771f\u6b63\u521b\u5efaSurface\u7684\u65b9\u6cd5\u662f\u7cfb\u7edf\u53bb\u8c03\u7528\u7684\uff0capp\u4e0d\u4f1a\u76f4\u63a5\u53bb\u8c03\u7528\uff0c\u4f46\u662f\u4e00\u65e6\u88ab\u8c03\u7528\u4e4b\u540e\u5c31\u4f1a\u8fdb\u5165\u5230JNI\u5c42\u76f8\u5e94\u65b9\u6cd5\u4e4b\u4e2d\uff0c<br \/>\n\u4f1a\u7528\u5230\u4e00\u4e2aSurfaceSession\uff0c\u4e66\u9762\u89e3\u91ca\u662f\u8868\u793a\u5230Surface Flinger\u7684\u4e00\u6b21\u4f1a\u8bdd\uff0c\u56e0\u4e3a\u5ba2\u6237\u7aef\u8981\u540c\u670d\u52a1\u7aef\u6c9f\u901a\uff0c\u5c31\u5b58\u5728\u8fd9\u6837\u4e00\u4e2a\u4f1a\u8bdd\u7684\u6982\u5ff5\uff0c\u8fd9\u4e2a\u5b9e\u9645\u5c31\u662fNative\u5c42SurfaceComposerClient\u7684\u4e00\u4e2a\u5b9e\u4f8b\u3002<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n=================================JNI&amp;Native========================================\r\nandroid_view_Surface.cpp nativeCreate()\r\n\tandroid_view_SurfaceSession_getClient\r\n\tSurfaceComposerClient-&gt;createSurface\r\n\t\tISurfaceComposerClient-&gt;createSurface \/\/ IPC\r\n\t\t\tClient-&gt;createSurface\r\n\t\t\t\tSurfaceFlinger-&gt;createLayer\r\n\t\t\t\t\tcreateXXXLayer()\r\n\t\t\t\t\t\tnew LayerXXX\r\n\t\t\t\t\tLayer-&gt;getSurface()\r\n\t\tnew SurfaceControl \/\/ SurfaceControl\u5305\u542b\u521b\u5efa\u51fa\u6765\u7684ISurface\r\n\tsetSurfaceControl \/\/ \u4fdd\u5b58\u5230JNI Context\u5f53\u4e2d\r\n<\/pre>\n<p>\u8fd9\u6837Isurface\u5c31\u521b\u5efa\u597d\u4e86<\/p>\n<p>\u518d\u6765\u770b\u53e6\u5916\u4e00\u8def\u53d1\u751f\u4e86\u4ec0\u4e48\u4e8b\u60c5\uff0cWindow\/View System\u9700\u8981\u521d\u59cb\u5316\u6574\u4e2aWindow\uff0c\u8fd9\u6837\u5728SurfaceView\u5f53\u4e2d\u4e00\u4e9bcallback(\u6bd4\u5982resize\/new-surface\/onWindowVisibilityChanged\/setVisibility\/onDetachedFromWindow)\u5c31\u4f1a\u88ab\u8c03\u7528\u5230\uff0c\u8fd9\u4e2a\u65f6\u5019\u6700\u7ec8\u4f1a\u53bb\u8c03\u7528updateWindow\uff0c\u7136\u540eIWindowSession.relayout\u4e4b\u540e\u5c31\u4f1a\u6709\u65b0\u7684Surface\u88ab\u4ea7\u751f\u51fa\u6765\uff0c\u7136\u540e\u901a\u8fc7Surface.transferFrom\u590d\u5236\u5230SurfaceView\u7684Surface\u5f53\u4e2d\u3002<\/p>\n<p>\u8fd8\u6709\u4e00\u70b9\u6ce8\u610f\u7684\u5730\u65b9Java\u5c42\u7684Surface(Surface.java)\u662f\u5982\u4f55\u8f6c\u5316\u4e3aNative\u5c42\u7684Surface(Surface.h|cpp\uff0c\u4e5f\u5c31\u662fSurfaceTextureClient)\u7684\uff0c\u6ce8\u610fSurface.java\u6301\u6709\u4e00\u4e2a\u540d\u4e3amNativeSurface\u7684Surface.h|cpp\u7684\u6307\u9488\uff0c\u7136\u540e\u6bcf\u6b21\u65b0\u521b\u5efaNative\u5c42\u7684Surface\u4e4b\u540e\uff0c\u5c31\u4f1a\u628a\u5b83\u4fdd\u5b58\u5230JNI Context\u5f53\u4e2d\uff0c\u7136\u540eJava\/Native\u5c31\u662f\u901a\u8fc7\u8fd9\u4e48\u6765\u8f6c\u6362\u7684\u3002<\/p>\n<p>\u63a5\u7740\u6211\u4eec\u5c31\u53ea\u770bNative\u5c42Surface\u7684\u7ba1\u7406\uff0candroid_view_Surface.h|cpp\u5f53\u4e2d\u6709\u8fd9\u4e48\u4e2a\u65b9\u6cd5android_view_Surface_getNativeWindow<br \/>\n\u800c\u5b83\u53c8\u53bb\u8c03\u7528\u4e00\u4e2a\u5185\u90e8\u65b9\u6cd5getSurface\uff0c\u5982\u4e0b\uff1a<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nstatic sp&lt;Surface&gt; getSurface(JNIEnv* env, jobject surfaceObj) {\r\n    sp&lt;Surface&gt; result(android_view_Surface_getSurface(env, surfaceObj)); \/\/ \u5982\u679c\u53d6\u51fa\u6765\u4e3a\u7a7a\r\n    if (result == NULL) {\r\n        \/*\r\n         * if this method is called from the WindowManager&#039;s process, it means\r\n         * the client is is not remote, and therefore is allowed to have\r\n         * a Surface (data), so we create it here.\r\n         * If we don&#039;t have a SurfaceControl, it means we&#039;re in a different\r\n         * process.\r\n         *\/\r\n\r\n        SurfaceControl* const control = reinterpret_cast&lt;SurfaceControl*&gt;(\r\n                env-&gt;GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl));\r\n        if (control) {\r\n            result = control-&gt;getSurface(); \/\/ \u521b\u5efaSurface(SurfaceTextureClient)\r\n            if (result != NULL) {\r\n                result-&gt;incStrong(surfaceObj);\r\n                env-&gt;SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface, \/\/ Native\u5173\u8054\u53d8\u91cf\uff0cgui\/Surface.h\r\n                        reinterpret_cast&lt;jint&gt;(result.get()));\r\n            }\r\n        }\r\n    }\r\n    return result;\r\n}\r\n\r\nsp&lt;ANativeWindow&gt; android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) { \/\/ \u8fd9\u662f\u4f9bNative Activity\u4f7f\u7528\u7684\r\n    return getSurface(env, surfaceObj);\r\n}\r\n<\/pre>\n<p>\u770b\u4f3c\u8fd9\u5c31\u662f\u521b\u5efaSurface\u7684\u5730\u65b9\uff0c\u5b9e\u5219\u4e0d\u7136\uff0c\u8fd9\u662f\u4f9bNative Activity\u4f7f\u7528\u3002\u6211\u4eec\u666e\u901a\u7684Java Activity\u662fcreateFromParcel\u3002<br \/>\n\u521b\u5efa\u7684\u8fc7\u7a0b\u5f53\u4e2d\u4f1a\u521d\u59cb\u5316ISurface\u53d8\u91cf\uff0c\u8fd9\u4e2a\u662f\u4eceSurfaceFlinger\u7684Layer\u7684\u521b\u5efa\u7684\uff0c\u53e6\u5916\u4e5f\u4f1a\u901a\u8fc7ISurface-&gt;getSurfaceTexture()\u53d6\u5f97BufferQueue\uff0c\u8fd9\u6837(Surface)SurfaceTextureClient\u548cBufferQueue\u4e5f\u5c31\u5efa\u7acb\u8d77\u4e86\u8054\u7cfb\uff0c\u4e5f\u5c31\u80fd\u901a\u8fc7native_window_*\u6216\u8005ANativeWindow\u5f80BufferQueue\u91cc\u538b\u5165\u6570\u636e\u3002<\/p>\n<p>\u4e3e\u4e2aCamera\u7684\u4f8b\u5b50\uff0c\u6211\u4eec\u77e5\u9053\u5728HAL\u5f53\u4e2d\u6bcf\u4e2aStream\u521b\u5efa\u7684\u65f6\u5019\u90fd\u4f1a\u6709\u4e00\u4e2acamera2_stream_ops\u53c2\u6570\u4f20\u8fdb\u53bb\uff0c\u5e76\u4e14\u5728Stream\u7684callback\u5f53\u4e2d\u90fd\u4f1a\u8c03\u7528camera2_stream_ops-&gt;enqueue_buffer\uff0c\u7136\u540e\u8c03\u7528\u5230ANativeWindow-&gt;queueBuffer\uff0c\u6700\u7ec8\u4f1a\u8c03\u7528\u5230BufferQueue\u7684\u65b9\u6cd5\uff0c\u6240\u4ee5\u4f60\u770b\u5982\u679c\u6211\u4eec\u5582\u7ed9Camera HAL\u7684ANativeWindow\u662fSurfaceFlinger\u5f53\u4e2d\u521b\u5efa\u7684\u8bdd\uff0c\u90a3\u4e48Stream\u7684\u6570\u636e\u5c31\u4f1a\u56de\u5230SurfaceFlinger\u5f53\u4e2d\uff0cSurfaceFlinger\u5bf9\u9700\u8981\u7684Layer\u7684\u6570\u636e\u8fdb\u884cmerge\u4e4b\u540e\u5c31\u53ef\u4ee5\u7ed9FB\u663e\u793a\u51fa\u6765\u4e86\uff0c\u8fd9\u5c31\u662fCamera preview\u7684\u539f\u7406\u3002<\/p>\n<p>SurfaceFlinger\u5185\u90e8\u6bd4\u8f83\u91cd\u8981\u7684\u4e00\u4e9b\u529f\u80fd\u6216\u8005\u7c7b\u5206\u6790\uff1a<br \/>\n\u6211\u4eec\u77e5\u9053\u5728Jelly Bean\u5f53\u4e2d\u6709\u9ec4\u6cb9\u8ba1\u5212\uff0c\u4e3b\u8981\u5c31\u662f\u5f15\u5165VSYNC\uff0c Triple Buffer\u8fd9\u4e9b\u4e1c\u897f\uff0cTriple Buffer\u5728Layer.h|cpp\u5f53\u4e2d\u6709\u63d0\u5230\u3002<br \/>\n\u90a3VSYNC\u662f\u4ec0\u4e48\u4e1c\u897f\uff0c\u7b80\u5355\u6765\u8bf4\u5c31\u662f\u4e00\u4e2a\u56fa\u5b9a\u9891\u7387\u7684\u65f6\u949f\uff0c\u901a\u5e38\u7531\u663e\u793a\u5668\u786c\u4ef6\u6765\u63d0\u4f9b\uff0c\u5982\u679c\u786c\u4ef6\u6ca1\u6709\u63d0\u4f9b\uff0c\u90a3Android\u8fd9\u91cc\u81ea\u5df1\u4f1a\u6a21\u62df\u4e00\u4e2a\uff0c\u53c2\u89c1HWComposer.h|cpp\u5f53\u4e2d\u7684VSyncThread\u8fd9\u4e2a\u7c7b\uff0c\u5b9e\u73b0\u4e5f\u662f\u975e\u5e38\u7b80\u6d01\u660e\u4e86\uff0c\u81ea\u5df1\u770b\u770b\u4ee3\u7801\u5c31\u80fd\u660e\u767d\u3002\u5176\u5b9eVSYNC\/Triple Buffer\u8fd9\u4e9b\u4e1c\u897f\u5728PC\u9886\u57df\u5df2\u7ecf\u662f\u5e94\u7528\u591a\u5e74\u7684\u8001\u6280\u672f\u4e86\uff0c\u611f\u5174\u8da3\u7684\u53ef\u4ee5\u81ea\u5df1\u641c\u7d22\u770b\u770b\u3002<\/p>\n<p>\u90a3\u7b80\u5355\u7684\u7406\u89e3\u6765\u770b\uff0c\u786c\u4ef6\u5b9e\u73b0\u5c31\u662f\u6211\u4eec\u6709\u6ce8\u518c\u4e00\u4e2acallback\u7ed9\u786c\u4ef6\uff0c\u5f53\u6709VSYNC\u8fc7\u6765\u7684\u8bdd\u5c31\u4f1a\u88ab\u8c03\u7528\uff0c\u5f53\u7136\u6700\u7ec8\u4f1a\u88ab\u8c03\u7528\u5230onVSyncReceived\u8fd9\u4e2a\u65b9\u6cd5\uff0c\u90a3\u8f6f\u4ef6\u65b9\u5f0f\u5c31\u662f\u5229\u7528\u65f6\u949f\u4e86\uff0c\u6bcf\u95f4\u9694\u56fa\u5b9a\u7684\u65f6\u95f4\u5c31\u8c03\u7528onVSyncReceived\u3002<br \/>\n\u53e6\u5916\u8fd8\u6709\u4e2a\u548cVSYNC\u6ca1\u6709\u5173\u7cfb\uff0c\u4f46\u662f\u5374\u5728\u8fd9\u91cc\u51fa\u73b0\u7684\u4e00\u4e2a\u5c31\u662fonHotplugReceived\uff0c\u5c31\u662f\u4f60\u7684\u5916\u63a5\u6216\u8005\u865a\u62df\u663e\u793a\u5668\u88ab\u62d4\u6389\u6216\u8005\u63a5\u4e0a\u4f1a\u53d1\u751f\u7684\u4e8b\u4ef6\uff0c\u8fd9\u91cc\u7684\u8bdd\u62d4\u6389\u4f1a\u5bfc\u81f4\u4ece\u786c\u4ef6VSYNC\u5207\u6362\u56de\u8f6f\u4ef6\u65b9\u5f0f\uff0c\u63a5\u4e0a\u7684\u8bdd\u53c8\u4f1a\u4ece\u8f6f\u4ef6\u5207\u6362\u56de\u786c\u4ef6\u7684\u65b9\u5f0f\uff0c\u603b\u4e4b\u8fd9\u91cc\u4f18\u5148\u4f7f\u7528\u786c\u4ef6\u65b9\u5f0f\u3002<\/p>\n<p>IDisplayEventConnection\u662f\u5ba2\u6237\u7aef\u7528\u6765\u548cSurfaceFlinger\u505aVSYNC\u6c9f\u901a\u7684\u901a\u9053\uff0c\u5229\u7528Binder\u5b9e\u73b0\uff0c\u6bd4\u5982setVsyncRate\/requestNextVsync\/getDataChannel\u8fd9\u4e9b\u65b9\u6cd5\uff0c\u4ece\u5b57\u9762\u610f\u601d\u5c31\u6bd4\u8f83\u5bb9\u6613\u7406\u89e3\u51fa\u8fd9\u51e0\u4e2a\u65b9\u6cd5\u7684\u542b\u4e49\uff0cset\u5c31\u8bbe\u7f6eVSYNC\u4e8b\u4ef6\u88ab\u901a\u77e5\u7684\u9891\u7387\uff0crequest\u5c31\u662f\u624b\u52a8\u8bf7\u6c42\u4e00\u6b21VSYNC\u4e8b\u4ef6\uff0cdata channel\u5c31\u662f\u83b7\u53d6\u6570\u636e\u4f20\u9012\u7684\u901a\u9053\uff0c\u8fd9\u91cc\u662fBitTube\u5b9e\u73b0\uff0c\u5b83\u662f\u4e00\u4e2a\u5229\u7528Socket\u5b9e\u73b0\u7684\u8de8\u8fdb\u7a0b\u901a\u4fe1\u7684\u7ba1\u9053\uff0c\u5e76\u4e14\u4f60\u53ef\u4ee5\u5728\u5b83\u4e0a\u9762\u6ce8\u518c\u611f\u5174\u8da3\u7684\u4e8b\u4ef6\uff0c\u5f53\u4e8b\u4ef6\u5230\u6765\u65f6\u5019\uff0c\u5b83\u901a\u77e5\u4f60(\u5229\u7528epoll\u5b9e\u73b0)\u3002<br \/>\n\u6240\u4ee5\u6bcf\u4e2a\u5ba2\u6237\u7aef\u53ef\u4ee5\u9009\u62e9\u81ea\u5df1\u8981\u7684VYSNC\u7684\u4e8b\u4ef6\u7684\u9891\u7387\uff0c\u7136\u540e\u5c31\u6536\u542c\u4e8b\u4ef6\u901a\u77e5\u5c31\u53ef\u4ee5\u4e86\uff0cJava\u5c42\u7684Choreographer\u5c31\u662f\u5229\u7528\u8fd9\u4e2a\u5b9e\u73b0\u7684\u3002\u6211\u4eec\u8981\u6307\u5bfc\u8fd9\u4e2aIDisplayEventConnection\u662f\u53ef\u4ee5\u6709\u591a\u4e2a\u7684\uff0c\u6bd4\u5982View\u7cfb\u7edf\u6216\u8005Animation\u7cfb\u7edf\u90fd\u7528\u5230\u8fd9\u4e2a\uff0c\u6bd4\u5982\u4f60\u81ea\u5df1\u5199\u7684App\u5982\u679c\u4e0d\u7528\u7cfb\u7edfView\/Animation\u76f8\u5173\u7684\uff0c\u4f60\u4e5f\u53ef\u4ee5\u81ea\u5df1\u5229\u7528Choreographer\u6765\u6ce8\u518c\u3002<br \/>\n\u90a3\u73b0\u5728SurfaceFlinger\u662f\u5982\u4f55\u7ba1\u7406\u8fd9\u4e9b\u4e8b\u4ef6\u8bf7\u6c42\u6216\u8005\u76d1\u542c\u901a\u77e5\u7684\u5462\uff1f<br \/>\n\u901a\u8fc7EventThread\uff0c\u8fd9\u662f\u4e00\u4e2a\u666e\u901a\u7684Thread\uff0c\u5ba2\u6237\u7aef\u6bcf\u8c03\u7528\u4e00\u6b21SurfaceFlinger\u7684createDisplayEventConnection\u5c31\u4f1a\u521b\u5efa\u4e00\u4e2aConnection\uff0c\u968f\u540e\u88ab\u52a0\u5165\u5230EventThreade\u5f53\u4e2d\u7684mDisplayEventConnections\uff0c\u5e76\u89e6\u53d1\u8fd9\u4e2a\u7ebf\u7a0b\u7684threadLoop\u6765\u6267\u884c(\u6ca1\u6709\u4e8b\u4ef6\u9700\u8981\u6267\u884c\u7684\u65f6\u5019\uff0c\u8be5\u7ebf\u7a0b\u662f\u7761\u7720\u72b6\u6001\uff0c\u56e0\u4e3awaitForEvent\u65b9\u6cd5\u91cc\u9762\u6709wait)\uff0c\u6700\u540e\u5c06\u7ed3\u679c\u901a\u8fc7postEvent\u63d0\u4ea4\u7ed9BitTupe\uff0c\u8fd9\u6837\u4e4b\u524d\u6709\u5728\u4e0a\u9762\u6ce8\u518c\u4e8b\u4ef6\u76d1\u542c\u7684\u5c31\u4f1a\u6536\u5230\u5bf9\u5e94\u7684\u4e8b\u4ef6\u3002<br \/>\n\u8be6\u7ec6\u7684\u4ee3\u7801\u5206\u6790\u8bf7\u53c2\u89c1(<a href=\"https:\/\/github.com\/guohai\/and-notes\/tree\/master\/surfaceflinger-jb-4.2\" target=\"_blank\">https:\/\/github.com\/guohai\/and-notes\/tree\/master\/surfaceflinger-jb-4.2<\/a>)\u4e2d\u6587\u6ce8\u91ca\/\u53ef\u80fd\u4e5f\u6709\u5c11\u90e8\u5206\u662f\u6211\u6dfb\u52a0\u7684\u82f1\u6587\u6ce8\u91ca\u3002<\/p>\n<p>\u6742\u9879\uff1a<br \/>\n\u53e6\u5916FrameBufferNativeWindow\u5df2\u7ecf\u4e0d\u518d\u88ab\u4f7f\u7528\u4e86\u3002<\/p>\n<p>\u6211\u4eec\u901a\u5e38\u8bf4\u5728\u65b0\u7684\u652f\u6301\u786c\u4ef6\u52a0\u901f\u7684\u8bbe\u5907\u548c\u7cfb\u7edf\u4e0a\uff0c\u6211\u4eec\u503e\u5411\u4e8e\u4f7f\u7528TextureView\u6765\u66ff\u4ee3SurfaceView\uff0c\u8fd9\u91cc\u9762\u53c8\u662f\u4ec0\u4e48\u539f\u56e0\u5462\uff1f<br \/>\n\u90fd\u77e5\u9053SurfaceView\u4f1a\u5355\u72ec\u521b\u5efa\u4e00\u4e2aSurface\uff0c\u5728SurfaceFlinger\u5f53\u4e2d\u7684\u4f53\u73b0\u4e5f\u662f\u591a\u521b\u5efa\u4e00\u4e2aLayer\uff0c\u7136\u540e\u4e0e\u539f\u6709\u7684\uff0c\u6bd4\u5982Window\/Status Bar\u7b49\u7b49\u8fd9\u4e9bLayer\u5408\u5e76\u4e4b\u540e\u518d\u5728display\u4e0a\u753b\u51fa\u6765\u3002<br \/>\n\u90a3\u4f7f\u7528TextureView\u5c31\u4e0d\u4f1a\u6709\u8fd9\u4e48\u4e00\u4e2a\u8fc7\u7a0b\u5417\uff1f\u662f\u7684\uff0c\u56e0\u4e3aTextureView\u91cc\u9762\u5229\u7528\u4e86SurfaceTexture\uff0cSurfaceTexture\u7684\u521b\u5efa\u4e0d\u4f1a\u5bfc\u81f4SurfaceFlinger\u4e2d\u591a\u51fa\u6765\u4e00\u4e2aLayer\uff0c\u56e0\u4e3a\u5b83\u662f\u4f7f\u7528\u786c\u4ef6\u6765\u505a\u7684\uff0c\u6240\u4ee5TextureView\u5fc5\u987b\u662f\u652f\u6301\u786c\u4ef6\u52a0\u901f\uff0c\u5e76\u4e14\u5f00\u542f\u7684\u60c5\u51b5\u4e0b\u624d\u80fd\u4f7f\u7528\uff0c\u5426\u5219\u5b83\u4ec0\u4e48\u4e5f\u505a\u4e0d\u4e86\u3002\u4f46\u662f\u5b83\u8fd8\u662f\u4f1a\u521b\u5efa\u4e00\u4e2aLayer\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u4e2aLayer\u662f\u786c\u4ef6\u6765\u521b\u5efa\uff0c\u7ba1\u7406\uff0c\u90a3\u8f6f\u4ef6\u5c42\u9762\u5c31\u4e0d\u7528\u82b1\u8fd9\u4e2a\u529f\u6765\u505a\u8fd9\u4ef6\u4e8b\u60c5\u3002Native\u5c42\u7684SurfaceTexture(ConsumerBase)\u5b83\u8d1f\u8d23\u63a5\u6536\u8fc7\u6765\u7684\u6570\u636e\uff0c\u7136\u540e\u901a\u8fc7JNI\u5f80\u4e0a\u4f20View\u5c42\uff0c\u8f6f\u4ef6\u5c42\u9762\u7684\u5de5\u4f5c\u5c31\u7ed3\u675f\u4e86\u3002<\/p>\n<p>P.S. \u8be6\u7ec6\u4fe1\u606f\u5f85\u8865\u5145<\/p>\n<\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>&lt;p&gt;\u9488\u5bf9Jelly Bean\u7248\u672c\u7684\u4ee3\u7801\u3002&lt;br \/&gt; SurfaceFlinger\u662f\u4ec0\u4e48\uff0c\u8fd9\u4e9b\u4ecb\u7ecd\u5927\u5bb6\u53ef\u4ee5\u5728\u7f51\u7edc\u4e0a\u627e\u627e\u770b\uff0c\u8fd9\u91cc\u5c31\u76f4\u63a5\u4e0a\u4ee3\u7801\u3002&lt;\/p&gt; &lt;p&gt;\u9996\u5148\u6211\u4eec\u5f97\u4e86\u89e3\u4e00\u79cd\u5e38\u7528\u7684\u7f16\u7a0b\u505a\u6cd5\uff0c\u751f\u4ea7\u8005\/\u6d88\u8d39\u8005\u6a21\u578b\uff0c\u4e5f\u8bb8\u90fd\u4f1a\u89c9\u5f97\u5f88\u7b80\u5355\uff0c\u4f46\u662f\u8fd9\u91cc\u5c31\u7528\u5230\u4e86\u5f88\u591a\u8fd9\u4e9b\u57fa\u672c\u6982\u5ff5\u3002&lt;br \/&gt; BufferQueue \u6570\u636e\u90fdqueue\u5230\u8fd9\u91cc\u9762\uff0c\u524d\u63d0\u662f\u5b83\u662f\u5148\u4eceBufferQueue\u53d6\u51fa\u4e00\u4e2a\u7a7a\u7684\u6570\u636e\u5355\u5143\uff0c\u79f0\u4e3a\u4e00\u4e2abuffer\uff0c\u5b9e\u9645\u4e3aGraphicBuffer\u7c7b\u578b\u3002&lt;\/p&gt; &lt;p&gt;ConsumerBase \u5b83\u662f\u6d88\u8d39\u8005\u7aef\u4f7f\u7528\u7684\u63a5\u53e3\uff0c\u5b83\u5b9e\u73b0\u4e86BufferQueue::ConsumerListener\u63a5\u53e3\uff0c\u4e5f\u5c31\u662fBufferQueue\u5f53\u4e2d\u6709buffer\u88abqueue\u7684\u65f6\u5019\uff0c\u5b83\u80fd\u88ab\u901a\u77e5\u5230(onFrameAvailable)\u3002\u540c\u7406\u5f53\u751f\u4ea7\u8005disconnect\u4e0eBufferQueue\u7684\u8fde\u63a5\u6216\u8005setBufferCount\u88ab\u8c03\u7528(\u8be5\u65b9\u6cd5\u91ca\u653e\u6389\u6240\u6709buffer\uff0c\u8ba9buffer\u90fd\u5f52BufferQueue\u6240\u6709\uff0c\u5982\u679c\u6709buffer\u5904\u4e8eDEQUEUED\u72b6\u6001\uff0c\u6b64\u65b9\u6cd5\u8fd4\u56de\u9519\u8bef)\uff0c\u5b83\u4e5f\u4f1a\u88ab\u901a\u77e5\u5230(onBuffersReleased)\u3002&lt;\/p&gt; &lt;p&gt;BufferItemConsumer\u548cCpuConsumer \u5b83\u4eec\u90fd\u662fConsumerBase\u7684\u5b50\u7c7b\uff0cBufferItemConsumer\u4e00\u6b21\u53ef\u4ee5acquire\u591a\u4e2abuffer\uff0cConsumerBase\u4e00\u6b21\u53ea\u80fd\u4e00\u4e2a\uff0cBufferItemConsumer\u662f\u4fee\u6539\u4e86BufferQueue\u7684mMaxAcquiredBufferCount\u53c2\u6570\uff0cConsumerBase\u4f7f\u7528\u7684\u9ed8\u8ba4\u503c1\u3002CpuBuffer\u53ef\u4ee5\u628abuffer\u9501\u8d77\u6765\u4f9bCPU\u4f7f\u7528\uff0c\u5b83\u4e5f\u662f\u8c03\u7528GRALLOC\u7684\u65b9\u6cd5\u6765\u5b8c\u6210\u8fd9\u4e2a\u529f\u80fd\u7684\u3002&lt;br \/&gt; FramebufferSurface ConsumerBase\u7684\u5b50\u7c7b\uff0c\u4f1a\u628a\u6536\u5230\u7684\u6570\u636e\u901a\u8fc7HWComposer\u5f80\u8367\u5e55\u4e0a\u8d34\u3002&lt;br \/&gt; SurfaceTexture ConsumerBase\u7684\u5b50\u7c7b\uff0c\u5b83\u53ef\u4ee5\u628aGraphicBuffer\u8f6c\u6362\u6210texture image\uff0c\u7136\u540e\u4ea4\u7ed9OpenGL\u3002&lt;\/p&gt; &lt;p&gt;SurfaceTextureLayer\u662f\u4e00\u4e2a\u5b9a\u5236\u5316\u7684BufferQueue\uff0cNATIVE_WINDOW_API_MEDIA\/NATIVE_WINDOW_API_CAMERA\u8fc7\u6765\u7684\u8bf7\u6c42\u4f1a\u628aBufferQueue\u8bbe\u7f6e\u4e3a\u5f02\u6b65\u6a21\u5f0f\u3002&lt;\/p&gt; &lt;p&gt;BufferQueue\u5f53\u4e2dbuffer\u7684\u72b6\u6001\uff0c\u8fd9\u4e2a\u5f88\u7b80\u5355\uff0c\u4f46\u662f\u4e5f\u5f88\u91cd\u8981\u3002&lt;\/p&gt; &lt;pre class=&quot;brush: java; title: ; notranslate&quot; title=&quot;&quot;&gt;\/\/ BufferState represents the different states in which a buffer slot \/\/ can be. enum BufferState { \/\/ FREE indicates that the buffer is not currently being used &hellip; <a href=\"https:\/\/guoh.ai\/lifelog\/2013\/08\/skeleton-of-surfaceflinger\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">SurfaceFlinger\u6e90\u7801\u5206\u6790<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_gfmr_meta_descriptions":[],"_gfmr_multilingual_taxonomy_terms":[],"footnotes":""},"categories":[7,28,34],"tags":[32],"class_list":["post-695","post","type-post","status-publish","format-standard","hentry","category-android","category-cpp","category-multimedia","tag-gfx"],"_links":{"self":[{"href":"https:\/\/guoh.ai\/lifelog\/wp-json\/wp\/v2\/posts\/695","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/guoh.ai\/lifelog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/guoh.ai\/lifelog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/guoh.ai\/lifelog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/guoh.ai\/lifelog\/wp-json\/wp\/v2\/comments?post=695"}],"version-history":[{"count":9,"href":"https:\/\/guoh.ai\/lifelog\/wp-json\/wp\/v2\/posts\/695\/revisions"}],"predecessor-version":[{"id":815,"href":"https:\/\/guoh.ai\/lifelog\/wp-json\/wp\/v2\/posts\/695\/revisions\/815"}],"wp:attachment":[{"href":"https:\/\/guoh.ai\/lifelog\/wp-json\/wp\/v2\/media?parent=695"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/guoh.ai\/lifelog\/wp-json\/wp\/v2\/categories?post=695"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/guoh.ai\/lifelog\/wp-json\/wp\/v2\/tags?post=695"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}