26
26
27
27
import processing .android .AppComponent ;
28
28
import processing .core .*;
29
-
30
29
import java .lang .ref .ReferenceQueue ;
31
30
import java .lang .ref .WeakReference ;
32
31
import java .net .URL ;
@@ -49,6 +48,43 @@ public class PGraphicsOpenGL extends PGraphics {
49
48
50
49
// ........................................................
51
50
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
+
52
88
// Basic rendering parameters:
53
89
54
90
/** Whether the PGraphics object is ready to render or not. */
@@ -829,55 +865,28 @@ protected void removeFontTexture(PFont font) {
829
865
830
866
//////////////////////////////////////////////////////////////
831
867
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 ;
837
868
838
- protected static class GLResourceTexture extends WeakReference <Texture > {
869
+ protected static class GLResourceTexture extends Disposable <Texture > {
839
870
int glName ;
840
871
841
872
private PGL pgl ;
842
873
private int context ;
843
874
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
-
864
875
public GLResourceTexture (Texture tex ) {
865
- super (tex , refQueue );
876
+ super (tex );
866
877
867
- drainRefQueueBounded ();
868
878
869
879
pgl = tex .pg .getPrimaryPGL ();
870
880
pgl .genTextures (1 , intBuffer );
871
881
tex .glName = intBuffer .get (0 );
872
882
873
883
this .glName = tex .glName ;
874
884
this .context = tex .context ;
875
-
876
- refList .add (this );
877
885
}
878
886
879
- private void disposeNative () {
880
- if (pgl != null && pgl .contextIsCurrent (context )) {
887
+ @ Override
888
+ public void disposeNative () {
889
+ if (pgl != null ) {
881
890
if (glName != 0 ) {
882
891
intBuffer .put (0 , glName );
883
892
pgl .deleteTextures (1 , intBuffer );
@@ -887,13 +896,11 @@ private void disposeNative() {
887
896
}
888
897
}
889
898
890
- void dispose () {
891
- refList .remove (this );
892
- disposeNative ();
893
- }
894
-
895
899
@ Override
896
900
public boolean equals (Object obj ) {
901
+ if (!(obj instanceof GLResourceTexture )) {
902
+ return false ;
903
+ }
897
904
GLResourceTexture other = (GLResourceTexture )obj ;
898
905
return other .glName == glName &&
899
906
other .context == context ;
@@ -909,49 +916,26 @@ public int hashCode() {
909
916
}
910
917
911
918
912
- protected static class GLResourceVertexBuffer extends WeakReference <VertexBuffer > {
919
+ protected static class GLResourceVertexBuffer extends Disposable <VertexBuffer > {
913
920
int glId ;
914
921
915
922
private PGL pgl ;
916
923
private int context ;
917
924
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
-
938
925
public GLResourceVertexBuffer (VertexBuffer vbo ) {
939
- super (vbo , refQueue );
940
-
941
- drainRefQueueBounded ();
926
+ super (vbo );
942
927
943
928
pgl = vbo .pgl .graphics .getPrimaryPGL ();
944
929
pgl .genBuffers (1 , intBuffer );
945
930
vbo .glId = intBuffer .get (0 );
946
931
947
932
this .glId = vbo .glId ;
948
933
this .context = vbo .context ;
949
-
950
- refList .add (this );
951
934
}
952
935
953
- private void disposeNative () {
954
- if (pgl != null && pgl .contextIsCurrent (context )) {
936
+ @ Override
937
+ public void disposeNative () {
938
+ if (pgl != null ) {
955
939
if (glId != 0 ) {
956
940
intBuffer .put (0 , glId );
957
941
pgl .deleteBuffers (1 , intBuffer );
@@ -961,13 +945,11 @@ private void disposeNative() {
961
945
}
962
946
}
963
947
964
- void dispose () {
965
- refList .remove (this );
966
- disposeNative ();
967
- }
968
-
969
948
@ Override
970
949
public boolean equals (Object obj ) {
950
+ if (!(obj instanceof GLResourceVertexBuffer )) {
951
+ return false ;
952
+ }
971
953
GLResourceVertexBuffer other = (GLResourceVertexBuffer )obj ;
972
954
return other .glId == glId &&
973
955
other .context == context ;
@@ -983,38 +965,16 @@ public int hashCode() {
983
965
}
984
966
985
967
986
- protected static class GLResourceShader extends WeakReference <PShader > {
968
+ protected static class GLResourceShader extends Disposable <PShader > {
987
969
int glProgram ;
988
970
int glVertex ;
989
971
int glFragment ;
990
972
991
973
private PGL pgl ;
992
974
private int context ;
993
975
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
-
1014
976
public GLResourceShader (PShader sh ) {
1015
- super (sh , refQueue );
1016
-
1017
- drainRefQueueBounded ();
977
+ super (sh );
1018
978
1019
979
this .pgl = sh .pgl .graphics .getPrimaryPGL ();
1020
980
sh .glProgram = pgl .createProgram ();
@@ -1026,12 +986,11 @@ public GLResourceShader(PShader sh) {
1026
986
this .glFragment = sh .glFragment ;
1027
987
1028
988
this .context = sh .context ;
1029
-
1030
- refList .add (this );
1031
989
}
1032
990
1033
- private void disposeNative () {
1034
- if (pgl != null && pgl .contextIsCurrent (context )) {
991
+ @ Override
992
+ public void disposeNative () {
993
+ if (pgl != null ) {
1035
994
if (glFragment != 0 ) {
1036
995
pgl .deleteShader (glFragment );
1037
996
glFragment = 0 ;
@@ -1048,13 +1007,11 @@ private void disposeNative() {
1048
1007
}
1049
1008
}
1050
1009
1051
- void dispose () {
1052
- refList .remove (this );
1053
- disposeNative ();
1054
- }
1055
-
1056
1010
@ Override
1057
1011
public boolean equals (Object obj ) {
1012
+ if (!(obj instanceof GLResourceShader )) {
1013
+ return false ;
1014
+ }
1058
1015
GLResourceShader other = (GLResourceShader )obj ;
1059
1016
return other .glProgram == glProgram &&
1060
1017
other .glVertex == glVertex &&
@@ -1074,7 +1031,7 @@ public int hashCode() {
1074
1031
}
1075
1032
1076
1033
1077
- protected static class GLResourceFrameBuffer extends WeakReference <FrameBuffer > {
1034
+ protected static class GLResourceFrameBuffer extends Disposable <FrameBuffer > {
1078
1035
int glFbo ;
1079
1036
int glDepth ;
1080
1037
int glStencil ;
@@ -1084,30 +1041,8 @@ protected static class GLResourceFrameBuffer extends WeakReference<FrameBuffer>
1084
1041
private PGL pgl ;
1085
1042
private int context ;
1086
1043
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
-
1107
1044
public GLResourceFrameBuffer (FrameBuffer fb ) {
1108
- super (fb , refQueue );
1109
-
1110
- drainRefQueueBounded ();
1045
+ super (fb );
1111
1046
1112
1047
pgl = fb .pg .getPrimaryPGL ();
1113
1048
if (!fb .screenFb ) {
@@ -1141,12 +1076,11 @@ public GLResourceFrameBuffer(FrameBuffer fb) {
1141
1076
}
1142
1077
1143
1078
this .context = fb .context ;
1144
-
1145
- refList .add (this );
1146
1079
}
1147
1080
1148
- private void disposeNative () {
1149
- if (pgl != null && pgl .contextIsCurrent (context )) {
1081
+ @ Override
1082
+ public void disposeNative () {
1083
+ if (pgl != null ) {
1150
1084
if (glFbo != 0 ) {
1151
1085
intBuffer .put (0 , glFbo );
1152
1086
pgl .deleteFramebuffers (1 , intBuffer );
@@ -1176,13 +1110,11 @@ private void disposeNative() {
1176
1110
}
1177
1111
}
1178
1112
1179
- void dispose () {
1180
- refList .remove (this );
1181
- disposeNative ();
1182
- }
1183
-
1184
1113
@ Override
1185
1114
public boolean equals (Object obj ) {
1115
+ if (!(obj instanceof GLResourceFrameBuffer )) {
1116
+ return false ;
1117
+ }
1186
1118
GLResourceFrameBuffer other = (GLResourceFrameBuffer )obj ;
1187
1119
return other .glFbo == glFbo &&
1188
1120
other .glDepth == glDepth &&
0 commit comments