2626
2727import processing .android .AppComponent ;
2828import processing .core .*;
29-
3029import java .lang .ref .ReferenceQueue ;
3130import java .lang .ref .WeakReference ;
3231import java .net .URL ;
@@ -49,6 +48,43 @@ public class PGraphicsOpenGL extends PGraphics {
4948
5049 // ........................................................
5150
51+ // Disposal of native resources
52+ // Using the technique alternative to finalization described in:
53+ // http://www.oracle.com/technetwork/articles/java/finalization-137655.html
54+ private static ReferenceQueue <Object > refQueue = new ReferenceQueue <>();
55+ private static List <Disposable <? extends Object >> reachableWeakReferences =
56+ new LinkedList <>();
57+
58+ static final private int MAX_DRAIN_GLRES_ITERATIONS = 10 ;
59+
60+ static void drainRefQueueBounded () {
61+ int iterations = 0 ;
62+ while (iterations < MAX_DRAIN_GLRES_ITERATIONS ) {
63+ Disposable <? extends Object > res =
64+ (Disposable <? extends Object >) refQueue .poll ();
65+ if (res == null ) {
66+ break ;
67+ }
68+ res .dispose ();
69+ ++iterations ;
70+ }
71+ }
72+
73+ private static abstract class Disposable <T > extends WeakReference <T > {
74+ protected Disposable (T obj ) {
75+ super (obj , refQueue );
76+ drainRefQueueBounded ();
77+ reachableWeakReferences .add (this );
78+ }
79+
80+ public void dispose () {
81+ reachableWeakReferences .remove (this );
82+ disposeNative ();
83+ }
84+
85+ abstract public void disposeNative ();
86+ }
87+
5288 // Basic rendering parameters:
5389
5490 /** Whether the PGraphics object is ready to render or not. */
@@ -829,55 +865,28 @@ protected void removeFontTexture(PFont font) {
829865
830866 //////////////////////////////////////////////////////////////
831867
832- // RESOURCE HANDLING
833- // Using the technique alternative to finalization described in:
834- // http://www.oracle.com/technetwork/articles/java/finalization-137655.html
835-
836- static final private int MAX_DRAIN_GLRES_ITERATIONS = 10 ;
837868
838- protected static class GLResourceTexture extends WeakReference <Texture > {
869+ protected static class GLResourceTexture extends Disposable <Texture > {
839870 int glName ;
840871
841872 private PGL pgl ;
842873 private int context ;
843874
844- static private ReferenceQueue <Texture > refQueue = new ReferenceQueue <Texture >();
845- static private List <GLResourceTexture > refList = new ArrayList <GLResourceTexture >();
846-
847- static void drainRefQueueBounded () {
848- ReferenceQueue <Texture > refQueue = GLResourceTexture .referenceQueue ();
849- int iterations = 0 ;
850- while (iterations < MAX_DRAIN_GLRES_ITERATIONS ) {
851- GLResourceTexture res = (GLResourceTexture )refQueue .poll ();
852- if (res == null ) {
853- break ;
854- }
855- res .dispose ();
856- ++iterations ;
857- }
858- }
859-
860- static ReferenceQueue <Texture > referenceQueue () {
861- return refQueue ;
862- }
863-
864875 public GLResourceTexture (Texture tex ) {
865- super (tex , refQueue );
876+ super (tex );
866877
867- drainRefQueueBounded ();
868878
869879 pgl = tex .pg .getPrimaryPGL ();
870880 pgl .genTextures (1 , intBuffer );
871881 tex .glName = intBuffer .get (0 );
872882
873883 this .glName = tex .glName ;
874884 this .context = tex .context ;
875-
876- refList .add (this );
877885 }
878886
879- private void disposeNative () {
880- if (pgl != null && pgl .contextIsCurrent (context )) {
887+ @ Override
888+ public void disposeNative () {
889+ if (pgl != null ) {
881890 if (glName != 0 ) {
882891 intBuffer .put (0 , glName );
883892 pgl .deleteTextures (1 , intBuffer );
@@ -887,13 +896,11 @@ private void disposeNative() {
887896 }
888897 }
889898
890- void dispose () {
891- refList .remove (this );
892- disposeNative ();
893- }
894-
895899 @ Override
896900 public boolean equals (Object obj ) {
901+ if (!(obj instanceof GLResourceTexture )) {
902+ return false ;
903+ }
897904 GLResourceTexture other = (GLResourceTexture )obj ;
898905 return other .glName == glName &&
899906 other .context == context ;
@@ -909,49 +916,26 @@ public int hashCode() {
909916 }
910917
911918
912- protected static class GLResourceVertexBuffer extends WeakReference <VertexBuffer > {
919+ protected static class GLResourceVertexBuffer extends Disposable <VertexBuffer > {
913920 int glId ;
914921
915922 private PGL pgl ;
916923 private int context ;
917924
918- static private ReferenceQueue <VertexBuffer > refQueue = new ReferenceQueue <VertexBuffer >();
919- static private List <GLResourceVertexBuffer > refList = new ArrayList <GLResourceVertexBuffer >();
920-
921- static void drainRefQueueBounded () {
922- ReferenceQueue <VertexBuffer > refQueue = GLResourceVertexBuffer .referenceQueue ();
923- int iterations = 0 ;
924- while (iterations < MAX_DRAIN_GLRES_ITERATIONS ) {
925- GLResourceVertexBuffer res = (GLResourceVertexBuffer )refQueue .poll ();
926- if (res == null ) {
927- break ;
928- }
929- res .dispose ();
930- ++iterations ;
931- }
932- }
933-
934- static ReferenceQueue <VertexBuffer > referenceQueue () {
935- return refQueue ;
936- }
937-
938925 public GLResourceVertexBuffer (VertexBuffer vbo ) {
939- super (vbo , refQueue );
940-
941- drainRefQueueBounded ();
926+ super (vbo );
942927
943928 pgl = vbo .pgl .graphics .getPrimaryPGL ();
944929 pgl .genBuffers (1 , intBuffer );
945930 vbo .glId = intBuffer .get (0 );
946931
947932 this .glId = vbo .glId ;
948933 this .context = vbo .context ;
949-
950- refList .add (this );
951934 }
952935
953- private void disposeNative () {
954- if (pgl != null && pgl .contextIsCurrent (context )) {
936+ @ Override
937+ public void disposeNative () {
938+ if (pgl != null ) {
955939 if (glId != 0 ) {
956940 intBuffer .put (0 , glId );
957941 pgl .deleteBuffers (1 , intBuffer );
@@ -961,13 +945,11 @@ private void disposeNative() {
961945 }
962946 }
963947
964- void dispose () {
965- refList .remove (this );
966- disposeNative ();
967- }
968-
969948 @ Override
970949 public boolean equals (Object obj ) {
950+ if (!(obj instanceof GLResourceVertexBuffer )) {
951+ return false ;
952+ }
971953 GLResourceVertexBuffer other = (GLResourceVertexBuffer )obj ;
972954 return other .glId == glId &&
973955 other .context == context ;
@@ -983,38 +965,16 @@ public int hashCode() {
983965 }
984966
985967
986- protected static class GLResourceShader extends WeakReference <PShader > {
968+ protected static class GLResourceShader extends Disposable <PShader > {
987969 int glProgram ;
988970 int glVertex ;
989971 int glFragment ;
990972
991973 private PGL pgl ;
992974 private int context ;
993975
994- static private ReferenceQueue <PShader > refQueue = new ReferenceQueue <PShader >();
995- static private List <GLResourceShader > refList = new ArrayList <GLResourceShader >();
996-
997- static void drainRefQueueBounded () {
998- ReferenceQueue <PShader > refQueue = GLResourceShader .referenceQueue ();
999- int iterations = 0 ;
1000- while (iterations < MAX_DRAIN_GLRES_ITERATIONS ) {
1001- GLResourceShader res = (GLResourceShader )refQueue .poll ();
1002- if (res == null ) {
1003- break ;
1004- }
1005- res .dispose ();
1006- ++iterations ;
1007- }
1008- }
1009-
1010- static ReferenceQueue <PShader > referenceQueue () {
1011- return refQueue ;
1012- }
1013-
1014976 public GLResourceShader (PShader sh ) {
1015- super (sh , refQueue );
1016-
1017- drainRefQueueBounded ();
977+ super (sh );
1018978
1019979 this .pgl = sh .pgl .graphics .getPrimaryPGL ();
1020980 sh .glProgram = pgl .createProgram ();
@@ -1026,12 +986,11 @@ public GLResourceShader(PShader sh) {
1026986 this .glFragment = sh .glFragment ;
1027987
1028988 this .context = sh .context ;
1029-
1030- refList .add (this );
1031989 }
1032990
1033- private void disposeNative () {
1034- if (pgl != null && pgl .contextIsCurrent (context )) {
991+ @ Override
992+ public void disposeNative () {
993+ if (pgl != null ) {
1035994 if (glFragment != 0 ) {
1036995 pgl .deleteShader (glFragment );
1037996 glFragment = 0 ;
@@ -1048,13 +1007,11 @@ private void disposeNative() {
10481007 }
10491008 }
10501009
1051- void dispose () {
1052- refList .remove (this );
1053- disposeNative ();
1054- }
1055-
10561010 @ Override
10571011 public boolean equals (Object obj ) {
1012+ if (!(obj instanceof GLResourceShader )) {
1013+ return false ;
1014+ }
10581015 GLResourceShader other = (GLResourceShader )obj ;
10591016 return other .glProgram == glProgram &&
10601017 other .glVertex == glVertex &&
@@ -1074,7 +1031,7 @@ public int hashCode() {
10741031 }
10751032
10761033
1077- protected static class GLResourceFrameBuffer extends WeakReference <FrameBuffer > {
1034+ protected static class GLResourceFrameBuffer extends Disposable <FrameBuffer > {
10781035 int glFbo ;
10791036 int glDepth ;
10801037 int glStencil ;
@@ -1084,30 +1041,8 @@ protected static class GLResourceFrameBuffer extends WeakReference<FrameBuffer>
10841041 private PGL pgl ;
10851042 private int context ;
10861043
1087- static private ReferenceQueue <FrameBuffer > refQueue = new ReferenceQueue <FrameBuffer >();
1088- static private List <GLResourceFrameBuffer > refList = new ArrayList <GLResourceFrameBuffer >();
1089-
1090- static void drainRefQueueBounded () {
1091- ReferenceQueue <FrameBuffer > refQueue = GLResourceFrameBuffer .referenceQueue ();
1092- int iterations = 0 ;
1093- while (iterations < MAX_DRAIN_GLRES_ITERATIONS ) {
1094- GLResourceFrameBuffer res = (GLResourceFrameBuffer )refQueue .poll ();
1095- if (res == null ) {
1096- break ;
1097- }
1098- res .dispose ();
1099- ++iterations ;
1100- }
1101- }
1102-
1103- static ReferenceQueue <FrameBuffer > referenceQueue () {
1104- return refQueue ;
1105- }
1106-
11071044 public GLResourceFrameBuffer (FrameBuffer fb ) {
1108- super (fb , refQueue );
1109-
1110- drainRefQueueBounded ();
1045+ super (fb );
11111046
11121047 pgl = fb .pg .getPrimaryPGL ();
11131048 if (!fb .screenFb ) {
@@ -1141,12 +1076,11 @@ public GLResourceFrameBuffer(FrameBuffer fb) {
11411076 }
11421077
11431078 this .context = fb .context ;
1144-
1145- refList .add (this );
11461079 }
11471080
1148- private void disposeNative () {
1149- if (pgl != null && pgl .contextIsCurrent (context )) {
1081+ @ Override
1082+ public void disposeNative () {
1083+ if (pgl != null ) {
11501084 if (glFbo != 0 ) {
11511085 intBuffer .put (0 , glFbo );
11521086 pgl .deleteFramebuffers (1 , intBuffer );
@@ -1176,13 +1110,11 @@ private void disposeNative() {
11761110 }
11771111 }
11781112
1179- void dispose () {
1180- refList .remove (this );
1181- disposeNative ();
1182- }
1183-
11841113 @ Override
11851114 public boolean equals (Object obj ) {
1115+ if (!(obj instanceof GLResourceFrameBuffer )) {
1116+ return false ;
1117+ }
11861118 GLResourceFrameBuffer other = (GLResourceFrameBuffer )obj ;
11871119 return other .glFbo == glFbo &&
11881120 other .glDepth == glDepth &&
0 commit comments