blob: ff43749e76a66391b6ef146050bc5b238dd083ad [file] [log] [blame]
jeffhao5d1ac922011-09-29 17:41:15 -07001/*
2 * Copyright (C) 2009 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
17import java.lang.ref.ReferenceQueue;
18import java.lang.ref.PhantomReference;
19import java.util.ArrayList;
20
21public class Bitmap {
22 String mName; /* for debugging */
23 int mWidth, mHeight;
24 Bitmap.NativeWrapper mNativeWrapper;
25
26 private static int sSerial = 100;
27 private static ArrayList sPhantomList = new ArrayList<PhantomWrapper>();
28 private static ReferenceQueue<PhantomWrapper> sPhantomQueue =
29 new ReferenceQueue<PhantomWrapper>();
30 private static BitmapWatcher sWatcher = new BitmapWatcher(sPhantomQueue);
31 static {
Dmitry Petrochenkofa658b02014-05-16 13:24:40 +070032 sWatcher.setDaemon(true);
jeffhao5d1ac922011-09-29 17:41:15 -070033 sWatcher.start();
34 };
35
36 Bitmap(String name, int width, int height, Bitmap.NativeWrapper nativeData) {
37 mName = name;
38 mWidth = width;
39 mHeight = height;
40 mNativeWrapper = nativeData;
41
42 System.out.println("Created " + this);
43 }
44
45 public String toString() {
46 return "Bitmap " + mName + ": " + mWidth + "x" + mHeight + " (" +
47 mNativeWrapper.mNativeData + ")";
48 }
49
50 public void drawAt(int x, int y) {
51 System.out.println("Drawing " + this);
52 }
53
54 public static void shutDown() {
55 sWatcher.shutDown();
56 try {
57 sWatcher.join();
58 } catch (InterruptedException ie) {
59 System.out.println("join intr");
60 }
61 System.out.println("Bitmap has shut down");
62 }
63
64 /*
65 * Pretend we're allocating native storage. Just returns a unique
66 * serial number.
67 */
68 static Bitmap.NativeWrapper allocNativeStorage(int width, int height) {
69 int nativeData;
70
71 synchronized (Bitmap.class) {
72 nativeData = sSerial++;
73 }
74
75 Bitmap.NativeWrapper wrapper = new Bitmap.NativeWrapper(nativeData);
76 PhantomWrapper phan = new PhantomWrapper(wrapper, sPhantomQueue,
77 nativeData);
78 sPhantomList.add(phan);
79 return wrapper;
80 }
81
82 static void freeNativeStorage(int nativeDataPtr) {
83 System.out.println("freeNativeStorage: " + nativeDataPtr);
84 }
85
86 /*
87 * Wraps a native data pointer in an object. When this object is no
88 * longer referenced, we free the native data.
89 */
90 static class NativeWrapper {
91 public NativeWrapper(int nativeDataPtr) {
92 mNativeData = nativeDataPtr;
93 }
94 public int mNativeData;
95
96 /*
97 @Override
98 protected void finalize() throws Throwable {
99 System.out.println("finalized " + mNativeData);
100 }
101 */
102 }
103}
104
105/*
106 * Keep an eye on the native data.
107 *
108 * We keep a copy of the native data pointer value, and set the wrapper
109 * as our referent. We need the copy because you can't get the referred-to
110 * object back out of a PhantomReference.
111 */
112class PhantomWrapper extends PhantomReference {
113 PhantomWrapper(Bitmap.NativeWrapper wrapper,
114 ReferenceQueue<PhantomWrapper> queue, int nativeDataPtr)
115 {
116 super(wrapper, queue);
117 mNativeData = nativeDataPtr;
118 }
119
120 public int mNativeData;
121}
122
123/*
124 * Thread that watches for un-referenced bitmap data.
125 */
126class BitmapWatcher extends Thread {
127 ReferenceQueue<PhantomWrapper> mQueue;
jeffhao5d1ac922011-09-29 17:41:15 -0700128
129 BitmapWatcher(ReferenceQueue<PhantomWrapper> queue) {
130 mQueue = queue;
131 setName("Bitmap Watcher");
132 }
133
134 public void run() {
randy.jeong10cd86b2015-10-08 19:32:12 +0900135 while (true) {
jeffhao5d1ac922011-09-29 17:41:15 -0700136 try {
137 PhantomWrapper ref = (PhantomWrapper) mQueue.remove();
138 //System.out.println("dequeued ref " + ref.mNativeData +
139 // " - " + ref);
140 Bitmap.freeNativeStorage(ref.mNativeData);
141 //ref.clear();
142 } catch (InterruptedException ie) {
143 System.out.println("intr");
randy.jeong10cd86b2015-10-08 19:32:12 +0900144 break;
jeffhao5d1ac922011-09-29 17:41:15 -0700145 }
146 }
147 }
148
149 public void shutDown() {
jeffhao5d1ac922011-09-29 17:41:15 -0700150 interrupt();
151 }
152}