• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 import java.lang.ref.ReferenceQueue;
18 import java.lang.ref.PhantomReference;
19 import java.util.ArrayList;
20 
21 public 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 {
sWatcher.start()32         sWatcher.start();
33     };
34 
Bitmap(String name, int width, int height, Bitmap.NativeWrapper nativeData)35     Bitmap(String name, int width, int height, Bitmap.NativeWrapper nativeData) {
36         mName = name;
37         mWidth = width;
38         mHeight = height;
39         mNativeWrapper = nativeData;
40 
41         System.out.println("Created " + this);
42     }
43 
toString()44     public String toString() {
45         return "Bitmap " + mName + ": " + mWidth + "x" + mHeight + " (" +
46                 mNativeWrapper.mNativeData + ")";
47     }
48 
drawAt(int x, int y)49     public void drawAt(int x, int y) {
50         System.out.println("Drawing " + this);
51     }
52 
shutDown()53     public static void shutDown() {
54         sWatcher.shutDown();
55         try {
56             sWatcher.join();
57         } catch (InterruptedException ie) {
58             System.out.println("join intr");
59         }
60         System.out.println("Bitmap has shut down");
61     }
62 
63     /*
64      * Pretend we're allocating native storage.  Just returns a unique
65      * serial number.
66      */
allocNativeStorage(int width, int height)67     static Bitmap.NativeWrapper allocNativeStorage(int width, int height) {
68         int nativeData;
69 
70         synchronized (Bitmap.class) {
71             nativeData = sSerial++;
72         }
73 
74         Bitmap.NativeWrapper wrapper = new Bitmap.NativeWrapper(nativeData);
75         PhantomWrapper phan = new PhantomWrapper(wrapper, sPhantomQueue,
76                 nativeData);
77         sPhantomList.add(phan);
78         return wrapper;
79     }
80 
freeNativeStorage(int nativeDataPtr)81     static void freeNativeStorage(int nativeDataPtr) {
82         System.out.println("freeNativeStorage: " + nativeDataPtr);
83     }
84 
85     /*
86      * Wraps a native data pointer in an object.  When this object is no
87      * longer referenced, we free the native data.
88      */
89     static class NativeWrapper {
NativeWrapper(int nativeDataPtr)90         public NativeWrapper(int nativeDataPtr) {
91             mNativeData = nativeDataPtr;
92         }
93         public int mNativeData;
94 
95         /*
96         @Override
97         protected void finalize() throws Throwable {
98             System.out.println("finalized " + mNativeData);
99         }
100         */
101     }
102 }
103 
104 /*
105  * Keep an eye on the native data.
106  *
107  * We keep a copy of the native data pointer value, and set the wrapper
108  * as our referent.  We need the copy because you can't get the referred-to
109  * object back out of a PhantomReference.
110  */
111 class PhantomWrapper extends PhantomReference {
PhantomWrapper(Bitmap.NativeWrapper wrapper, ReferenceQueue<PhantomWrapper> queue, int nativeDataPtr)112     PhantomWrapper(Bitmap.NativeWrapper wrapper,
113         ReferenceQueue<PhantomWrapper> queue, int nativeDataPtr)
114     {
115         super(wrapper, queue);
116         mNativeData = nativeDataPtr;
117     }
118 
119     public int mNativeData;
120 }
121 
122 /*
123  * Thread that watches for un-referenced bitmap data.
124  */
125 class BitmapWatcher extends Thread {
126     ReferenceQueue<PhantomWrapper> mQueue;
127     volatile boolean mQuit = false;
128 
BitmapWatcher(ReferenceQueue<PhantomWrapper> queue)129     BitmapWatcher(ReferenceQueue<PhantomWrapper> queue) {
130         mQueue = queue;
131         setName("Bitmap Watcher");
132     }
133 
run()134     public void run() {
135         while (!mQuit) {
136             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");
144             }
145         }
146     }
147 
shutDown()148     public void shutDown() {
149         mQuit = true;
150         interrupt();
151     }
152 }
153