Skip to content

Commit 6c5f4cd

Browse files
chethaaseAndroid (Google) Code Review
authored andcommitted
Merge "Fix hang/crash in native path code" into jb-dev
2 parents 90673b9 + d34dd71 commit 6c5f4cd

File tree

4 files changed

+137
-0
lines changed

4 files changed

+137
-0
lines changed

libs/hwui/DisplayListRenderer.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ void DisplayList::clearResources() {
184184
}
185185
mPaths.clear();
186186

187+
for (size_t i = 0; i < mSourcePaths.size(); i++) {
188+
caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
189+
}
190+
mSourcePaths.clear();
191+
187192
for (size_t i = 0; i < mMatrices.size(); i++) {
188193
delete mMatrices.itemAt(i);
189194
}
@@ -242,6 +247,12 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
242247
mPaths.add(paths.itemAt(i));
243248
}
244249

250+
const SortedVector<SkPath*> &sourcePaths = recorder.getSourcePaths();
251+
for (size_t i = 0; i < sourcePaths.size(); i++) {
252+
mSourcePaths.add(sourcePaths.itemAt(i));
253+
caches.resourceCache.incrementRefcount(sourcePaths.itemAt(i));
254+
}
255+
245256
const Vector<SkMatrix*> &matrices = recorder.getMatrices();
246257
for (size_t i = 0; i < matrices.size(); i++) {
247258
mMatrices.add(matrices.itemAt(i));
@@ -1273,6 +1284,11 @@ void DisplayListRenderer::reset() {
12731284
mShaders.clear();
12741285
mShaderMap.clear();
12751286

1287+
for (size_t i = 0; i < mSourcePaths.size(); i++) {
1288+
caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
1289+
}
1290+
mSourcePaths.clear();
1291+
12761292
mPaints.clear();
12771293
mPaintMap.clear();
12781294

libs/hwui/DisplayListRenderer.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ class DisplayList {
487487

488488
Vector<SkPaint*> mPaints;
489489
Vector<SkPath*> mPaths;
490+
SortedVector<SkPath*> mSourcePaths;
490491
Vector<SkMatrix*> mMatrices;
491492
Vector<SkiaShader*> mShaders;
492493

@@ -634,6 +635,10 @@ class DisplayListRenderer: public OpenGLRenderer {
634635
return mPaths;
635636
}
636637

638+
const SortedVector<SkPath*>& getSourcePaths() const {
639+
return mSourcePaths;
640+
}
641+
637642
const Vector<SkMatrix*>& getMatrices() const {
638643
return mMatrices;
639644
}
@@ -750,6 +755,10 @@ class DisplayListRenderer: public OpenGLRenderer {
750755
mPathMap.replaceValueFor(path, pathCopy);
751756
mPaths.add(pathCopy);
752757
}
758+
if (mSourcePaths.indexOf(path) < 0) {
759+
Caches::getInstance().resourceCache.incrementRefcount(path);
760+
mSourcePaths.add(path);
761+
}
753762

754763
addInt((int) pathCopy);
755764
}
@@ -830,6 +839,8 @@ class DisplayListRenderer: public OpenGLRenderer {
830839
Vector<SkPath*> mPaths;
831840
DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
832841

842+
SortedVector<SkPath*> mSourcePaths;
843+
833844
Vector<SkiaShader*> mShaders;
834845
DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
835846

tests/HwAccelerationTest/AndroidManifest.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,15 @@
657657
</intent-filter>
658658
</activity>
659659

660+
<activity
661+
android:name="PathDestructionActivity"
662+
android:label="_PathDestruction">
663+
<intent-filter>
664+
<action android:name="android.intent.action.MAIN" />
665+
<category android:name="android.intent.category.LAUNCHER" />
666+
</intent-filter>
667+
</activity>
668+
660669
<activity
661670
android:name="TransformsAndAnimationsActivity"
662671
android:label="_TransformAnim">
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (C) 2012 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.test.hwui;
18+
19+
import android.app.Activity;
20+
import android.content.Context;
21+
import android.graphics.Canvas;
22+
import android.graphics.Paint;
23+
import android.graphics.Path;
24+
import android.os.Bundle;
25+
import android.util.MathUtils;
26+
import android.view.View;
27+
28+
/**
29+
* The point of this test is to ensure that we can cause many paths to be created, drawn,
30+
* and destroyed without causing hangs or crashes. This tests the native reference counting
31+
* scheme in particular, because we should be able to have the Java-level path finalized
32+
* without destroying the underlying native path object until we are done referencing it
33+
* in pending DisplayLists.
34+
*/
35+
public class PathDestructionActivity extends Activity {
36+
37+
private static final int MIN_SIZE = 20;
38+
@Override
39+
protected void onCreate(Bundle savedInstanceState) {
40+
super.onCreate(savedInstanceState);
41+
42+
MyView view = new MyView(this);
43+
setContentView(view);
44+
}
45+
46+
private static class MyView extends View {
47+
Paint strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
48+
Paint fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
49+
Paint fillAndStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
50+
51+
private MyView(Context context) {
52+
super(context);
53+
strokePaint.setStyle(Paint.Style.STROKE);
54+
fillPaint.setStyle(Paint.Style.FILL);
55+
fillAndStrokePaint.setStyle(Paint.Style.FILL_AND_STROKE);
56+
}
57+
58+
private Path getRandomPath() {
59+
float left, top, right, bottom;
60+
left = MathUtils.random(getWidth() - MIN_SIZE);
61+
top = MathUtils.random(getHeight() - MIN_SIZE);
62+
right = left + MathUtils.random(getWidth() - left);
63+
bottom = top + MathUtils.random(getHeight() - top);
64+
Path path = new Path();
65+
path.moveTo(left, top);
66+
path.lineTo(right, top);
67+
path.lineTo(right, bottom);
68+
path.lineTo(left, bottom);
69+
path.close();
70+
return path;
71+
}
72+
73+
private int getRandomColor() {
74+
int red = MathUtils.random(255);
75+
int green = MathUtils.random(255);
76+
int blue = MathUtils.random(255);
77+
return 0xff000000 | red << 16 | green << 8 | blue;
78+
}
79+
80+
@Override
81+
protected void onDraw(Canvas canvas) {
82+
Path path;
83+
for (int i = 0; i < 15; ++i) {
84+
path = getRandomPath();
85+
strokePaint.setColor(getRandomColor());
86+
canvas.drawPath(path, strokePaint);
87+
path = null;
88+
path = getRandomPath();
89+
fillPaint.setColor(getRandomColor());
90+
canvas.drawPath(path, fillPaint);
91+
path = null;
92+
path = getRandomPath();
93+
fillAndStrokePaint.setColor(getRandomColor());
94+
canvas.drawPath(path, fillAndStrokePaint);
95+
path = null;
96+
}
97+
98+
invalidate();
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)