Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (c) 2009-2010 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 package com.jme3.util;
     34 
     35 import java.lang.ref.PhantomReference;
     36 import java.lang.ref.ReferenceQueue;
     37 import java.lang.ref.WeakReference;
     38 import java.util.ArrayList;
     39 import java.util.logging.Level;
     40 import java.util.logging.Logger;
     41 
     42 /**
     43  * GLObjectManager tracks all GLObjects used by the Renderer. Using a
     44  * <code>ReferenceQueue</code> the <code>GLObjectManager</code> can delete
     45  * unused objects from GPU when their counterparts on the CPU are no longer used.
     46  *
     47  * On restart, the renderer may request the objects to be reset, thus allowing
     48  * the GLObjects to re-initialize with the new display context.
     49  */
     50 public class NativeObjectManager {
     51 
     52     private static final Logger logger = Logger.getLogger(NativeObjectManager.class.getName());
     53 
     54     /**
     55      * The queue will receive notifications of {@link NativeObject}s which are no longer
     56      * referenced.
     57      */
     58     private ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
     59 
     60     /**
     61      * List of currently active GLObjects.
     62      */
     63     private ArrayList<NativeObjectRef> refList
     64             = new ArrayList<NativeObjectRef>();
     65 
     66     private class NativeObjectRef extends PhantomReference<Object>{
     67 
     68         private NativeObject objClone;
     69         private WeakReference<NativeObject> realObj;
     70 
     71         public NativeObjectRef(NativeObject obj){
     72             super(obj.handleRef, refQueue);
     73             assert obj.handleRef != null;
     74 
     75             this.realObj = new WeakReference<NativeObject>(obj);
     76             this.objClone = obj.createDestructableClone();
     77         }
     78     }
     79 
     80     /**
     81      * Register a GLObject with the manager.
     82      */
     83     public void registerForCleanup(NativeObject obj){
     84         NativeObjectRef ref = new NativeObjectRef(obj);
     85         refList.add(ref);
     86         if (logger.isLoggable(Level.FINEST))
     87             logger.log(Level.FINEST, "Registered: {0}", new String[]{obj.toString()});
     88     }
     89 
     90     /**
     91      * Deletes unused GLObjects
     92      */
     93     public void deleteUnused(Object rendererObject){
     94         while (true){
     95             NativeObjectRef ref = (NativeObjectRef) refQueue.poll();
     96             if (ref == null)
     97                 return;
     98 
     99             refList.remove(ref);
    100             ref.objClone.deleteObject(rendererObject);
    101             if (logger.isLoggable(Level.FINEST))
    102                 logger.log(Level.FINEST, "Deleted: {0}", ref.objClone);
    103         }
    104     }
    105 
    106     /**
    107      * Deletes all objects. Must only be called when display is destroyed.
    108      */
    109     public void deleteAllObjects(Object rendererObject){
    110         deleteUnused(rendererObject);
    111         for (NativeObjectRef ref : refList){
    112             ref.objClone.deleteObject(rendererObject);
    113             NativeObject realObj = ref.realObj.get();
    114             if (realObj != null){
    115                 // Note: make sure to reset them as well
    116                 // They may get used in a new renderer in the future
    117                 realObj.resetObject();
    118             }
    119         }
    120         refList.clear();
    121     }
    122 
    123     /**
    124      * Resets all {@link NativeObject}s.
    125      */
    126     public void resetObjects(){
    127         for (NativeObjectRef ref : refList){
    128             // here we use the actual obj not the clone,
    129             // otherwise its useless
    130             NativeObject realObj = ref.realObj.get();
    131             if (realObj == null)
    132                 continue;
    133 
    134             realObj.resetObject();
    135             if (logger.isLoggable(Level.FINEST))
    136                 logger.log(Level.FINEST, "Reset: {0}", realObj);
    137         }
    138         refList.clear();
    139     }
    140 
    141 //    public void printObjects(){
    142 //        System.out.println(" ------------------- ");
    143 //        System.out.println(" GL Object count: "+ objectList.size());
    144 //        for (GLObject obj : objectList){
    145 //            System.out.println(obj);
    146 //        }
    147 //    }
    148 }
    149