diff options
Diffstat (limited to 'core/java/android/view/View.java')
-rw-r--r-- | core/java/android/view/View.java | 259 |
1 files changed, 135 insertions, 124 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1d19c9b..b54d462 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -56,6 +56,7 @@ import android.os.Parcelable; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.Trace; import android.text.TextUtils; import android.util.AttributeSet; import android.util.FloatProperty; @@ -14405,143 +14406,158 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void buildDrawingCache(boolean autoScale) { if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ? mDrawingCache == null : mUnscaledDrawingCache == null)) { - mCachingFailed = false; + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, + "buildDrawingCache/SW Layer for " + getClass().getSimpleName()); + } + try { + buildDrawingCacheImpl(autoScale); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } + } + } - int width = mRight - mLeft; - int height = mBottom - mTop; + /** + * private, internal implementation of buildDrawingCache, used to enable tracing + */ + private void buildDrawingCacheImpl(boolean autoScale) { + mCachingFailed = false; - final AttachInfo attachInfo = mAttachInfo; - final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired; + int width = mRight - mLeft; + int height = mBottom - mTop; + + final AttachInfo attachInfo = mAttachInfo; + final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired; + + if (autoScale && scalingRequired) { + width = (int) ((width * attachInfo.mApplicationScale) + 0.5f); + height = (int) ((height * attachInfo.mApplicationScale) + 0.5f); + } + + final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor; + final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque(); + final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache; - if (autoScale && scalingRequired) { - width = (int) ((width * attachInfo.mApplicationScale) + 0.5f); - height = (int) ((height * attachInfo.mApplicationScale) + 0.5f); + final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4); + final long drawingCacheSize = + ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize(); + if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) { + if (width > 0 && height > 0) { + Log.w(VIEW_LOG_TAG, "View too large to fit into drawing cache, needs " + + projectedBitmapSize + " bytes, only " + + drawingCacheSize + " available"); } + destroyDrawingCache(); + mCachingFailed = true; + return; + } - final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor; - final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque(); - final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache; + boolean clear = true; + Bitmap bitmap = autoScale ? mDrawingCache : mUnscaledDrawingCache; - final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4); - final long drawingCacheSize = - ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize(); - if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) { - if (width > 0 && height > 0) { - Log.w(VIEW_LOG_TAG, "View too large to fit into drawing cache, needs " - + projectedBitmapSize + " bytes, only " - + drawingCacheSize + " available"); + if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) { + Bitmap.Config quality; + if (!opaque) { + // Never pick ARGB_4444 because it looks awful + // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case + switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) { + case DRAWING_CACHE_QUALITY_AUTO: + case DRAWING_CACHE_QUALITY_LOW: + case DRAWING_CACHE_QUALITY_HIGH: + default: + quality = Bitmap.Config.ARGB_8888; + break; } - destroyDrawingCache(); - mCachingFailed = true; - return; + } else { + // Optimization for translucent windows + // If the window is translucent, use a 32 bits bitmap to benefit from memcpy() + quality = use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; } - boolean clear = true; - Bitmap bitmap = autoScale ? mDrawingCache : mUnscaledDrawingCache; + // Try to cleanup memory + if (bitmap != null) bitmap.recycle(); - if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) { - Bitmap.Config quality; - if (!opaque) { - // Never pick ARGB_4444 because it looks awful - // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case - switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) { - case DRAWING_CACHE_QUALITY_AUTO: - case DRAWING_CACHE_QUALITY_LOW: - case DRAWING_CACHE_QUALITY_HIGH: - default: - quality = Bitmap.Config.ARGB_8888; - break; - } + try { + bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(), + width, height, quality); + bitmap.setDensity(getResources().getDisplayMetrics().densityDpi); + if (autoScale) { + mDrawingCache = bitmap; } else { - // Optimization for translucent windows - // If the window is translucent, use a 32 bits bitmap to benefit from memcpy() - quality = use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; + mUnscaledDrawingCache = bitmap; } - - // Try to cleanup memory - if (bitmap != null) bitmap.recycle(); - - try { - bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(), - width, height, quality); - bitmap.setDensity(getResources().getDisplayMetrics().densityDpi); - if (autoScale) { - mDrawingCache = bitmap; - } else { - mUnscaledDrawingCache = bitmap; - } - if (opaque && use32BitCache) bitmap.setHasAlpha(false); - } catch (OutOfMemoryError e) { - // If there is not enough memory to create the bitmap cache, just - // ignore the issue as bitmap caches are not required to draw the - // view hierarchy - if (autoScale) { - mDrawingCache = null; - } else { - mUnscaledDrawingCache = null; - } - mCachingFailed = true; - return; + if (opaque && use32BitCache) bitmap.setHasAlpha(false); + } catch (OutOfMemoryError e) { + // If there is not enough memory to create the bitmap cache, just + // ignore the issue as bitmap caches are not required to draw the + // view hierarchy + if (autoScale) { + mDrawingCache = null; + } else { + mUnscaledDrawingCache = null; } - - clear = drawingCacheBackgroundColor != 0; + mCachingFailed = true; + return; } - Canvas canvas; - if (attachInfo != null) { - canvas = attachInfo.mCanvas; - if (canvas == null) { - canvas = new Canvas(); - } - canvas.setBitmap(bitmap); - // Temporarily clobber the cached Canvas in case one of our children - // is also using a drawing cache. Without this, the children would - // steal the canvas by attaching their own bitmap to it and bad, bad - // thing would happen (invisible views, corrupted drawings, etc.) - attachInfo.mCanvas = null; - } else { - // This case should hopefully never or seldom happen - canvas = new Canvas(bitmap); - } + clear = drawingCacheBackgroundColor != 0; + } - if (clear) { - bitmap.eraseColor(drawingCacheBackgroundColor); + Canvas canvas; + if (attachInfo != null) { + canvas = attachInfo.mCanvas; + if (canvas == null) { + canvas = new Canvas(); } + canvas.setBitmap(bitmap); + // Temporarily clobber the cached Canvas in case one of our children + // is also using a drawing cache. Without this, the children would + // steal the canvas by attaching their own bitmap to it and bad, bad + // thing would happen (invisible views, corrupted drawings, etc.) + attachInfo.mCanvas = null; + } else { + // This case should hopefully never or seldom happen + canvas = new Canvas(bitmap); + } - computeScroll(); - final int restoreCount = canvas.save(); + if (clear) { + bitmap.eraseColor(drawingCacheBackgroundColor); + } - if (autoScale && scalingRequired) { - final float scale = attachInfo.mApplicationScale; - canvas.scale(scale, scale); - } + computeScroll(); + final int restoreCount = canvas.save(); - canvas.translate(-mScrollX, -mScrollY); + if (autoScale && scalingRequired) { + final float scale = attachInfo.mApplicationScale; + canvas.scale(scale, scale); + } - mPrivateFlags |= PFLAG_DRAWN; - if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated || - mLayerType != LAYER_TYPE_NONE) { - mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID; - } + canvas.translate(-mScrollX, -mScrollY); - // Fast path for layouts with no backgrounds - if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { - mPrivateFlags &= ~PFLAG_DIRTY_MASK; - dispatchDraw(canvas); - if (mOverlay != null && !mOverlay.isEmpty()) { - mOverlay.getOverlayView().draw(canvas); - } - } else { - draw(canvas); + mPrivateFlags |= PFLAG_DRAWN; + if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated || + mLayerType != LAYER_TYPE_NONE) { + mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID; + } + + // Fast path for layouts with no backgrounds + if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { + mPrivateFlags &= ~PFLAG_DIRTY_MASK; + dispatchDraw(canvas); + if (mOverlay != null && !mOverlay.isEmpty()) { + mOverlay.getOverlayView().draw(canvas); } + } else { + draw(canvas); + } - canvas.restoreToCount(restoreCount); - canvas.setBitmap(null); + canvas.restoreToCount(restoreCount); + canvas.setBitmap(null); - if (attachInfo != null) { - // Restore the cached Canvas for our siblings - attachInfo.mCanvas = canvas; - } + if (attachInfo != null) { + // Restore the cached Canvas for our siblings + attachInfo.mCanvas = canvas; } } @@ -15470,10 +15486,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, && mAttachInfo.mHardwareRenderer != null) { mBackgroundRenderNode = getDrawableRenderNode(background, mBackgroundRenderNode); - final RenderNode displayList = mBackgroundRenderNode; - if (displayList != null && displayList.isValid()) { - setBackgroundDisplayListProperties(displayList); - ((HardwareCanvas) canvas).drawRenderNode(displayList); + final RenderNode renderNode = mBackgroundRenderNode; + if (renderNode != null && renderNode.isValid()) { + setBackgroundRenderNodeProperties(renderNode); + ((HardwareCanvas) canvas).drawRenderNode(renderNode); return; } } @@ -15489,14 +15505,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - /** - * Set up background drawable display list properties. - * - * @param displayList Valid display list for the background drawable - */ - private void setBackgroundDisplayListProperties(RenderNode displayList) { - displayList.setTranslationX(mScrollX); - displayList.setTranslationY(mScrollY); + private void setBackgroundRenderNodeProperties(RenderNode renderNode) { + renderNode.setTranslationX(mScrollX); + renderNode.setTranslationY(mScrollY); } /** |