الروبوت فهم الأجهزة مبدأ التسارع من الورق الأبيض

تسريع الأجهزة، حدسي، وهذا هو ل الرسومات المتسارع يجعل تنفيذ GPU تعتمد والفرق الرئيسي بين الأجهزة والبرمجيات يتسارع الرسومات GPU تقديم للتعامل مع ما هو، أو وحدة المعالجة المركزية إذا كان GPU، ويعتبر أن تكون الأجهزة تسارع تقديم، في حين أن تقديم البرامج. وينطبق الشيء نفسه في الروبوت، ولكن نسبة إلى متوسط تقديم البرامج، تسارع تفعل أيضا جوانب أخرى من التحسين، لا تقتصر فقط من حيث الرسم قبل أن ترسم، وكيفية بناء على المنطقة الرسم، كما قدم عظيم الأمثل تسريع الأجهزة، قد يتم تحليلها وبالتالي خصائص تسارع من جزأين التالية:

  • 1، واستراتيجية مبكرة: كيفية بناء احتياجات المنطقة المراد رسمها
  • 2، بعد التعادل: وموضوع التقديم منفصل، تعتمد على GPU للرسم

سواء كانت برامج أو تسارع الأجهزة تقديم، رسم تخصيص الذاكرة متشابهة، هي الحاجة إلى تخصيص كتلة من الذاكرة طلبات الخدمات إلى SurfaceFlinger، ولكن تسارع ممكن مباشرة من مخازن الأجهزة مخزن الإطار المؤقت تخصيص الذاكرة (إلى SurfaceFlinger كان ذلك الجاف)، وهما يتم رسمها في APP في النهاية، بعد تعادله الانتهاء إخطار إلى SurfaceFlinger تحتاج أيضا إلى إعادة تصنيعه، وليس هناك فرق في هذه العملية، الفرق الحقيقي هو في كيفية رسم البيانات في نهاية كاملة APP UI ، فهم بديهية من هذه الورقة تحت الفرق بين الاثنين، وسوف تشمل جزءا من شفرة المصدر، ولكن من دون فهم.

نقاط تسارع الخلاف

ربما من الروبوت 4. + البدء، افتراضيا، معتمدة مع تسارع تشغيل، وهناك أيضا يدعم الهاتف تسريع الأجهزة، ولكن جزءا من API لا يدعم تسريع الأجهزة، إذا كان استخدام هذه API، تحتاج إلى إيقاف تسارع الرئيسي ، عرض طبقة أو طبقات آخر، مثل قماش clipPath مثل. أو ومع ذلك، عرض الرسم هو برنامج أو جهاز تسريع تسريع، وعادة لا مرئية في تطوير الرسومات تقديم ذلك الوقت، والاختلافات بين الأجهزة والبرمجيات نقطة أين هو؟ على سبيل المثال، هناك حاجة لإعادة رسم عرض، داعيا عموما عرض، يبطل، إعادة رسم اثار، اتبع هذا الذهاب الخط، انتقل نقاط التفتيش الخلاف.

مشاهدة إعادة الرسم

وكما يتبين من تدفق دعوة أعلاه، واخيرا يدخل في عرض لإعادة رسم رسم ViewRootImpl، هناك تتسارع نقطة قرار نقطة الأجهزة الاختلاف، ما يلي مبسط

ViewRootImpl.java

تعادل باطلة الخاص (منطقية fullRedrawNeeded) { ... إذا (! dirty.isEmpty () || mIsAnimating || accessibilityFocusDirty) { < ! - تشغيل مفتاح تسريع 1 الأجهزة على - > إذا (mAttachInfo.mHardwareRenderer! = فارغة && mAttachInfo.mHardwareRenderer.isEnabled ()) { ... dirty.setEmpty ()؛ mBlockResizeBuffer = كاذبة؛ < ! - مفتاح 2 الأجهزة تسارع تقديم - > mAttachInfo.mHardwareRenderer.draw (mView، mAttachInfo، هذا)؛ } {شيء آخر ... < ! - برنامج مفتاح رسم 3 - > إذا (! drawSoftware (السطح، mAttachInfo، xOffset، yOffset، scalingRequired وقذرة)) { العودة؛ } ...

1 والنقطة الأساسية هي لتمكين الظروف تسريع الأجهزة، والأجهزة يجب أن تدعم تسريع الأجهزة قيد التشغيل قبل أن يتمكنوا من تلبية، على استخدام HardwareRenderer.draw، وإلا drawSoftware (البرنامج تقديم). القصير نظرة الجواب في هذه الحالة، افتراضيا، هذا الشرط صحيحا، لأنه بعد 4 + الهواتف عموما دعم تسريع الأجهزة، ولكن أيضا في إضافة نافذة عندما سوف ViewRootImpl enableHardwareAcceleration تسارع مفتوحة، HardwareRenderer جديدة، وتهيئة الأجهزة بيئة متسارعة.

enableHardwareAcceleration الفراغ الخاص (WindowManager.LayoutParams attrs) { < ! - تكوين مفتاح تسريع الأجهزة المكتسبة - > // في محاولة لتمكين تسارع إذا طلب نهائي منطقية hardwareAccelerated = ! (Attrs.flags وWindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) = 0؛ إذا (hardwareAccelerated) { ... < ! - تسارع الأجهزة الجديدة العارض الرسومات - > mAttachInfo.mHardwareRenderer = HardwareRenderer.create (mContext، شفافة)؛ إذا (mAttachInfo.mHardwareRenderer! = فارغة) { mAttachInfo.mHardwareRenderer.setName (attrs.getTitle () toString ())؛ mAttachInfo.mHardwareAccelerated = mAttachInfo.mHardwareAccelerationRequested = صحيح. } ...

في الواقع، وهنا مع وجدت جعلها نقطة البرمجيات الخلاف تسارع الأجهزة، هو ViewRootImpl في السحب عندما، إذا اقتضى الأمر تسارع الأجهزة على استخدام HardwareRenderer رسم، رسم أو اتخاذ عملية البرمجيات، drawSoftware هو في الواقع بسيط جدا، واستخدام Surface.lockCanvas، إلى إلى SurfaceFlinger طلب للحصول على تخصيص الذاكرة الذاكرة المشتركة مجهول، في نفس الوقت الحصول على SkiaCanvas عادية، داعيا للمكتبات باسم Skia، والرسومات وجعلها،

خاص drawSoftware منطقية (سطح سطح، AttachInfo attachInfo، XOFF كثافة العمليات، يوف كثافة العمليات، منطقية scalingRequired، مصحح القذرة) { قماش قماش النهائي؛ محاولة { < ! - مفتاح نقطة 1 - > قماش = mSurface.lockCanvas (القذرة)؛ .. < ! - مفتاح رسم 2 - > mView.draw (قماش)؛ .. طبقات يتم توليفها إخطار إلى SurfaceFlinger 3 نقاط رئيسية surface.unlockCanvasAndPost (قماش)؛ ...} العودة الحقيقية؛}

العمل drawSoftware به بالكامل من قبل وحدة المعالجة المركزية، وGPU لا تنطوي العملية، ركز الأجهزة التالية نظرة أجريت HardwareRenderer المتسارع التقديم.

تسارع الأجهزة HardwareRenderer تقديم نموذج

وقال في بداية، وجعلها تسارع الأجهزة يتكون من مرحلتين: مرحلة البناء + رسم المرحلة، هو بناء واستخدام برنامج OpenGL الموضوع تقديم ما يسمى متكرر اجتياز جميع وجهات النظر، وتتطلب العملية مؤقتا، ثم مرة أخرى لفصل التقديم. تسارع الروبوت في الإطار، وتستخرج الرأي في RenderNode مشاهدة عقدة، مما يجعل عرض وسوف تستخرج في واحدة DrawOp (DisplayListOp)، كما هو الحال في drawLine عرض، سيتم استخراجها الإنشاء إلى DrawLintOp، قد تكون الإجراءات drawBitmap المستخرجة في DrawBitmapOp، مما يجعل كل الفرعية مشاهدة تستخرج في DrawRenderNodeOp، كل لديه DrawOp برنامج OpenGL المقابلة القيادة رسم، في حين أيضا عقد البيانات الداخلية اللازمة لرسم. على النحو التالي:

الرسم التجريدي المرجع

ذلك لأن كل عرض ليس فقط سيطرتهم قائمة DrawOp الخاصة، في حين عقد أيضا مشاهدة رسم طفل من المدخل، حتى العودية، سوف تكون قادرة على الاعتماد كل أب اللوحة، العديد من المحللين ودعا قائمة العرض، شفرة المصدر وسميت بهذا الاسم الطبقة، ولكن هناك في الواقع أكثر مثل شجرة بدلا من قائمة، تشير إلى ما يلي:

تسارع .JPG

بعد بناء كاملة، يمكنك استخدام هذه الشجرة لرسم أب تجعل موضوع رسم هنا هو نفس البرنامج لرسم مكانا مختلفا جدا عندما عرض البرنامج، مشاهدة الرسم النهائي عموما في موضوع الرئيسي، وتسريع الأجهزة، ما لم الاحتياجات الخاصة، عادة الانتهاء من رسم في موضوع مستقل، وذلك منذ الترابط الرئيسي للمشاركة في الكثير من الضغط لتحسين سرعة استجابة موضوع UI.

الأجهزة نموذج تسريع .JPG

معرفة كل نموذج، وأنه هو رمز بسيط لفهم عملية التنفيذ، وتبدو تحت الشجرة وبشكل متكرر بناء مجموعة RenderNode DrawOp.

مجموعة البناء DrawOp باستخدام HardwareRenderer

HardwareRenderer تسارع الأجهزة كله جعل من المدخل، هو ThreadedRenderer تحقيق الكائن، فإنه يتبين من اسمها، ThreadedRenderer يجب أن تكون مرتبطة بشكل وثيق مع تجعل موضوع، ولكن يتم إنشاء ThreadedRenderer على موضوع UI، يعتبر أيضا أنها كانت تتعلق موضوع UI، ودورها الرئيسي :

  • 1، DrawOp كاملة بناء المنصوص عليها في موضوع UI
  • 2، المسؤولة عن التواصل مع موضوع التقديم

ThreadedRenderer دورا بارزا مهم جدا، مجرد إلقاء نظرة على التنفيذ:

ThreadedRenderer (السياق السياق، شفافة منطقية) { ... < ! - node-- مواطن جديد > منذ فترة طويلة rootNodePtr = nCreateRootRenderNode ()؛ mRootNode = RenderNode.adopt (rootNodePtr)؛ mRootNode.setClipToBounds (كاذبة)؛ < ! - NativeProxy-- جديد > mNativeProxy = nCreateProxy (شفافة، rootNodePtr)؛ ProcessInitializer.sInstance.init (السياق، mNativeProxy)؛ loadSystemProperties ()؛ }

يتضح من رمز أعلاه، ThreadedRenderer هناك كله DrawOp RootNode تستخدم لتحديد جذر الشجرة، هناك عقدة الجذر يمكن الوصول إلى كافة رسم أب، فضلا عن وجوه RenderProxy، والذي يستخدم الآن لجعل موضوع التعامل مع الاتصالات، والنظر في المنشئ الخاص به:

RenderProxy :: RenderProxy (منطقي شفافة، RenderNode * rootRenderNode، IContextFactory * contextFactory) : MRenderThread (RenderThread :: getInstance ()) ، MContext (nullptr) { SETUP_TASK (createContext)؛ args- > شفافة = شفافة. args- > rootRenderNode = rootRenderNode. args- > خيط = & mRenderThread. args- > contextFactory = contextFactory. mContext = (CanvasContext *) postAndWait (مهمة)؛ mDrawFrameTask.setContext (& mRenderThread، mContext)؛ }

كما يمكن أن يرى من RenderThread :: getInstance ()، RenderThread هو الخيط المفرد، وهذا هو، كل العملية فقط تصل إلى الأجهزة موضوع التقديم، لذلك لن يكون هناك صراعات متعددة الخيوط الوصول المتزامنة، هنا في الواقع البيئة الأجهزة التقديم وقد شكلت بيئة جيدة. هنا ثم ننظر ThreadedRenderer وظيفة التعادل، وكيفية بناء شجرة تقديم أب:

Override تعادل باطل (عرض، AttachInfo attachInfo، الاسترجاعات HardwareDrawCallbacks) { attachInfo.mIgnoreDirtyState = صحيح. نهائي مصمم الرقص مصممة الرقصات = attachInfo.mViewRootImpl.mChoreographer. choreographer.mFrameInfo.markDrawStart ()؛ < ! - مفتاح 1: بناء مشاهدة شجرة DrawOp - > updateRootDisplayList (عرض، الاسترجاعات)؛ < ! - مفتاح 2: إعلام رسم موضوع RenderThread - > الباحث syncResult = nSyncAndDrawFrame (mNativeProxy، frameInfo، frameInfo.length)؛ ... }

نهتم فقط النقاط الرئيسية 1 updateRootDisplayList، بناء RootDisplayList، في الواقع، وبناء مشاهدة شجرة DrawOp، سوف updateRootDisplayList بدوره يدعو مشاهدة الجذرية للupdateDisplayListIfDirty، دعونا مشاهدة الطفل العودية updateDisplayListIfDirty، من أجل استكمال إنشاء شجرة DrawOp، عملية لفترة وجيزة:

updateRootDisplayList الخاص الفراغ (عرض، HardwareDrawCallbacks الاسترجاعات) { < ! - تحديث - > updateViewTreeDisplayList (عرض)؛ إذا (mRootNodeNeedsUpdate ||! mRootNode.isValid ()) { < ! - الحصول على DisplayListCanvas-- > DisplayListCanvas قماش = mRootNode.start (mSurfaceWidth، mSurfaceHeight)؛ محاولة { < ! - استخدام قماش مخبأ Op-- > الباحث النهائي saveCount = canvas.save ()؛ canvas.translate (mInsetLeft، mInsetTop)؛ callbacks.onHardwarePreDraw (قماش)؛ canvas.insertReorderBarrier ()؛ canvas.drawRenderNode (view.updateDisplayListIfDirty ())؛ canvas.insertInorderBarrier ()؛ callbacks.onHardwarePostDraw (قماش)؛ canvas.restoreToCount (saveCount)؛ mRootNodeNeedsUpdate = كاذبة؛ } وأخيرا { < ! - شغل كل أب RootRenderNode-- > mRootNode.end (قماش)؛ } } }
  • مع إطلالة على RenderNode الحصول على DisplayListCanvas
  • DisplayListCanvas استخدامها لبناء وتخزين جميع DrawOp
  • ذاكرة التخزين المؤقت DisplayListCanvas DrawOp شغل RenderNode
  • قدمت عرض مخبأ الجذر DrawOp RootRenderNode إلى بناء كامل

رسم عملية

ببساطة ننظر عرض العودية بناء DrawOp، وملء بأنفسهم

 NonNull الجمهور RenderNode updateDisplayListIfDirty () { نهائي RenderNode renderNode = mRenderNode. ... // بدء الحصول على تسريع الأجهزة لرسم DisplayListCanvas DisplayListCanvas نهائي قماش = renderNode.start (العرض والارتفاع). محاولة { // سواء textureView طبقة HardwareLayer النهائية = getHardwareLayer ()؛ إذا (طبقة! = فارغة && layer.isValid ()) { canvas.drawHardwareLayer (طبقة، 0، 0، mLayerPaint)؛ } آخر إذا (layerType == LAYER_TYPE_SOFTWARE) { // سواء لإجبار البرنامج لرسم buildDrawingCache (صحيح)؛ نقطية مخبأ = getDrawingCache (صحيح)؛ إذا (مخبأ! = فارغة) { canvas.drawBitmap (ذاكرة التخزين المؤقت، 0، 0، mLayerPaint)؛ } } {شيء آخر // ViewGroup إذا فقط، ورسم بأنفسهم دون العودية المباشرة الطفل مشاهدة إذا ((mPrivateFlags وPFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { dispatchDraw (قماش)؛ } {شيء آخر < ! - يطلقون على أنفسهم رسم، إذا كان ViewGroup متكرر دون View-- > رسم (قماش)؛ } } } وأخيرا { < ! - مخبأ بناء Op-- > renderNode.end (قماش)؛ setDisplayListProperties (renderNode)؛ } } العودة renderNode. }

مشاهدة TextureView مع برنامج خاص إلزامية إجراء مقارنات، وهناك معالجة إضافية هنا لا يهمني، تنظر مباشرة في السحب العادي، إذا كان في عرض وظيفة onDraw، وهناك drawLine هنا سوف ندعو DisplayListCanvas وظيفة drawLine، DisplayListCanvas وفئة الرسم RenderNode حول كما يلي

FIG تسارع الطبقة

سوف DisplayListCanvas وظيفة drawLine تدخل في نهاية المطاف drawLine DisplayListCanvas.cpp،

DisplayListCanvas الفراغ :: drawLines (CONST تعويم * نقطة العد كثافة العمليات، CONST SkPaint والطلاء) { نقطة = refBuffer < عوامة > (نقاط، العد)؛ addDrawOp (جديد (الوك ()) DrawLinesOp (نقطة الفرز، refPaint (والطلاء)))؛ }

يمكن أن ينظر إليه هنا شيدت DrawLinesOp، وأضاف إلى قائمة مخبأ DisplayListCanvas للذهاب، حتى نتمكن من استكمال بناء DrawOp شجرة متكررة، واستخدام RenderNode بعد بناء ظيفة النهاية، DisplayListCanvas البيانات المخزنة مؤقتا في RenderNode انتقل إلى:

نهاية باطلة العامة (قماش DisplayListCanvas) { canvas.onPostDraw ()؛ منذ فترة طويلة renderNodeData = canvas.finishRecording ()؛ < ! - سوف DrawOp مؤقتا الذهاب RenderNode - > nSetDisplayListData (mNativeRenderNode، renderNodeData)؛ // قماش الانتعاش قبالة> canvas.recycle ()؛ mValid = صحيح. }

لذلك، فإننا سوف استكمال بناء شجرة DrawOp، بعد استخدام RenderProxy إرسال رسالة إلى RenderThread، طلب موضوع برنامج OpenGL التقديم.

RenderThread لتقديم UI الجرافيك العازلة

بعد الانتهاء DrawOp بناء شجرة، وموضوع UI باستخدام RenderProxy موضوع يرسل طلب مهمة RenderThread DrawFrameTask، RenderThread حتى يستيقظ، بدء تقديم، عملية العامة التالية:

  • أولا، DrawOp الاندماج
  • التالي رسم طبقة خاصة
  • وأخيرا، رسم كل ما تبقى DrawOpList
  • سوف swapBuffers دعوة رسم رسومات جيدة المخزن المؤقت التي سبق تقديمها إلى السطح الساخر التوليف والعرض.

ولكن بعد ذلك قبل أن يصل فرشاة رسم أصل الذاكرة، التي شيدت قبل الشجرة بعد كل DrawOp مجرد ذاكرة مستخدم العادي، وجزء من بيانات إلى SurfaceFlinger غير مرئية، وضعت في وقت لاحق لبيانات الذاكرة المشتركة سيكون إلى SurfaceFlinger التوليف، برامج التحليل قبل أن UI استخلاصها من مجهول الذاكرة المشتركة، لذلك الأجهزة تسارع الذاكرة القادمة من يشارك؟ هنا قد ترغب في العودة ونظرة على ViewRootImlp

performTraversals الفراغ الخاص () { ... إذا (mAttachInfo.mHardwareRenderer! = فارغة) { محاولة { hwInitialized = mAttachInfo.mHardwareRenderer.initialize ( mSurface)؛ إذا (hwInitialized && (host.mPrivateFlags وView.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) { mSurface.allocateBuffers ()؛ } } صيد (OutOfResourcesException ه) { handleOutOfResourcesException (ه)؛ العودة؛ } } .... / ** * تخصيص مخازن في وقت مبكر لتأخير تخصيص تجنب خلال تقديم *Hide * / allocateBuffers الفراغ الجمهور () { تزامن (mLock) { checkNotReleasedLocked ()؛ nativeAllocateBuffers (mNativeObject)؛ } }

كما يمكن أن يرى، على سبيل الأجهزة تسارع المشهد، عندما الفرصة لتخصيص طلب الذاكرة إلى SurfaceFlinger قليلا في وقت سابق، بدلا من تقديم البرامج، التي بدأتها سطح lockCanvas، الأهداف الرئيسية هي: وضع فتحة، لتجنب المخصصة قبل إعادة تطبيق عند تقديم لتجنب فشل تخصيص، مضيعة للعمل تحضيري قبل وحدة المعالجة المركزية، والثاني هو ممكن أيضا لتقديم موضوع العمل على تبسيط وتقليل التأخير. ومع ذلك، لا يزال هناك مشكلة أخرى، وهي عملية APP، مقارنة بنفس الفترة سوف يكون هناك واجهة الرسومات السطح، ولكن فقط موضوع التقديم، ثم ما الذي جعله؟ هذه المرة نحن بحاجة إلى السطح وموضوع تقديم (السياق) ملزمة.

ساكنة jboolean android_view_ThreadedRenderer_initialize (JNIEnv * الحياة الفطرية، jobject clazz، jlong proxyPtr، jsurface jobject) { RenderProxy * وكيل = reinterpret_cast < RenderProxy * > (ProxyPtr)؛ س < ANativeWindow >  نافذة = android_view_Surface_getNativeWindow (الحياة الفطرية، jsurface)؛ العودة proxy- > تهيئة (إطار)؛ }

سطح المكتسبة أول مرة من قبل android_view_Surface_getNativeWindowSurface، وطبقة الأم، السطحية المقابلة لANativeWindow، ثم، وظائف عضو ANativeWindow الطبقة تهيئة RenderProxy الحصول عليها ملزمة سابقا إلى RenderThread

منطقي RenderProxy :: تهيئة (س CONST < ANativeWindow > & نافذة) { SETUP_TASK (تهيئة)؛ args- > السياق = mContext. args- > نافذة = window.get ()؛ عودة (منطقي) postAndWait (مهمة)؛ }

لا يزال يبعث برسالة إلى موضوع التقديم، والسماح للنافذة ملزمة الحالية، في الواقع، والدعوة CanvasContext وظيفة تهيئة، لذلك ذاكرة الرسومات منضمة الرسومات السياق:

منطقي CanvasContext :: تهيئة (ANativeWindow نافذة *) { setSurface (إطار)؛ إذا (mCanvas) عودة كاذبة؛ mCanvas = OpenGLRenderer الجديدة (mRenderThread.renderState ())؛ mCanvas- > initProperties ()؛ العودة الحقيقية. }

CanvasContext setSurface من قبل التيار التي ستقدم السطحية بد أن RenderThread في التدفق العام تحصل عليها EGLSurface eglApi، EGLSurface بتغليف سطح الرسم، وأبعد من ذلك، من قبل مجموعة eglApi EGLSurface تجعل النافذة، ومثل للذاكرة الرسومات الحالية تتم مزامنة المعلومات من خلال الوقت RenderThread بعد تعادله بهدف لمعرفة ما يتم رسمها على النافذة. هنا هو لرسو السفن الرئيسي مع OpenGL المكتبة، في نهاية المطاف أن يعزى جميع العمليات إلى واجهة مجردة eglApi للذهاب. إذا، ليس هذا هو الروبوت، ومنصة جافا المشتركة، ويحتاج أيضا عملية مماثلة، عملية التغليف وملزمة لتقديم EGLSurface الحالية، لأن برنامج OpenGL هو عبارة عن مجموعة من المواصفات، وتريد استخدام، يجب أن تذهب وفقا لهذه المواصفات. ثم، إنشاء كائن OpenGLRenderer الثاني وراء تنفيذ العمليات المتعلقة برنامج OpenGL، عندما، في الواقع، التي تقوم بها OpenGLRenderer.

عملية ملزمة

العملية المذكورة أعلاه الانتهاء، أمر DrawOp tree've بنيت، وكان تخصيص الذاكرة أيضا جيدة، والبيئة ومشاهد ربط ينجح، ويوجه الباقي، لكنه قال من قبل، حقيقي رسم بعض المكالمات برنامج OpenGL قبل عملية الدمج يتم ذلك لتحسين تسارع الروبوت، بدوره حولها ومواصلة اتخاذ عملية القرعة، في الواقع، انتقل drawRenderNode OpenGLRenderer عملية متكررة:

الفراغ OpenGLRenderer :: drawRenderNode (RenderNode * renderNode، مصحح وقذرة، int32_t replayFlags) { ... < ! - بناء deferredList-- > DeferredDisplayList deferredList (mState.currentClipRect ()، avoidOverdraw)؛ DeferStateStruct deferStruct (deferredList، * هذا، replayFlags)؛ < ! - عمليات الاندماج والجماعات - > renderNode- > إرجاء (deferStruct، 0)؛ < ! - رسم layer-- > flushLayers ()؛ startFrame ()؛ < ! - رسم شجرة DrawOp - > deferredList.flush (* هذا وقذرة)؛ ... }

تسارع الأجهزة عملية تقديم

انظروا renderNode- > إرجاء (deferStruct، 0)، عملية الدمج، لا يتم رسم شجرة DrawOp مباشرة، ولكن تنفيذها لأول مرة الأمثل المشترك DeferredDisplayList، وهذا هو الأمثل وسائل تسريع الروبوت الأجهزة المستخدمة، وليس فقط يمكن أن تقلل من الرسم لا لزوم له، ويمكن أيضا أن تكون مركزية ذلك العلاج الرسم مماثلة لتحسين سرعة الرسم.

الفراغ RenderNode :: إرجاء (DeferStateStruct وdeferStruct، ومستوى كثافة CONST) { DeferOperationHandler معالج (deferStruct، ومستوى)؛ issueOperations < DeferOperationHandler > (DeferStruct.mRenderer، معالج)؛ }

RenderNode :: إرجاء يحتوي في الواقع عملية متكررة، على سبيل المثال، إذا كان ممثلو RenderNode الحالية DecorView، فإنه سيتم دمج متكرر كل الفرعي عرض التحسين، وعملية لفترة وجيزة دمج خوارزمية والأمثل، في الواقع، وذلك أساسا لبناء DeferedDisplayList وفقا لشجرة DrawOp ، إرجاء، كانت هناك تأخيرات المتوسط، لDrawOp اندماج اثنين من الشروط الضرورية،

  • 1: يجب أن يكون اثنين DrawOp نفس النوع، عندما تستخرج هذا النوع من الدمج وID دفعة والقيم هي ما يلي:
 التعداد OpBatchId { kOpBatch_None = 0، // لا دفعة kOpBatch_Bitmap، kOpBatch_Patch، kOpBatch_AlphaVertices، kOpBatch_Vertices، kOpBatch_AlphaMaskTexture، kOpBatch_Text، kOpBatch_ColorText، kOpBatch_Count، // اضافة هويات دفعة أخرى قبل هذا }؛
  • 2: يجب أن يكون DrawOp من ID دمج معرف نفسه، دمج لا ضيقة للغاية، وتطويعه من قبل كل قرار DrawOp، ولكن يبدو فقط DrawPatchOp، DrawBitmapOp، DrawTextOp الخاصة، والباقي لا تحتاج إلى النظر يبدو أن الاندماج هو فوق ثلاثة حظة، شروط الاندماج قاسية جدا

في عملية الاندماج، تقسم DrawOp إلى نوعين: الحاجة ولا تحتاج إلى دمج معا، ويتم تخزينها مؤقتا في قوائم مختلفة، لا يمكنك دمج عن طريق نوع كانت مخزنة في الدفعة * mBatchLookup قد تكون مجتمعة وفقا لنوع وMergeID المخزنة TinyHashMap < mergeid_t، DrawBatch * >  mMergingBatches إن الرسم البياني أدناه:

DrawOp .jpg وعمليات الدمج

بعد عملية الدمج، DeferredDisplayList المتجهات < دفعة * >  mBatches بما في ذلك أمر رسم من كل متكامل، بعد تقديم يمكن أن يكون، وتجدر الإشارة إلى أن عملية الدمج ليست أكثر من مجرد تغيير هنا، لا مجرد جمع، وذلك أساسا لتسهيل استخدام مختلف القوام وغيرها من الموارد، مثل الوقت لرسم النص، تحتاج إلى وفقا للنص من تقديم الملمس، ولكن هذه المرة كنت بحاجة إلى إحداثيات نسيج النص الاستعلام، اندمجت معا لتسهيل معاملة موحدة، المقدمة مرة واحدة، والحد من النفايات التحميل الموارد، وبطبيعة الحال، لفهم العملية الشاملة لتسريع الأجهزة، عملية الدمج يمكن تجاهلها تماما حتى حدسي أعتقد، بعد أن كنت قد بنيت، ويمكنك توجيه التقديم، الميزة الرئيسية هي تقديم لرسم موضوع آخر باستخدام برنامج OpenGL، وهذا هو الميزة الأكثر أهمية في . وسيتم اختيار كل DrawOp mBatches في GraphicBuffer بواسطة برنامج OpenGL، وأخيرا التوليف عن طريق الإخطار swapBuffers إلى SurfaceFlinger.

ملخص

تسريعها بالأجهزة تقديم البرامج مع الفرق الرئيسي هو في السحب، وتخصيص الذاكرة عملية الشامل، والتوليف طبقة هو نفسه، ولكن بالمقارنة مع تقديم خوارزمية البرنامج هو أكثر معقولية، في حين باستخدام موضوع تقديم منفصل، مما يقلل من الترابط الرئيسي تسارع الأجهزة العبء.

للاشارة فقط، يرجى تصحيح لي

[المرفقة] المتعلقة العمارة الفيديو

جمع البيانات

ووتش إلكتروني + الخاص الرد، "أندروز البيانات" الوصول الحر!

الروبوت للحصول على الحصول على بنية متطورة المعلومات، وشفرة المصدر والملاحظات والفيديو. UI كبار، وتحسين الأداء، ودورات مهندس معماري، NDK والتنمية الهجينة (ReactNative + Weex) الصغيرة إلكتروني صغير، ممارسة الرفرفة الروبوت المتقدم جميع جوانب تكنولوجيا

وحدة التحكم اللعب: الأكثر وسامة ثقيلة المدفعية تصل، EW بيسبول

الطائرات الاستهلاكية بدون طيار تصميم نظام نقل صورة لبعض من المفتاح | الصعب إنشاء الفئة المفتوحة

شو تشنغ وكانت امرأة غامضة النار وزوجته TAO بين عشية وضحاها قد قال: بدنيا لا يهم

وحدة التحكم اللعب: MG البيون القديم

جيب اللعب آلات البيع، وبيع "مئات الحشرات وليمة"

أوصى خمسة محاكاة ساخرة فرحان من الفيلم، والناس تضحك انفجر!

"ليتل أكاديمية الساحرة"، وأحدث المعلومات: أستاذ لاول مرة كاملة

اللعب وحدة التحكم: HG فرقة القديم من 08ms

MVC، MVP، MVVM، وكيفية اختيار؟

لعب مراقبة الوضع: GK الزئبق وWaye تي

وقال ليزلي ذات مرة: "أنا الإعلانات التجارية، وأكثر من اختيار الفيلم."

الفيلم هو هسياو هسين لعبت الفرنسي يسقط وغونغ لي، وكيل سابق لمدة 35 سنة من نفس الجنس والحب هو محزن جدا