Revision: 2550
http://sourceforge.net/p/swingme/code/2550
Author: yuranet
Date: 2021-07-28 21:49:27 +0000 (Wed, 28 Jul 2021)
Log Message:
-----------
autorelease all iOS refs
Modified Paths:
--------------
iOSME/src/android/graphics/ColorMatrix.java
iOSME/src/javax/microedition/lcdui/Image.java
Modified: iOSME/src/android/graphics/ColorMatrix.java
===================================================================
--- iOSME/src/android/graphics/ColorMatrix.java 2021-07-28 19:32:47 UTC (rev 2549)
+++ iOSME/src/android/graphics/ColorMatrix.java 2021-07-28 21:49:27 UTC (rev 2550)
@@ -1,5 +1,6 @@
package android.graphics;
+import org.moe.natj.objc.ObjCRuntime;
import java.util.Arrays;
import apple.coreimage.CIFilter;
import apple.coreimage.CIVector;
@@ -181,6 +182,8 @@
*/
public CIFilter toCIFilter() {
+ long pool = ObjCRuntime.createAutoreleasePool();
+
CIFilter filter = CIFilter.filterWithName("CIColorMatrix");
CIVector rVector = CIVector.vectorWithXYZW(mArray[0], mArray[1], mArray[2], mArray[3]);
CIVector gVector = CIVector.vectorWithXYZW(mArray[5], mArray[6], mArray[7], mArray[8]);
@@ -194,6 +197,9 @@
filter.setValueForKey(aVector, "inputAVector");
filter.setValueForKey(inputBiasVector, "inputBiasVector");
+ // clear all autorelease referances and only keep java ones
+ ObjCRuntime.releaseAutoreleasePool(pool);
+
return filter;
}
}
Modified: iOSME/src/javax/microedition/lcdui/Image.java
===================================================================
--- iOSME/src/javax/microedition/lcdui/Image.java 2021-07-28 19:32:47 UTC (rev 2549)
+++ iOSME/src/javax/microedition/lcdui/Image.java 2021-07-28 21:49:27 UTC (rev 2550)
@@ -54,58 +54,66 @@
public static Image createImage(String resource) throws IOException {
- // try load any image that may be in a group
- UIImage img = UIImage.imageNamed(resource.startsWith("/") ? resource.substring(1) : resource);
- if (img != null) {
- return new Image(img);
- }
+ long pool = ObjCRuntime.createAutoreleasePool();
+ try {
- // for images that are copied during build step, they are in a folder not a group, so we need to have a folder name
- // https://stackoverflow.com/questions/11499925/uiimage-imagenamed-does-not-find-image-within-blue-referenced-xcode-folder
- img = UIImage.imageNamed("Graphics" + resource);
+ // try load any image that may be in a group
+ UIImage img = UIImage.imageNamed(resource.startsWith("/") ? resource.substring(1) : resource);
+ if (img != null) {
+ return new Image(img);
+ }
- if (img != null) {
+ // for images that are copied during build step, they are in a folder not a group, so we need to have a folder name
+ // https://stackoverflow.com/questions/11499925/uiimage-imagenamed-does-not-find-image-within-blue-referenced-xcode-folder
+ img = UIImage.imageNamed("Graphics" + resource);
- if (img.size().width() % 1 != 0 || img.size().height() % 1 != 0) {
- System.out.println("WARN strange image size " + resource + " " + UIKit.NSStringFromCGSize(img.size()));
- }
+ if (img != null) {
- if (resource.endsWith(".9.png") && img.scale() != 1.0) {
- img = grow9patch(img);
- if (img.scale() == 3.0) {
+ if (img.size().width() % 1 != 0 || img.size().height() % 1 != 0) {
+ System.out.println("WARN strange image size " + resource + " " + UIKit.NSStringFromCGSize(img.size()));
+ }
+
+ if (resource.endsWith(".9.png") && img.scale() != 1.0) {
img = grow9patch(img);
+ if (img.scale() == 3.0) {
+ img = grow9patch(img);
+ }
}
+
+ return new Image(img);
}
- return new Image(img);
- }
-
/* can do this with newer versions of java
- URL url = Image.class.getResource(resource);
- if (url != null) {
- try {
- Path path = Paths.get(url.toURI());
- byte[] bytes = Files.readAllBytes(path);
+ URL url = Image.class.getResource(resource);
+ if (url != null) {
+ try {
+ Path path = Paths.get(url.toURI());
+ byte[] bytes = Files.readAllBytes(path);
- // https://discuss.multi-os-engine.org/t/stream-to-nsdata-and-moe-pointer-magic/306
- BytePtr ptr = PtrFactory.newByteArray(bytes);
- NSData data = NSData.dataWithBytesLength( ptr, bytes.length );
- UIImage image = UIImage.imageWithData( data );
- return new Image(image);
+ // https://discuss.multi-os-engine.org/t/stream-to-nsdata-and-moe-pointer-magic/306
+ BytePtr ptr = PtrFactory.newByteArray(bytes);
+ NSData data = NSData.dataWithBytesLength( ptr, bytes.length );
+ UIImage image = UIImage.imageWithData( data );
+ return new Image(image);
+ }
+ catch (Exception ex) {
+ throw new IOException(ex);
+ }
}
- catch (Exception ex) {
- throw new IOException(ex);
- }
- }
*/
- InputStream in = Image.class.getResourceAsStream(resource);
- if (in == null) {
- throw new IOException("can not find: " + resource);
+ InputStream in = Image.class.getResourceAsStream(resource);
+ if (in == null) {
+ throw new IOException("can not find: " + resource);
+ }
+ Image image = createImage(in);
+ in.close();
+ return image;
+
}
- Image image = createImage(in);
- in.close();
- return image;
+ finally {
+ ObjCRuntime.releaseAutoreleasePool(pool);
+ }
}
private static UIImage grow9patch(UIImage img) {
@@ -155,21 +163,27 @@
public static Image createImage(byte[] imgData, int offset, int length) {
- // https://discuss.multi-os-engine.org/t/stream-to-nsdata-and-moe-pointer-magic/306
- BytePtr ptr;
- if (offset == 0 && length == imgData.length) {
- ptr = PtrFactory.newByteArray(imgData);
+ long pool = ObjCRuntime.createAutoreleasePool();
+ try {
+
+ // https://discuss.multi-os-engine.org/t/stream-to-nsdata-and-moe-pointer-magic/306
+ BytePtr ptr;
+ if (offset == 0 && length == imgData.length) {
+ ptr = PtrFactory.newByteArray(imgData);
+ } else {
+ ptr = PtrFactory.newByteArray(length);
+ ptr.copyFrom(imgData, offset, 0, length);
+ }
+ NSData data = NSData.dataWithBytesLength(ptr, length);
+ UIImage image = UIImage.imageWithData(data);
+ if (image == null) {
+ throw new IllegalArgumentException("failed to make image from " + imgData + " " + offset + " " + length);
+ }
+ return new Image(image);
}
- else {
- ptr = PtrFactory.newByteArray(length);
- ptr.copyFrom(imgData, offset, 0, length);
+ finally {
+ ObjCRuntime.releaseAutoreleasePool(pool);
}
- NSData data = NSData.dataWithBytesLength(ptr, length);
- UIImage image = UIImage.imageWithData(data);
- if (image == null) {
- throw new IllegalArgumentException("failed to make image from " + imgData + " " + offset + " " + length);
- }
- return new Image(image);
}
public static Image createImage(Image image, int x, int y, int width, int height, int transform) {
@@ -177,13 +191,11 @@
throw new IllegalArgumentException("Area out of Image: "+image.getWidth()+"x"+image.getHeight()+" area: "+x+","+y+" "+width+"x"+height);
}
- // TODO only do this if image is immutable
UIImage newImg = image.getUIImage(x, y, width, height, transform);
return new Image(newImg);
}
public static Image createImage(int width, int height) {
-
UIKit.UIGraphicsBeginImageContext(new CGSize(width, height));
CGContextRef context = UIKit.UIGraphicsGetCurrentContext();
@@ -220,11 +232,6 @@
}
}
- @Override
- public String toString() {
- return "Image{mutable=" + mutable + " " + uiImage + " " + context + "}";
- }
-
public boolean isMutable() {
//return uiImage == null || uiImage.scale() == 1.0;
return mutable;
@@ -244,14 +251,6 @@
return (int) uiImage.size().height();
}
- private int getIntsPerRow() {
- long bytesPerRow = CoreGraphics.CGBitmapContextGetBytesPerRow(context);
- if (bytesPerRow % 4 != 0) {
- throw new IllegalStateException("odd number of bytes per row " + bytesPerRow);
- }
- return (int) bytesPerRow / 4;
- }
-
public synchronized Graphics getGraphics() {
if (!isMutable()) {
throw new IllegalStateException("Image is immutable");
@@ -259,8 +258,6 @@
// we must have used a image to draw, we need to clear it before we draw again to this context
if (uiImage != null) {
- //System.out.println("release image " + CoreFoundation.CFGetRetainCount(uiImage.CGImage()));
- CoreGraphics.CGImageRelease(uiImage.CGImage());
releaseUIImage();
}
@@ -274,23 +271,6 @@
* somehow prevented from being called at the same time as that would lead to possible images being created
* from the context as the same time as the context is being created for background threads to access img data
*/
- private synchronized void loadImageIntoGraphicsContext() {
- // the image has already been loaded into the context, do nothing
- if (context != null) {
- return;
- }
-
- // load the current image into the context
- UIKit.UIGraphicsBeginImageContext(new CGSize(getWidth(), getHeight()));
- context = UIKit.UIGraphicsGetCurrentContext();
- CoreGraphics.CGContextRetain(context);
-
- // this is needed for 9-patches to load correctly
- CoreGraphics.CGContextSetInterpolationQuality(context, CGInterpolationQuality.None);
-
- uiImage.drawAtPoint(CoreGraphics.CGPointZero());
- }
-
public synchronized UIImage getUIImage() {
// if image is imutable, we must have used the context just to get data, its safe to get rid of the context then.
@@ -312,49 +292,53 @@
*/
CGImageRef cgImageRef = CoreGraphics.CGBitmapContextCreateImage(context);
+ long pool = ObjCRuntime.createAutoreleasePool();
uiImage = UIImage.imageWithCGImage(cgImageRef);
+ ObjCRuntime.releaseAutoreleasePool(pool);
+
+ CoreGraphics.CGImageRelease(cgImageRef);
return uiImage;
+ }
-/*
- // if we have a context open we need to close it
- if (context != null) {
+ public UIImage getUIImage(int xSrc, int ySrc, int width, int height, int transform) {
+ UIImage start = getUIImage();
+ double scale = start.scale();
+ CGRect srcRect = new CGRect(new CGPoint(scale * xSrc, scale * ySrc), new CGSize(scale * width, scale * height));
+ CGImageRef cropped = CoreGraphics.CGImageCreateWithImageInRect(start.CGImage(), srcRect);
- CGContextRef current = UIKit.UIGraphicsGetCurrentContext();
- boolean same = current != null && current.getPeer().equals(context.getPeer());
- if (!same) UIKit.UIGraphicsPushContext(context);
+ long pool = ObjCRuntime.createAutoreleasePool();
+ UIImage transformed;
+ if (transform == Sprite.TRANS_NONE && scale == 1.0) {
+ transformed = UIImage.imageWithCGImage(cropped);
+ }
+ else {
+ transformed = UIImage.imageWithCGImageScaleOrientation(cropped, scale, Graphics.getUIImageOrientation(transform));
+ }
+ ObjCRuntime.releaseAutoreleasePool(pool);
- // we may have created a context just to get data from the image
- // but if not, we need to get the image back from the context
- if (uiImage == null) {
- uiImage = UIKit.UIGraphicsGetImageFromCurrentImageContext();
- if (uiImage == null) {
- System.out.println("WARN UIKit not returning image, context matches: " + same);
+ CoreGraphics.CGImageRelease(cropped); // TODO not sure if needed as we neveer called Retain
- CGImageRef cgImageRef = CoreGraphics.CGBitmapContextCreateImage(context);
-
- if (cgImageRef == null) {
- throw new IllegalStateException("failed to get image from context " + context);
- }
-
- uiImage = UIImage.imageWithCGImage(cgImageRef);
- }
- }
-
- UIKit.UIGraphicsEndImageContext();
- CoreGraphics.CGContextRelease(context);
- context = null;
+ if (transformed.scale() != scale || (transformed.size().width() != width && transformed.size().width() != height)) {
+ throw new IllegalStateException("scale is not correct " + transformed.scale() +"="+ start.scale() +" "+ transformed.size().width() +"="+ width +" "+ transformed.size().height() +"="+ height);
}
- return uiImage;
-*/
+ return transformed;
}
+ @Override
+ public String toString() {
+ return "Image{mutable=" + mutable + " " + uiImage + " " + context + "}";
+ }
+
private void releaseCGContext() {
- context.free();
+ CoreGraphics.CGContextRelease(context);
context = null;
}
private void releaseUIImage() {
+ // as we always created UIImages inside pools, only java holds the referances to the objects
+ // so when we release them in java (through GC), they will also get released in iOS
+ // https://www.noisyfox.io/natj-memory-management.html
uiImage = null;
}
@@ -369,25 +353,12 @@
super.finalize();
}
- public UIImage getUIImage(int xSrc, int ySrc, int width, int height, int transform) {
- UIImage start = getUIImage();
- double scale = start.scale();
- CGRect srcRect = new CGRect(new CGPoint(scale * xSrc, scale * ySrc), new CGSize(scale * width, scale * height));
- CGImageRef cropped = CoreGraphics.CGImageCreateWithImageInRect(start.CGImage(), srcRect);
- UIImage transformed;
- if (transform == Sprite.TRANS_NONE && scale == 1.0) {
- transformed = UIImage.imageWithCGImage(cropped);
+ private int getIntsPerRow() {
+ long bytesPerRow = CoreGraphics.CGBitmapContextGetBytesPerRow(context);
+ if (bytesPerRow % 4 != 0) {
+ throw new IllegalStateException("odd number of bytes per row " + bytesPerRow);
}
- else {
- transformed = UIImage.imageWithCGImageScaleOrientation(cropped, scale, Graphics.getUIImageOrientation(transform));
- }
- CoreGraphics.CGImageRelease(cropped); // TODO not sure if needed as we neveer called Retain
-
- if (transformed.scale() != scale || (transformed.size().width() != width && transformed.size().width() != height)) {
- throw new IllegalStateException("scale is not correct " + transformed.scale() +"="+ start.scale() +" "+ transformed.size().width() +"="+ width +" "+ transformed.size().height() +"="+ height);
- }
-
- return transformed;
+ return (int) bytesPerRow / 4;
}
public void getRGB(int[] rgb, int offset, int distScanLength, int x, int y, int width, int height) {
@@ -405,8 +376,21 @@
}
*/
- loadImageIntoGraphicsContext();
+ synchronized (this) {
+ // if the image has already been loaded into the context, do nothing
+ if (context == null) {
+ // load the current image into the context
+ UIKit.UIGraphicsBeginImageContext(new CGSize(getWidth(), getHeight()));
+ context = UIKit.UIGraphicsGetCurrentContext();
+ CoreGraphics.CGContextRetain(context);
+ // this is needed for 9-patches to load correctly
+ CoreGraphics.CGContextSetInterpolationQuality(context, CGInterpolationQuality.None);
+
+ uiImage.drawAtPoint(CoreGraphics.CGPointZero());
+ }
+ }
+
//CoreGraphics.CGBitmapContextGetBitsPerComponent(context); // 8
//CoreGraphics.CGBitmapContextGetBitsPerPixel(context); // 32
int srcScanLenght = getIntsPerRow();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|