private static void destroyResources(View view) { view.destroyHardwareResources(); if (view instanceof ViewGroup) { ViewGroup group = (ViewGroup) view; int count = group.getChildCount(); for (int i = 0; i < count; i++) { destroyResources(group.getChildAt(i)); } } }
@Override boolean draw( View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) { if (canDraw()) { if (!hasDirtyRegions()) { dirty = null; } attachInfo.mIgnoreDirtyState = true; attachInfo.mDrawingTime = SystemClock.uptimeMillis(); view.mPrivateFlags |= View.PFLAG_DRAWN; final int surfaceState = checkCurrent(); if (surfaceState != SURFACE_STATE_ERROR) { HardwareCanvas canvas = mCanvas; attachInfo.mHardwareCanvas = canvas; if (mProfileEnabled) { mProfileLock.lock(); } // We had to change the current surface and/or context, redraw everything if (surfaceState == SURFACE_STATE_UPDATED) { dirty = null; beginFrame(null); } else { int[] size = mSurfaceSize; beginFrame(size); if (size[1] != mHeight || size[0] != mWidth) { mWidth = size[0]; mHeight = size[1]; canvas.setViewport(mWidth, mHeight); dirty = null; } } int saveCount = 0; int status = DisplayList.STATUS_DONE; try { view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED) == View.PFLAG_INVALIDATED; view.mPrivateFlags &= ~View.PFLAG_INVALIDATED; long getDisplayListStartTime = 0; if (mProfileEnabled) { mProfileCurrentFrame += PROFILE_FRAME_DATA_COUNT; if (mProfileCurrentFrame >= mProfileData.length) { mProfileCurrentFrame = 0; } getDisplayListStartTime = System.nanoTime(); } canvas.clearLayerUpdates(); DisplayList displayList; Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList"); try { displayList = view.getDisplayList(); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareFrame"); try { status = onPreDraw(dirty); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } saveCount = canvas.save(); callbacks.onHardwarePreDraw(canvas); if (mProfileEnabled) { long now = System.nanoTime(); float total = (now - getDisplayListStartTime) * 0.000001f; //noinspection PointlessArithmeticExpression mProfileData[mProfileCurrentFrame] = total; } if (displayList != null) { long drawDisplayListStartTime = 0; if (mProfileEnabled) { drawDisplayListStartTime = System.nanoTime(); } Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList"); try { status |= canvas.drawDisplayList( displayList, mRedrawClip, DisplayList.FLAG_CLIP_CHILDREN); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } if (mProfileEnabled) { long now = System.nanoTime(); float total = (now - drawDisplayListStartTime) * 0.000001f; mProfileData[mProfileCurrentFrame + 1] = total; } handleFunctorStatus(attachInfo, status); } else { // Shouldn't reach here view.draw(canvas); } } finally { callbacks.onHardwarePostDraw(canvas); canvas.restoreToCount(saveCount); view.mRecreateDisplayList = false; mFrameCount++; if (mDebugDirtyRegions) { if (mDebugPaint == null) { mDebugPaint = new Paint(); mDebugPaint.setColor(0x7fff0000); } if (dirty != null && (mFrameCount & 1) == 0) { canvas.drawRect(dirty, mDebugPaint); } } } onPostDraw(); attachInfo.mIgnoreDirtyState = false; if ((status & DisplayList.STATUS_DREW) == DisplayList.STATUS_DREW) { long eglSwapBuffersStartTime = 0; if (mProfileEnabled) { eglSwapBuffersStartTime = System.nanoTime(); } sEgl.eglSwapBuffers(sEglDisplay, mEglSurface); if (mProfileEnabled) { long now = System.nanoTime(); float total = (now - eglSwapBuffersStartTime) * 0.000001f; mProfileData[mProfileCurrentFrame + 2] = total; } checkEglErrors(); } if (mProfileEnabled) { mProfileLock.unlock(); } return dirty == null; } } return false; }