-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Textures/bitmaps partially loading #25
Comments
Additional info, we have found the error exists in (atleast) air 21,23,24,25,27 The actual error appears appears to be in the bitmap data of the texture object, not the bitmap data that we load from png. If we see a discrepancy between the two assessed by looking for the area of non blank pixels, we know the error has occurred:
Where bmpdata 1 and 2 represent the source bitmapdata, and the bitmapdata on the texture object (GTexture in our case as we are using the Genome2d framework). The error can be fixed by recreating the texture with the source bitmap again. This is obviously not ideal as it's slow and ugly, but maybe it's of help to people. |
Anecdotally, this seems to happen the first time I launch my game on a new device, or after a restart. Quitting and restarting the game fixes the issue. Uninstalling and reinstalling makes it come back. Restarting the device makes it come back. |
@FatRedBird how do you obtain the texture object's BitmapData? Flash's |
I'm using the Genom2d framework for my rendering. GTexture has a bitmapdata property. For a while I also believed it was caused primarilly on first run of a game, however I now beliebe it happens when the app is demanding a lot of RAM. In our first run we tend to have more texture sheets being loaded and disposed due to intro animations. |
Tim Conkling created a sample project that exhibits this bug on his Nvidia shield. It's available here on Github. He also shot a video of demonstrating the bug using this sample project. It's here on Youtube. Thanks a lot for your efforts, Tim! |
@FatRedBird - I've been spending a lot of time with this bug over the last week, and what I've found is that the issue is actually occurring during bitmap loading, and not during texture creation. Using the technique you described above, I compare the non-transparent pixel bounds of my loaded bitmaps to the textures I create from them. In all cases, the bounds are the same. However, when the bug is triggered, the non-transparent bounds of the original loaded bitmap differ from what that bitmap's contents are on disk -- it's the bitmaps themselves that are being loaded incorrectly. The workaround I've just implemented, which accurately detects the issue, tests bitmaps as they're loaded, and reloads them, after a brief timeout, if they're cropped. The major irritation here is that your game needs to know what the bottom-most non-transparent pixel row is for each of your bitmaps. (My game uses texture atlases that are not always completely filled, so the bottom-most non transparent pixel row, for me, is generally not the bottom row of the bitmap.) Here's a snippet of my validation code, to illustrate what I mean: public function doNextLoad () :BitmapLoader {
_numTries++;
var loader :BitmapLoader = new BitmapLoader(_urlOrByteArray);
loader.begin().onSuccess(validateBitmap).onFailure(_result.fail);
return loader;
}
public function validateBitmap (bitmapData :BitmapData) :void {
var bottomRow :Number = getBottomPixelRow(bitmapData);
var valid :Boolean = (_expectedBottomRow - bottomRow < 1);
if (valid || _numTries >= MAX_TRIES) {
if (!valid) {
log.warning("Succeeding with broken texture",
"name", _name, "percentLoaded", (bottomRow / _expectedBottomRow));
}
_result.succeed(Texture.fromBitmapData(bitmapData, false, false));
} else {
log.warning("Bitmap loaded partially, retrying",
"name", _name,
"numTries", _numTries,
"percentLoaded", (bottomRow / _expectedBottomRow),
"expectedBottomRow", _expectedBottomRow,
"loadedBottomRow", bottomRow);
bitmapData.dispose();
var timer :Timer = new Timer(RETRY_DELAY * _numTries * 1000.0, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, function (e :TimerEvent) :void {
doNextLoad();
});
timer.start();
}
}
public static function getBottomPixelRow (bitmapData :BitmapData) :Number {
var bounds :Rectangle = bitmapData.transparent ?
bitmapData.getColorBoundsRect(0xFF000000, 0x0, false) :
bitmapData.getColorBoundsRect(0xFFFFFFFF, 0x0, false);
return bounds.bottom;
}
private static const MAX_TRIES :int = 5;
private static const RETRY_DELAY :Number = 0.1; (This validating bitmaploader has an Doing an immediate reload of the offending bitmap often results in the error recurring, so I have a reload timeout that increases with each failure. I haven't yet seen a bitmap fail 5 times in a row, but of course it's possible. The error seems to occur more frequently when there are multiple in-progress bitmap loads -- though this may just mean that the error is more likely when there's more memory being allocated, as you note above. This code logs a warning when it detects an issue, and anecdotally, the "percentComplete" of failed bitmaps (as measured by the loaded bitmap's bottom-most non-transparent row, divided by its expected bottom-most non-transparent row), has always been 25%, 50%, or 75%, which I didn't expect. My test textures are all 2048x2048. This makes me think that bitmap loading happens in discrete chunks, and there's some early exit that sometimes occurs before all chunks have been loaded. |
I haven't seen this problem reported since AIR 29, so I'm supposing this is fixed! I'll close the issue now, but if anyone reports differently, we can open it up again anytime. |
Adobe tracker link:
https://tracker.adobe.com/#/view/AIR-4198475
Forum link:
https://forum.starling-framework.org/topic/textures-partially-uploaded-to-gpu-original-bitmapdata-is-perfect/page/2
Problem Description:
On certain android devices (SM-T530 running android 5.0.2), textures created only partially load up, a full horizontal slice from the top of the texture, down to a seemingly arbitrary height, is created, and the bottom is not created (or perhaps uploaded to the gpu). This results in incomplete rendering. This bug did not occur on some other android devices, including the (SM-G935F running android 7.0)
Steps to Reproduce:
Load up a big texture (4096,4096) and attempt to render it on (SM-T530 running android 5.0.2) using air sdk27, it wont render fully, switch to air sdk19 it works, switch back to air sdk27, it doesn't work. Please not that this does not fail on all devices.
Actual Result:
incomplete texture
Expected Result:
corrrect rendering
Any Workarounds:
The bug was allieviated by switching to air sdk 19, however, this is not an option as having previously published with version 27, we are now stuck targetting android:targetSdkVersion="24", which requires persmissions which can only be accessed with air sdk 24.
The text was updated successfully, but these errors were encountered: