Merge "Optimize drawHardwareAccelerated method in Editor class"
This commit is contained in:
@@ -503,8 +503,15 @@ public class DynamicLayout extends Layout
|
||||
|
||||
mNumberOfBlocks = newNumberOfBlocks;
|
||||
final int deltaLines = newLineCount - (endLine - startLine + 1);
|
||||
for (int i = firstBlock + numAddedBlocks; i < mNumberOfBlocks; i++) {
|
||||
mBlockEndLines[i] += deltaLines;
|
||||
if (deltaLines != 0) {
|
||||
// Display list whose index is >= mIndexFirstChangedBlock is valid
|
||||
// but it needs to update its drawing location.
|
||||
mIndexFirstChangedBlock = firstBlock + numAddedBlocks;
|
||||
for (int i = mIndexFirstChangedBlock; i < mNumberOfBlocks; i++) {
|
||||
mBlockEndLines[i] += deltaLines;
|
||||
}
|
||||
} else {
|
||||
mIndexFirstChangedBlock = mNumberOfBlocks;
|
||||
}
|
||||
|
||||
int blockIndex = firstBlock;
|
||||
@@ -559,6 +566,20 @@ public class DynamicLayout extends Layout
|
||||
return mNumberOfBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public int getIndexFirstChangedBlock() {
|
||||
return mIndexFirstChangedBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void setIndexFirstChangedBlock(int i) {
|
||||
mIndexFirstChangedBlock = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineCount() {
|
||||
return mInts.size() - 1;
|
||||
@@ -697,6 +718,8 @@ public class DynamicLayout extends Layout
|
||||
private int[] mBlockIndices;
|
||||
// Number of items actually currently being used in the above 2 arrays
|
||||
private int mNumberOfBlocks;
|
||||
// The first index of the blocks whose locations are changed
|
||||
private int mIndexFirstChangedBlock;
|
||||
|
||||
private int mTopPadding, mBottomPadding;
|
||||
|
||||
|
||||
@@ -124,7 +124,6 @@ public class Editor {
|
||||
InputMethodState mInputMethodState;
|
||||
|
||||
DisplayList[] mTextDisplayLists;
|
||||
int mLastLayoutHeight;
|
||||
|
||||
boolean mFrozenWithFocus;
|
||||
boolean mSelectionMoved;
|
||||
@@ -1289,20 +1288,11 @@ public class Editor {
|
||||
mTextDisplayLists = new DisplayList[ArrayUtils.idealObjectArraySize(0)];
|
||||
}
|
||||
|
||||
// If the height of the layout changes (usually when inserting or deleting a line,
|
||||
// but could be changes within a span), invalidate everything. We could optimize
|
||||
// more aggressively (for example, adding offsets to blocks) but it would be more
|
||||
// complex and we would only get the benefit in some cases.
|
||||
int layoutHeight = layout.getHeight();
|
||||
if (mLastLayoutHeight != layoutHeight) {
|
||||
invalidateTextDisplayList();
|
||||
mLastLayoutHeight = layoutHeight;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -1327,7 +1317,8 @@ public class Editor {
|
||||
if (blockIsInvalid) blockDisplayList.invalidate();
|
||||
}
|
||||
|
||||
if (!blockDisplayList.isValid()) {
|
||||
final boolean blockDisplayListIsInvalid = !blockDisplayList.isValid();
|
||||
if (i >= indexFirstChangedBlock || blockDisplayListIsInvalid) {
|
||||
final int blockBeginLine = endOfPreviousBlock + 1;
|
||||
final int top = layout.getLineTop(blockBeginLine);
|
||||
final int bottom = layout.getLineBottom(blockEndLine);
|
||||
@@ -1344,24 +1335,30 @@ public class Editor {
|
||||
right = (int) (max + 0.5f);
|
||||
}
|
||||
|
||||
final HardwareCanvas hardwareCanvas = blockDisplayList.start();
|
||||
try {
|
||||
// Tighten the bounds of the viewport to the actual text size
|
||||
hardwareCanvas.setViewport(right - left, bottom - top);
|
||||
// The dirty rect should always be null for a display list
|
||||
hardwareCanvas.onPreDraw(null);
|
||||
// drawText is always relative to TextView's origin, this translation brings
|
||||
// this range of text back to the top left corner of the viewport
|
||||
hardwareCanvas.translate(-left, -top);
|
||||
layout.drawText(hardwareCanvas, blockBeginLine, blockEndLine);
|
||||
// No need to untranslate, previous context is popped after drawDisplayList
|
||||
} finally {
|
||||
hardwareCanvas.onPostDraw();
|
||||
blockDisplayList.end();
|
||||
blockDisplayList.setLeftTopRightBottom(left, top, right, bottom);
|
||||
// Same as drawDisplayList below, handled by our TextView's parent
|
||||
blockDisplayList.setClipChildren(false);
|
||||
// Rebuild display list if it is invalid
|
||||
if (blockDisplayListIsInvalid) {
|
||||
final HardwareCanvas hardwareCanvas = blockDisplayList.start();
|
||||
try {
|
||||
// Tighten the bounds of the viewport to the actual text size
|
||||
hardwareCanvas.setViewport(right - left, bottom - top);
|
||||
// The dirty rect should always be null for a display list
|
||||
hardwareCanvas.onPreDraw(null);
|
||||
// drawText is always relative to TextView's origin, this translation brings
|
||||
// this range of text back to the top left corner of the viewport
|
||||
hardwareCanvas.translate(-left, -top);
|
||||
layout.drawText(hardwareCanvas, blockBeginLine, blockEndLine);
|
||||
// No need to untranslate, previous context is popped after drawDisplayList
|
||||
} finally {
|
||||
hardwareCanvas.onPostDraw();
|
||||
blockDisplayList.end();
|
||||
// Same as drawDisplayList below, handled by our TextView's parent
|
||||
blockDisplayList.setClipChildren(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Valid disply list whose index is >= indexFirstChangedBlock
|
||||
// only needs to update its drawing location.
|
||||
blockDisplayList.setLeftTopRightBottom(left, top, right, bottom);
|
||||
}
|
||||
|
||||
((HardwareCanvas) canvas).drawDisplayList(blockDisplayList, null,
|
||||
@@ -1369,6 +1366,8 @@ public class Editor {
|
||||
|
||||
endOfPreviousBlock = blockEndLine;
|
||||
}
|
||||
|
||||
dynamicLayout.setIndexFirstChangedBlock(numberOfBlocks);
|
||||
} else {
|
||||
// Boring layout is used for empty and hint text
|
||||
layout.drawText(canvas, firstLine, lastLine);
|
||||
|
||||
@@ -6459,7 +6459,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
mDeferScroll = -1;
|
||||
bringPointIntoView(Math.min(curs, mText.length()));
|
||||
}
|
||||
if (changed && mEditor != null) mEditor.invalidateTextDisplayList();
|
||||
}
|
||||
|
||||
private boolean isShowingHint() {
|
||||
|
||||
Reference in New Issue
Block a user