// Path: systemlib/src/main/java/android/graphics/RecordingCanvas.java
// public class RecordingCanvas extends Canvas {
//   private static final int POOL_LIMIT = 25;
//   private static final Pools.SynchronizedPool<RecordingCanvas> sPool =
//       new Pools.SynchronizedPool<>(POOL_LIMIT);
// 
// 
//   public void enableZ() {
//   }
// 
//   public void disableZ() {
//   }
// 
//   public void drawRenderNode(RenderNode renderNode) {
//   }
// }
// 
// Path: systemlib/src/main/java/android/util/Pools.java
// public final class Pools {
// 
//   /**
//    * Interface for managing a pool of objects.
//    *
//    * @param <T> The pooled type.
//    */
//   public static interface Pool<T> {
// 
//     /**
//      * @return An instance from the pool if such, null otherwise.
//      */
//     public T acquire();
// 
//     /**
//      * Release an instance to the pool.
//      *
//      * @param instance The instance to release.
//      * @return Whether the instance was put in the pool.
//      * @throws IllegalStateException If the instance is already in the pool.
//      */
//     public boolean release(T instance);
//   }
// 
//   private Pools() {
//     /* do nothing - hiding constructor */
//   }
// 
//   /**
//    * Simple (non-synchronized) pool of objects.
//    *
//    * @param <T> The pooled type.
//    */
//   public static class SimplePool<T> implements Pool<T> {
//     private final Object[] mPool;
// 
//     private int mPoolSize;
// 
//     /**
//      * Creates a new instance.
//      *
//      * @param maxPoolSize The max pool size.
//      * @throws IllegalArgumentException If the max pool size is less than zero.
//      */
//     public SimplePool(int maxPoolSize) {
//       if (maxPoolSize <= 0) {
//         throw new IllegalArgumentException("The max pool size must be > 0");
//       }
//       mPool = new Object[maxPoolSize];
//     }
// 
//     @Override
//     @SuppressWarnings("unchecked")
//     public T acquire() {
//       if (mPoolSize > 0) {
//         final int lastPooledIndex = mPoolSize - 1;
//         T instance = (T) mPool[lastPooledIndex];
//         mPool[lastPooledIndex] = null;
//         mPoolSize--;
//         return instance;
//       }
//       return null;
//     }
// 
//     @Override
//     public boolean release(T instance) {
//       if (isInPool(instance)) {
//         throw new IllegalStateException("Already in the pool!");
//       }
//       if (mPoolSize < mPool.length) {
//         mPool[mPoolSize] = instance;
//         mPoolSize++;
//         return true;
//       }
//       return false;
//     }
// 
//     private boolean isInPool(T instance) {
//       for (int i = 0; i < mPoolSize; i++) {
//         if (mPool[i] == instance) {
//           return true;
//         }
//       }
//       return false;
//     }
//   }
// 
//   /**
//    * Synchronized pool of objects.
//    *
//    * @param <T> The pooled type.
//    */
//   public static class SynchronizedPool<T> extends SimplePool<T> {
//     private final Object mLock;
// 
//     /**
//      * Creates a new instance.
//      *
//      * @param maxPoolSize The max pool size.
//      * @param lock        an optional custom object to synchronize on
//      * @throws IllegalArgumentException If the max pool size is less than zero.
//      */
//     public SynchronizedPool(int maxPoolSize, Object lock) {
//       super(maxPoolSize);
//       mLock = lock;
//     }
// 
//     /**
//      * @see #SynchronizedPool(int, Object)
//      */
//     public SynchronizedPool(int maxPoolSize) {
//       this(maxPoolSize, new Object());
//     }
// 
//     @Override
//     public T acquire() {
//       synchronized (mLock) {
//         return super.acquire();
//       }
//     }
// 
//     @Override
//     public boolean release(T element) {
//       synchronized (mLock) {
//         return super.release(element);
//       }
//     }
//   }
// }
// 
// Path: systemlib/src/main/java/android/view/DisplayListCanvas.java
// public class DisplayListCanvas extends Canvas {
// 
//   private static final int POOL_LIMIT = 25;
//   //android 6.0,7.0,7.1,8.0,8.1,9.0
//   private static final Pools.SynchronizedPool<DisplayListCanvas> sPool =
//       new Pools.SynchronizedPool<DisplayListCanvas>(POOL_LIMIT);
// 
//   public void onPreDraw(Rect dirty) {
//   }
// 
//   public void insertReorderBarrier() {
//   }
// 
//   public void insertInorderBarrier() {
//   }
// 
//   public void drawRenderNode(RenderNode renderNode) {
//   }
// }


import android.graphics.Canvas;
import android.graphics.RecordingCanvas;
import android.os.Build;
import android.util.Pools;
import android.view.DisplayListCanvas;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
package com.wanjian.sak.system.canvaspool;



public class CanvasPoolCompact {
  private static CanvasPoolCompact sInstance = new CanvasPoolCompact();

  public static CanvasPoolCompact get() {
    return sInstance;
  }

  private List<WeakReference<CanvasRecycleListener>> listeners = new ArrayList<>();

  private CanvasPoolCompact() {
    Class clz;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      clz = RecordingCanvas.class;
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      clz = DisplayListCanvas.class;
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      try {
        clz = Class.forName("android.view.GLES20RecordingCanvas");
      } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
      }
    } else {
      throw new RuntimeException();
    }
    final Pools.SynchronizedPool origin;
    Field field;
    try {
      field = clz.getDeclaredField("sPool");
      field.setAccessible(true);
// Path: systemlib/src/main/java/android/graphics/RecordingCanvas.java
// public class RecordingCanvas extends Canvas {
//   private static final int POOL_LIMIT = 25;
//   private static final Pools.SynchronizedPool<RecordingCanvas> sPool =
//       new Pools.SynchronizedPool<>(POOL_LIMIT);
// 
// 
//   public void enableZ() {
//   }
// 
//   public void disableZ() {
//   }
// 
//   public void drawRenderNode(RenderNode renderNode) {
//   }
// }
// 
// Path: systemlib/src/main/java/android/util/Pools.java
// public final class Pools {
// 
//   /**
//    * Interface for managing a pool of objects.
//    *
//    * @param <T> The pooled type.
//    */
//   public static interface Pool<T> {
// 
//     /**
//      * @return An instance from the pool if such, null otherwise.
//      */
//     public T acquire();
// 
//     /**
//      * Release an instance to the pool.
//      *
//      * @param instance The instance to release.
//      * @return Whether the instance was put in the pool.
//      * @throws IllegalStateException If the instance is already in the pool.
//      */
//     public boolean release(T instance);
//   }
// 
//   private Pools() {
//     /* do nothing - hiding constructor */
//   }
// 
//   /**
//    * Simple (non-synchronized) pool of objects.
//    *
//    * @param <T> The pooled type.
//    */
//   public static class SimplePool<T> implements Pool<T> {
//     private final Object[] mPool;
// 
//     private int mPoolSize;
// 
//     /**
//      * Creates a new instance.
//      *
//      * @param maxPoolSize The max pool size.
//      * @throws IllegalArgumentException If the max pool size is less than zero.
//      */
//     public SimplePool(int maxPoolSize) {
//       if (maxPoolSize <= 0) {
//         throw new IllegalArgumentException("The max pool size must be > 0");
//       }
//       mPool = new Object[maxPoolSize];
//     }
// 
//     @Override
//     @SuppressWarnings("unchecked")
//     public T acquire() {
//       if (mPoolSize > 0) {
//         final int lastPooledIndex = mPoolSize - 1;
//         T instance = (T) mPool[lastPooledIndex];
//         mPool[lastPooledIndex] = null;
//         mPoolSize--;
//         return instance;
//       }
//       return null;
//     }
// 
//     @Override
//     public boolean release(T instance) {
//       if (isInPool(instance)) {
//         throw new IllegalStateException("Already in the pool!");
//       }
//       if (mPoolSize < mPool.length) {
//         mPool[mPoolSize] = instance;
//         mPoolSize++;
//         return true;
//       }
//       return false;
//     }
// 
//     private boolean isInPool(T instance) {
//       for (int i = 0; i < mPoolSize; i++) {
//         if (mPool[i] == instance) {
//           return true;
//         }
//       }
//       return false;
//     }
//   }
// 
//   /**
//    * Synchronized pool of objects.
//    *
//    * @param <T> The pooled type.
//    */
//   public static class SynchronizedPool<T> extends SimplePool<T> {
//     private final Object mLock;
// 
//     /**
//      * Creates a new instance.
//      *
//      * @param maxPoolSize The max pool size.
//      * @param lock        an optional custom object to synchronize on
//      * @throws IllegalArgumentException If the max pool size is less than zero.
//      */
//     public SynchronizedPool(int maxPoolSize, Object lock) {
//       super(maxPoolSize);
//       mLock = lock;
//     }
// 
//     /**
//      * @see #SynchronizedPool(int, Object)
//      */
//     public SynchronizedPool(int maxPoolSize) {
//       this(maxPoolSize, new Object());
//     }
// 
//     @Override
//     public T acquire() {
//       synchronized (mLock) {
//         return super.acquire();
//       }
//     }
// 
//     @Override
//     public boolean release(T element) {
//       synchronized (mLock) {
//         return super.release(element);
//       }
//     }
//   }
// }
// 
// Path: systemlib/src/main/java/android/view/DisplayListCanvas.java
// public class DisplayListCanvas extends Canvas {
// 
//   private static final int POOL_LIMIT = 25;
//   //android 6.0,7.0,7.1,8.0,8.1,9.0
//   private static final Pools.SynchronizedPool<DisplayListCanvas> sPool =
//       new Pools.SynchronizedPool<DisplayListCanvas>(POOL_LIMIT);
// 
//   public void onPreDraw(Rect dirty) {
//   }
// 
//   public void insertReorderBarrier() {
//   }
// 
//   public void insertInorderBarrier() {
//   }
// 
//   public void drawRenderNode(RenderNode renderNode) {
//   }
// }


// Path: saklib/src/main/java/com/wanjian/sak/system/canvaspool/CanvasPoolCompact.java
import android.graphics.Canvas;
import android.graphics.RecordingCanvas;
import android.os.Build;
import android.util.Pools;
import android.view.DisplayListCanvas;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

package com.wanjian.sak.system.canvaspool;



public class CanvasPoolCompact {
  private static CanvasPoolCompact sInstance = new CanvasPoolCompact();

  public static CanvasPoolCompact get() {
    return sInstance;
  }

  private List<WeakReference<CanvasRecycleListener>> listeners = new ArrayList<>();

  private CanvasPoolCompact() {
    Class clz;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      clz = RecordingCanvas.class;
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      clz = DisplayListCanvas.class;
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      try {
        clz = Class.forName("android.view.GLES20RecordingCanvas");
      } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
      }
    } else {
      throw new RuntimeException();
    }
    final Pools.SynchronizedPool origin;
    Field field;
    try {
      field = clz.getDeclaredField("sPool");
      field.setAccessible(true);
      origin = (Pools.SynchronizedPool) field.get(null);