use of android.view.DisplayListCanvas in project android_frameworks_base by DirtyUnicorns.
the class RippleComponent method draw.
/**
* Draws the ripple to the canvas, inheriting the paint's color and alpha
* properties.
*
* @param c the canvas to which the ripple should be drawn
* @param p the paint used to draw the ripple
* @return {@code true} if something was drawn, {@code false} otherwise
*/
public boolean draw(Canvas c, Paint p) {
final boolean hasDisplayListCanvas = !mForceSoftware && c.isHardwareAccelerated() && c instanceof DisplayListCanvas;
if (mHasDisplayListCanvas != hasDisplayListCanvas) {
mHasDisplayListCanvas = hasDisplayListCanvas;
if (!hasDisplayListCanvas) {
// We've switched from hardware to non-hardware mode. Panic.
endHardwareAnimations();
}
}
if (hasDisplayListCanvas) {
final DisplayListCanvas hw = (DisplayListCanvas) c;
startPendingAnimation(hw, p);
if (mHardwareAnimator != null) {
return drawHardware(hw);
}
}
return drawSoftware(c, p);
}
use of android.view.DisplayListCanvas in project android_frameworks_base by DirtyUnicorns.
the class BackdropFrameRenderer method redrawLocked.
/**
* Redraws the background, the caption and the system inset backgrounds if something changed.
*
* @param newBounds The window bounds which needs to be drawn.
* @param fullscreen Whether the window is currently drawing in fullscreen.
* @param systemInsets The current visible system insets for the window.
* @param stableInsets The stable insets for the window.
*/
private void redrawLocked(Rect newBounds, boolean fullscreen, Rect systemInsets, Rect stableInsets) {
// While a configuration change is taking place the view hierarchy might become
// inaccessible. For that case we remember the previous metrics to avoid flashes.
// Note that even when there is no visible caption, the caption child will exist.
final int captionHeight = mDecorView.getCaptionHeight();
// Once set to something other then 0 it should be kept that way.
if (captionHeight != 0) {
// Remember the height of the caption.
mLastCaptionHeight = captionHeight;
}
// content. If any size is 0, we have to wait for it to be drawn first.
if ((mLastCaptionHeight == 0 && mDecorView.isShowingCaption()) || mLastContentWidth == 0 || mLastContentHeight == 0) {
return;
}
// Since the surface is spanning the entire screen, we have to add the start offset of
// the bounds to get to the surface location.
final int left = mLastXOffset + newBounds.left;
final int top = mLastYOffset + newBounds.top;
final int width = newBounds.width();
final int height = newBounds.height();
mFrameAndBackdropNode.setLeftTopRightBottom(left, top, left + width, top + height);
// Draw the caption and content backdrops in to our render node.
DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
final Drawable drawable = mUserCaptionBackgroundDrawable != null ? mUserCaptionBackgroundDrawable : mCaptionBackgroundDrawable;
if (drawable != null) {
drawable.setBounds(0, 0, left + width, top + mLastCaptionHeight);
drawable.draw(canvas);
}
// The backdrop: clear everything with the background. Clipping is done elsewhere.
if (mResizingBackgroundDrawable != null) {
mResizingBackgroundDrawable.setBounds(0, mLastCaptionHeight, left + width, top + height);
mResizingBackgroundDrawable.draw(canvas);
}
mFrameAndBackdropNode.end(canvas);
drawColorViews(left, top, width, height, fullscreen, systemInsets, stableInsets);
// We need to render the node explicitly
mRenderer.drawRenderNode(mFrameAndBackdropNode);
reportDrawIfNeeded();
}
use of android.view.DisplayListCanvas in project android_frameworks_base by AOSPA.
the class BackdropFrameRenderer method redrawLocked.
/**
* Redraws the background, the caption and the system inset backgrounds if something changed.
*
* @param newBounds The window bounds which needs to be drawn.
* @param fullscreen Whether the window is currently drawing in fullscreen.
* @param systemInsets The current visible system insets for the window.
* @param stableInsets The stable insets for the window.
*/
private void redrawLocked(Rect newBounds, boolean fullscreen, Rect systemInsets, Rect stableInsets) {
// While a configuration change is taking place the view hierarchy might become
// inaccessible. For that case we remember the previous metrics to avoid flashes.
// Note that even when there is no visible caption, the caption child will exist.
final int captionHeight = mDecorView.getCaptionHeight();
// Once set to something other then 0 it should be kept that way.
if (captionHeight != 0) {
// Remember the height of the caption.
mLastCaptionHeight = captionHeight;
}
// content. If any size is 0, we have to wait for it to be drawn first.
if ((mLastCaptionHeight == 0 && mDecorView.isShowingCaption()) || mLastContentWidth == 0 || mLastContentHeight == 0) {
return;
}
// Since the surface is spanning the entire screen, we have to add the start offset of
// the bounds to get to the surface location.
final int left = mLastXOffset + newBounds.left;
final int top = mLastYOffset + newBounds.top;
final int width = newBounds.width();
final int height = newBounds.height();
mFrameAndBackdropNode.setLeftTopRightBottom(left, top, left + width, top + height);
// Draw the caption and content backdrops in to our render node.
DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
final Drawable drawable = mUserCaptionBackgroundDrawable != null ? mUserCaptionBackgroundDrawable : mCaptionBackgroundDrawable;
if (drawable != null) {
drawable.setBounds(0, 0, left + width, top + mLastCaptionHeight);
drawable.draw(canvas);
}
// The backdrop: clear everything with the background. Clipping is done elsewhere.
if (mResizingBackgroundDrawable != null) {
mResizingBackgroundDrawable.setBounds(0, mLastCaptionHeight, left + width, top + height);
mResizingBackgroundDrawable.draw(canvas);
}
mFrameAndBackdropNode.end(canvas);
drawColorViews(left, top, width, height, fullscreen, systemInsets, stableInsets);
// We need to render the node explicitly
mRenderer.drawRenderNode(mFrameAndBackdropNode);
reportDrawIfNeeded();
}
use of android.view.DisplayListCanvas in project android_frameworks_base by AOSPA.
the class KeyguardAffordanceView method drawBackgroundCircle.
private void drawBackgroundCircle(Canvas canvas) {
if (mCircleRadius > 0 || mFinishing) {
if (mFinishing && mSupportHardware && mHwCenterX != null) {
// Our hardware drawing proparties can be null if the finishing started but we have
// never drawn before. In that case we are not doing a render thread animation
// anyway, so we need to use the normal drawing.
DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
displayListCanvas.drawCircle(mHwCenterX, mHwCenterY, mHwCircleRadius, mHwCirclePaint);
} else {
updateCircleColor();
canvas.drawCircle(mCenterX, mCenterY, mCircleRadius, mCirclePaint);
}
}
}
use of android.view.DisplayListCanvas in project android_frameworks_base by AOSPA.
the class Editor method drawHardwareAccelerated.
private void drawHardwareAccelerated(Canvas canvas, Layout layout, Path highlight, Paint highlightPaint, int cursorOffsetVertical) {
final long lineRange = layout.getLineRangeForDraw(canvas);
int firstLine = TextUtils.unpackRangeStartFromLong(lineRange);
int lastLine = TextUtils.unpackRangeEndFromLong(lineRange);
if (lastLine < 0)
return;
layout.drawBackground(canvas, highlight, highlightPaint, cursorOffsetVertical, firstLine, lastLine);
if (layout instanceof DynamicLayout) {
if (mTextRenderNodes == null) {
mTextRenderNodes = ArrayUtils.emptyArray(TextRenderNode.class);
}
DynamicLayout dynamicLayout = (DynamicLayout) layout;
int[] blockEndLines = dynamicLayout.getBlockEndLines();
int[] blockIndices = dynamicLayout.getBlockIndices();
final int numberOfBlocks = dynamicLayout.getNumberOfBlocks();
final int indexFirstChangedBlock = dynamicLayout.getIndexFirstChangedBlock();
int endOfPreviousBlock = -1;
int searchStartIndex = 0;
for (int i = 0; i < numberOfBlocks; i++) {
int blockEndLine = blockEndLines[i];
int blockIndex = blockIndices[i];
final boolean blockIsInvalid = blockIndex == DynamicLayout.INVALID_BLOCK_INDEX;
if (blockIsInvalid) {
blockIndex = getAvailableDisplayListIndex(blockIndices, numberOfBlocks, searchStartIndex);
// Note how dynamic layout's internal block indices get updated from Editor
blockIndices[i] = blockIndex;
if (mTextRenderNodes[blockIndex] != null) {
mTextRenderNodes[blockIndex].isDirty = true;
}
searchStartIndex = blockIndex + 1;
}
if (mTextRenderNodes[blockIndex] == null) {
mTextRenderNodes[blockIndex] = new TextRenderNode("Text " + blockIndex);
}
final boolean blockDisplayListIsInvalid = mTextRenderNodes[blockIndex].needsRecord();
RenderNode blockDisplayList = mTextRenderNodes[blockIndex].renderNode;
if (i >= indexFirstChangedBlock || blockDisplayListIsInvalid) {
final int blockBeginLine = endOfPreviousBlock + 1;
final int top = layout.getLineTop(blockBeginLine);
final int bottom = layout.getLineBottom(blockEndLine);
int left = 0;
int right = mTextView.getWidth();
if (mTextView.getHorizontallyScrolling()) {
float min = Float.MAX_VALUE;
float max = Float.MIN_VALUE;
for (int line = blockBeginLine; line <= blockEndLine; line++) {
min = Math.min(min, layout.getLineLeft(line));
max = Math.max(max, layout.getLineRight(line));
}
left = (int) min;
right = (int) (max + 0.5f);
}
// Rebuild display list if it is invalid
if (blockDisplayListIsInvalid) {
final DisplayListCanvas displayListCanvas = blockDisplayList.start(right - left, bottom - top);
try {
// drawText is always relative to TextView's origin, this translation
// brings this range of text back to the top left corner of the viewport
displayListCanvas.translate(-left, -top);
layout.drawText(displayListCanvas, blockBeginLine, blockEndLine);
mTextRenderNodes[blockIndex].isDirty = false;
// No need to untranslate, previous context is popped after
// drawDisplayList
} finally {
blockDisplayList.end(displayListCanvas);
// Same as drawDisplayList below, handled by our TextView's parent
blockDisplayList.setClipToBounds(false);
}
}
// Valid disply list whose index is >= indexFirstChangedBlock
// only needs to update its drawing location.
blockDisplayList.setLeftTopRightBottom(left, top, right, bottom);
}
((DisplayListCanvas) canvas).drawRenderNode(blockDisplayList);
endOfPreviousBlock = blockEndLine;
}
dynamicLayout.setIndexFirstChangedBlock(numberOfBlocks);
} else {
// Boring layout is used for empty and hint text
layout.drawText(canvas, firstLine, lastLine);
}
}
Aggregations