sketchpunk / opencomicreader

Comic/Manga viewer for Android devices.
96 stars 37 forks source link

New page loading mode not working on Onyx Lynx T68 #47

Open rlach opened 10 years ago

rlach commented 10 years ago

Commit 0fd6e136c2d5c6c0b0f0b3e5be65e1b16da9ad0b

Description: On line 86 of ComicLoader.java max texture size is determined as 0. Then in PageLoader.java newWidth and newHeight get set to 0, which throws and Exception on line 179. It's: java.lang.IllegalArgumentException: width and height must be > 0

Also it later crashes the app with NullPointerException when exception handler calls bmp.recycle(), as it's null at this point.

It works correctly on some devices(for example Prestigio PAP4500), but doesn't work on Onyx Lynx T68.

Device: Onyx Lynx T68

OpenGL information gathered by https://play.google.com/store/apps/details?id=nl.svdree.glesinfo: [EGL]

Vendor: Google Inc. Version: 1.2 Android Driver 1.2.0 Extensions: EGL_ANDROID_swap_rectangle EGL_ANDROID_image_native_buffer EGL_KHR_image_base EGL_ANDROID_get_render_buffer

[OpenGL-ES 1.x]

Vendor: Android Version: OpenGL ES-CM 1.0 Renderer: Android PixelFlinger 1.4 Max. lights: 8 Max. texture size: 4096 Max. texture units: 2 Subpixel bits: 4 Extensions: GL_OES_byte_coordinates GL_OES_fixed_point GL_OES_single_precision GL_OES_read_format GL_OES_compressed_paletted_texture GL_OES_draw_texture GL_OES_matrix_get GL_OES_query_matrix GL_OES_EGL_image GL_OES_compressed_ETC1_RGB8_texture GL_ARB_texture_compression GL_ARB_texture_non_power_of_two GL_ANDROID_user_clip_plane GL_ANDROID_vertex_buffer_object GL_ANDROID_generate_mipmap

[OpenGL-ES 2.x]

Not supported

rlach commented 10 years ago

For now I added: if(maxTextureSize == 0) { maxTextureSize = 4096; } after line 81 in PageLoader and the pages load for me, so this is just an issue with detecting maxTextureSize correctly. I couldn't find better way for detecting it than you are using in ComicLoader.java, line 86. If you have some ideas I can try them out on my device and tell you what works.

sketchpunk commented 10 years ago

Thats weird that you're device doesn't return a texture size from openGL. 4096 is too large, for my kindle fire the max texture size is around 2000, anything more will crash the app. I think I might add a setting that allows you to set a default texture size that will be used if openGL reports back a zero. This way for devices with a lower limit can set it manually what works best for them, then your device with an upper limit can set that. This way you get the best quality possible for each device. Sucks to have to do this, OpenGL should report back the correct texture size. There is no other way to know what you're limit is without loading up a massive size image and getting back an error in adb telling you what it's limit is. Are you using a custom rom btw?

sketchpunk commented 10 years ago

so that app is able to tell you the correct texture size? I wonder how that app does it. I'm not an openGL person so I don't know it really. Took me awhile to find that bit of source to give me the texture size. If there is a better way of doing it thats more reliable, then I'll def use it.

That app doesn't seem to be open sourced, so no way to take a quick peak on how it gather's all that info.

rlach commented 10 years ago

I'm using default, non-rooted rom. I could ask Onyx support what the deal is. I was looking for open source openGL reporting app, but couldn't find one(plus not every one of them supports that device). I've set texture size to 4096 though and it doesn't crash the app for me. Actually I've read hundred of pages since that time, including very big ones, and had no crashes.

Since I'm also not an openGL guy I can't figure out what is going on. If I won't find the answer myself I think I'll ask on stack.

sketchpunk commented 10 years ago

4096 is fine because that's what your device can handle. but Amazon Fire can only handle half. So I can't hardcode that value so not to screw someone else up. But if that app can detect the right size, then there might be a different way to pull that info or I might be pulling it out to soon. If you want to try, take that bit of code and put it in a button event. Click a button and toast the value. If its still zero, then it def doesn't work. If you get the right value, then I need to get that value at a different point in the activity life cycle.

rlach commented 10 years ago

Obviously I'm not asking you to hardcode anything in code. I think it might be just that the context is still not initialized. Actually I can see in logcat logs warning that I get calls to gl which is not initialized. But what is strange that it returns correct values on other devices, including my mobile phone.

rlach commented 10 years ago

I figured out the problem, or at least I think it did.

When you were loading it, after all, the openGL ES context wasn't available yet. Why did it work on some devices? Apparently, at least according to google search results, some devices do some pre-preemptive HW checks when you open an APP. Thus it worked over there, as the values were already known despite lack of running openGL context.

My fix: In ComicLoader I check if maxSize is in prefs. If it is not then I launch OpenGLESTestingActivity(silly name, I know). It is pretty much activity created with this tutorial: http://developer.android.com/training/graphics/opengl/environment.html I pass context all the way to Renderer, where I do the following in OnSurfaceCreated:

int[] maxTextureSize = new int[1];
int maxSize = 0;

GLES10.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);
maxSize = maxTextureSize[0]; // MaxTextureSize
prefs.edit().putInt("maxTextureSize", maxSize).commit();

finish(); 

At that point every device I tried it on already has context, so the max texture size is detected correctly. Since the size is saved to prefs it has to do the check only once, and I don't think there are android phones on the market where GPU could be changed.

Also, when I take the texture size out in loader, after test has completed I use this:

mMaxSize = prefs.getInt("maxTextureSize", 2048);

That way even if the test would somehow fail it will still fallback to 2048 size. According to google search, all android devices with android 2.0+ were required to support 2048. Assuming I can trust what random people wrote on the internet this should be safe. Hopefully this value won't ever be used, as the testing activity should work on every device anyway.