Skip to content

Commit 0d6f4c0

Browse files
author
Romain Guy
committed
Dejank: don't allocate when scrolling lists
The new display list properties introduces in JB were causing numerous and expensive memory allocations while scrolling lists. During a scroll ListView sometimes attempts to apply an offset to views before they are drawn for the first time. This had the side effect of generating a new IllegalStateException and its entire stack trace. The exception was caught inside the display list and never seen by users. Generating an exception is very expensive both in terms of allocated memory and CPU time spent crawling the stack. List scrolls/flings are a common case of this issue but it also happens during various types of animations. A simple alpha animation, for instance, can cause the problem to occur. Another side effect of this issue is more frequent and longer GC pauses. Change-Id: Ic1b37cc84f7c8f290209cfb990d030e96d6e0dc7
1 parent d7c00d2 commit 0d6f4c0

File tree

1 file changed

+54
-100
lines changed

1 file changed

+54
-100
lines changed

core/java/android/view/GLES20DisplayList.java

Lines changed: 54 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class GLES20DisplayList extends DisplayList {
4343
mName = name;
4444
}
4545

46+
boolean hasNativeDisplayList() {
47+
return mValid && mFinalizer != null;
48+
}
49+
4650
int getNativeDisplayList() {
4751
if (!mValid || mFinalizer == null) {
4852
throw new IllegalStateException("The display list is not valid.");
@@ -110,229 +114,179 @@ public int getSize() {
110114

111115
@Override
112116
public void setCaching(boolean caching) {
113-
try {
114-
nSetCaching(getNativeDisplayList(), caching);
115-
} catch (IllegalStateException e) {
116-
// invalid DisplayList okay: we'll set current values the next time we render to it
117+
if (hasNativeDisplayList()) {
118+
nSetCaching(mFinalizer.mNativeDisplayList, caching);
117119
}
118120
}
119121

120122
@Override
121123
public void setClipChildren(boolean clipChildren) {
122-
try {
123-
nSetClipChildren(getNativeDisplayList(), clipChildren);
124-
} catch (IllegalStateException e) {
125-
// invalid DisplayList okay: we'll set current values the next time we render to it
124+
if (hasNativeDisplayList()) {
125+
nSetClipChildren(mFinalizer.mNativeDisplayList, clipChildren);
126126
}
127127
}
128128

129129
@Override
130130
public void setStaticMatrix(Matrix matrix) {
131-
try {
132-
nSetStaticMatrix(getNativeDisplayList(), matrix.native_instance);
133-
} catch (IllegalStateException e) {
134-
// invalid DisplayList okay: we'll set current values the next time we render to it
131+
if (hasNativeDisplayList()) {
132+
nSetStaticMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance);
135133
}
136134
}
137135

138136
@Override
139137
public void setAnimationMatrix(Matrix matrix) {
140-
try {
141-
nSetAnimationMatrix(getNativeDisplayList(),
138+
if (hasNativeDisplayList()) {
139+
nSetAnimationMatrix(mFinalizer.mNativeDisplayList,
142140
(matrix != null) ? matrix.native_instance : 0);
143-
} catch (IllegalStateException e) {
144-
// invalid DisplayList okay: we'll set current values the next time we render to it
145141
}
146142
}
147143

148144
@Override
149145
public void setAlpha(float alpha) {
150-
try {
151-
nSetAlpha(getNativeDisplayList(), alpha);
152-
} catch (IllegalStateException e) {
153-
// invalid DisplayList okay: we'll set current values the next time we render to it
146+
if (hasNativeDisplayList()) {
147+
nSetAlpha(mFinalizer.mNativeDisplayList, alpha);
154148
}
155149
}
156150

157151
@Override
158152
public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
159-
try {
160-
nSetHasOverlappingRendering(getNativeDisplayList(), hasOverlappingRendering);
161-
} catch (IllegalStateException e) {
162-
// invalid DisplayList okay: we'll set current values the next time we render to it
153+
if (hasNativeDisplayList()) {
154+
nSetHasOverlappingRendering(mFinalizer.mNativeDisplayList, hasOverlappingRendering);
163155
}
164156
}
165157

166158
@Override
167159
public void setTranslationX(float translationX) {
168-
try {
169-
nSetTranslationX(getNativeDisplayList(), translationX);
170-
} catch (IllegalStateException e) {
171-
// invalid DisplayList okay: we'll set current values the next time we render to it
160+
if (hasNativeDisplayList()) {
161+
nSetTranslationX(mFinalizer.mNativeDisplayList, translationX);
172162
}
173163
}
174164

175165
@Override
176166
public void setTranslationY(float translationY) {
177-
try {
178-
nSetTranslationY(getNativeDisplayList(), translationY);
179-
} catch (IllegalStateException e) {
180-
// invalid DisplayList okay: we'll set current values the next time we render to it
167+
if (hasNativeDisplayList()) {
168+
nSetTranslationY(mFinalizer.mNativeDisplayList, translationY);
181169
}
182170
}
183171

184172
@Override
185173
public void setRotation(float rotation) {
186-
try {
187-
nSetRotation(getNativeDisplayList(), rotation);
188-
} catch (IllegalStateException e) {
189-
// invalid DisplayList okay: we'll set current values the next time we render to it
174+
if (hasNativeDisplayList()) {
175+
nSetRotation(mFinalizer.mNativeDisplayList, rotation);
190176
}
191177
}
192178

193179
@Override
194180
public void setRotationX(float rotationX) {
195-
try {
196-
nSetRotationX(getNativeDisplayList(), rotationX);
197-
} catch (IllegalStateException e) {
198-
// invalid DisplayList okay: we'll set current values the next time we render to it
181+
if (hasNativeDisplayList()) {
182+
nSetRotationX(mFinalizer.mNativeDisplayList, rotationX);
199183
}
200184
}
201185

202186
@Override
203187
public void setRotationY(float rotationY) {
204-
try {
205-
nSetRotationY(getNativeDisplayList(), rotationY);
206-
} catch (IllegalStateException e) {
207-
// invalid DisplayList okay: we'll set current values the next time we render to it
188+
if (hasNativeDisplayList()) {
189+
nSetRotationY(mFinalizer.mNativeDisplayList, rotationY);
208190
}
209191
}
210192

211193
@Override
212194
public void setScaleX(float scaleX) {
213-
try {
214-
nSetScaleX(getNativeDisplayList(), scaleX);
215-
} catch (IllegalStateException e) {
216-
// invalid DisplayList okay: we'll set current values the next time we render to it
195+
if (hasNativeDisplayList()) {
196+
nSetScaleX(mFinalizer.mNativeDisplayList, scaleX);
217197
}
218198
}
219199

220200
@Override
221201
public void setScaleY(float scaleY) {
222-
try {
223-
nSetScaleY(getNativeDisplayList(), scaleY);
224-
} catch (IllegalStateException e) {
225-
// invalid DisplayList okay: we'll set current values the next time we render to it
202+
if (hasNativeDisplayList()) {
203+
nSetScaleY(mFinalizer.mNativeDisplayList, scaleY);
226204
}
227205
}
228206

229207
@Override
230208
public void setTransformationInfo(float alpha, float translationX, float translationY,
231209
float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
232-
try {
233-
nSetTransformationInfo(getNativeDisplayList(), alpha, translationX, translationY,
210+
if (hasNativeDisplayList()) {
211+
nSetTransformationInfo(mFinalizer.mNativeDisplayList, alpha, translationX, translationY,
234212
rotation, rotationX, rotationY, scaleX, scaleY);
235-
} catch (IllegalStateException e) {
236-
// invalid DisplayList okay: we'll set current values the next time we render to it
237213
}
238214
}
239215

240216
@Override
241217
public void setPivotX(float pivotX) {
242-
try {
243-
nSetPivotX(getNativeDisplayList(), pivotX);
244-
} catch (IllegalStateException e) {
245-
// invalid DisplayList okay: we'll set current values the next time we render to it
218+
if (hasNativeDisplayList()) {
219+
nSetPivotX(mFinalizer.mNativeDisplayList, pivotX);
246220
}
247221
}
248222

249223
@Override
250224
public void setPivotY(float pivotY) {
251-
try {
252-
nSetPivotY(getNativeDisplayList(), pivotY);
253-
} catch (IllegalStateException e) {
254-
// invalid DisplayList okay: we'll set current values the next time we render to it
225+
if (hasNativeDisplayList()) {
226+
nSetPivotY(mFinalizer.mNativeDisplayList, pivotY);
255227
}
256228
}
257229

258230
@Override
259231
public void setCameraDistance(float distance) {
260-
try {
261-
nSetCameraDistance(getNativeDisplayList(), distance);
262-
} catch (IllegalStateException e) {
263-
// invalid DisplayList okay: we'll set current values the next time we render to it
232+
if (hasNativeDisplayList()) {
233+
nSetCameraDistance(mFinalizer.mNativeDisplayList, distance);
264234
}
265235
}
266236

267237
@Override
268238
public void setLeft(int left) {
269-
try {
270-
nSetLeft(getNativeDisplayList(), left);
271-
} catch (IllegalStateException e) {
272-
// invalid DisplayList okay: we'll set current values the next time we render to it
239+
if (hasNativeDisplayList()) {
240+
nSetLeft(mFinalizer.mNativeDisplayList, left);
273241
}
274242
}
275243

276244
@Override
277245
public void setTop(int top) {
278-
try {
279-
nSetTop(getNativeDisplayList(), top);
280-
} catch (IllegalStateException e) {
281-
// invalid DisplayList okay: we'll set current values the next time we render to it
246+
if (hasNativeDisplayList()) {
247+
nSetTop(mFinalizer.mNativeDisplayList, top);
282248
}
283249
}
284250

285251
@Override
286252
public void setRight(int right) {
287-
try {
288-
nSetRight(getNativeDisplayList(), right);
289-
} catch (IllegalStateException e) {
290-
// invalid DisplayList okay: we'll set current values the next time we render to it
253+
if (hasNativeDisplayList()) {
254+
nSetRight(mFinalizer.mNativeDisplayList, right);
291255
}
292256
}
293257

294258
@Override
295259
public void setBottom(int bottom) {
296-
try {
297-
nSetBottom(getNativeDisplayList(), bottom);
298-
} catch (IllegalStateException e) {
299-
// invalid DisplayList okay: we'll set current values the next time we render to it
260+
if (hasNativeDisplayList()) {
261+
nSetBottom(mFinalizer.mNativeDisplayList, bottom);
300262
}
301263
}
302264

303265
@Override
304266
public void setLeftTop(int left, int top) {
305-
try {
306-
nSetLeftTop(getNativeDisplayList(), left, top);
307-
} catch (IllegalStateException e) {
308-
// invalid DisplayList okay: we'll set current values the next time we render to it
267+
if (hasNativeDisplayList()) {
268+
nSetLeftTop(mFinalizer.mNativeDisplayList, left, top);
309269
}
310270
}
311271

312272
@Override
313273
public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
314-
try {
315-
nSetLeftTopRightBottom(getNativeDisplayList(), left, top, right, bottom);
316-
} catch (IllegalStateException e) {
317-
// invalid DisplayList okay: we'll set current values the next time we render to it
274+
if (hasNativeDisplayList()) {
275+
nSetLeftTopRightBottom(mFinalizer.mNativeDisplayList, left, top, right, bottom);
318276
}
319277
}
320278

321279
@Override
322280
public void offsetLeftRight(int offset) {
323-
try {
324-
nOffsetLeftRight(getNativeDisplayList(), offset);
325-
} catch (IllegalStateException e) {
326-
// invalid DisplayList okay: we'll set current values the next time we render to it
281+
if (hasNativeDisplayList()) {
282+
nOffsetLeftRight(mFinalizer.mNativeDisplayList, offset);
327283
}
328284
}
329285

330286
@Override
331287
public void offsetTopBottom(int offset) {
332-
try {
333-
nOffsetTopBottom(getNativeDisplayList(), offset);
334-
} catch (IllegalStateException e) {
335-
// invalid DisplayList okay: we'll set current values the next time we render to it
288+
if (hasNativeDisplayList()) {
289+
nOffsetTopBottom(mFinalizer.mNativeDisplayList, offset);
336290
}
337291
}
338292

0 commit comments

Comments
 (0)