| <<<Back 1 day (to 2015/12/29) | 20151230 |
rayjj | I guess I missed mvrhel | 00:22.25 |
| Robin_Watts: it's OK to call clist_close_writer_and_init_reader from list_print because the clist is already a blank page at that point. the gx_saved_pages_param_process is called from put_params, and that always erases the page, so any unprinted data in the clist files will be discarded anyway | 00:26.46 |
Robin_Watts | Are you saying that the call to add an end_page to the clist within clist_close_writer_and_init_reader will not write to the current clist? | 00:28.28 |
| No, I think you're saying that it'll add an end_page, but that won't matter. | 00:29.11 |
rayjj | Robin_Watts: the page(s) to be printed will all have been "saved" via gx_saved_pages_list_add called from gdev_prn_output_page_aux | 00:29.26 |
Robin_Watts | Yes, I understand that. | 00:29.43 |
| But clist_close_writer_and_init_reader does an end_page, then inits rendering, and reads the color usage. | 00:30.35 |
rayjj | Robin_Watts: that clist doesn't matter -- it is a dummy, and after printing, clist_finish_page (or some variant) will reset the clist to writing mode with an empty page | 00:30.36 |
Robin_Watts | OK, so close_and_... will be called on the clist that's about to die, so the writing doesn't matter. | 00:31.06 |
| but the reading of the color usage has got to be wrong. | 00:31.17 |
rayjj | Robin_Watts: and reading the color_usage is OK, because it'll be read again after we load the page we actually want to print | 00:31.38 |
| every rendering starts by reading the color_usage | 00:32.08 |
| Robin_Watts: see gx_output_saved_page | 00:32.38 |
| Robin_Watts: it also reads the icctable there | 00:33.14 |
Robin_Watts | ok, I'll look again tomorrow. Thanks. | 00:33.27 |
rayjj | Robin_Watts: the main reason that save_page and load_page were used around printing the saved pages was to make sure that subsequent actions (parsing more stuff) gets the right device param settings (which can vary per page) and doesn't create new clist files | 00:35.12 |
| but if you refactor the code to save the clist fnames and/or {c,b}file info and the device params and restore them before the call to clist_finish_page in the list_print "out:" block, it should be OK | 00:37.33 |
| Robin_Watts: and at the time, the files weren't "cloned" so the confusion with file position wasn't there | 00:40.17 |
tor8 | Robin_Watts: have you had time to look at tor/jni yet? | 14:48.56 |
Robin_Watts | tor8: Nope. I'm in clist hell. | 14:49.07 |
tor8 | I'm starting to convince myself that this way is going to be easier in the long run. it's a raw mapping of c functions, with thin shim java classes on top to reproduce basically the same interface as your implementation | 14:50.02 |
| the difference as I see it is that the C layer is dumb as bricks | 14:50.15 |
Robin_Watts | WTF is ffi ? | 14:52.15 |
malc_ | foreign function interface | 14:52.32 |
| i guess | 14:52.35 |
tor8 | what malc_ said | 14:52.45 |
Robin_Watts | oh, I see it. | 14:52.47 |
tor8 | Robin_Watts: so there's a big fat 'ffi' class with static functions that are all the fz_foo_bar native bindings | 14:53.18 |
Robin_Watts | Right. | 14:54.45 |
malc_ | http://www.bash.org/?6460 | 14:56.48 |
Robin_Watts | tor8: So it looks OK as far as it goes, but you've dodged the multi-threading stuff. | 15:19.45 |
| And you absolutely can't dodge that. | 15:19.54 |
| Android app programming etc is all about running stuff on handlers and on the UI thread etc. | 15:20.20 |
| so the challenge is in finding the best way to do that. | 15:20.33 |
tor8 | Robin_Watts: I was thinking the getctx() function (added in a separate commit) would tackle that | 15:21.38 |
| it would call something to get a thread local fz_context | 15:21.56 |
Robin_Watts | tor8: At the moment that just returns a single global context. | 15:22.17 |
| (unless I'm misunderstanding) | 15:22.26 |
tor8 | it does, I've just stubbed it for now | 15:22.36 |
| to test some basic stuff using desktop java | 15:22.43 |
| my other thought was to pass the ctx to the fz_ functions | 15:23.02 |
| but it's easier to do macro stuff in C if that's what's required | 15:23.18 |
Robin_Watts | So the big differences I can see between this and my code are: | 15:23.52 |
tor8 | so it would look like ffi.fz_load_page(ffi.ctx(), doc.ptr, number) | 15:23.54 |
Robin_Watts | 1) The context handling. | 15:24.03 |
| 2) having all the native stuff in ffi rather than in the individual java classes. | 15:24.29 |
| 3) The 'simplicity' of the DrawDevice stuff. | 15:24.44 |
tor8 | your '2' is what I wanted to try out | 15:25.03 |
Robin_Watts | 1 is incomplete, so I can't really see whether it's a benefit or not - I suspect we're going to end up with exactly the same stuff. | 15:25.23 |
tor8 | I expect 1 will look extremely similar to what you did, yes | 15:25.38 |
Robin_Watts | 2 is essentially a question of packaging. I think the actual implementations are going to look almost identical, just with different prefixes to the names. | 15:26.06 |
| Oh, and the 'this' pointer in the native functions becomes useless in yours... | 15:26.23 |
tor8 | the 'this' pointer is the class object for the 'ffi' class | 15:26.40 |
| which would be used in the getctx() function | 15:26.53 |
| the idea was that the ffi bindings can be coded by a monkey, or auto-generated | 15:27.30 |
| seeing as they should map 1-on-1 with the matching C functinos | 15:27.47 |
| just a bit of marshaling for rects and matrixes | 15:27.57 |
| and strings | 15:28.12 |
Robin_Watts | It's the marshalling that's the the interesting bit. | 15:28.19 |
| And for such marshalling having "this" point to the class in question rather than to ffi seems like it will be more useful to me. (But I could be wrong) | 15:29.00 |
| The JNI functions for my stuff are all pretty simple, I reckon, with the exception of the Device interface. | 15:29.38 |
tor8 | we pass the native pointers in the function arguments; the 'this' marshaling happens on the java side | 15:29.46 |
| each object oriented function will wrap a ffi.fz_foo_bar call | 15:29.59 |
Robin_Watts | and the complexity there is justified. | 15:30.19 |
tor8 | and more fancy marshaling and polymorphism can happen on the java side, where it's easier to deal with | 15:30.30 |
Robin_Watts | tor8: yeah, you may be right. That's pretty much what I do too. | 15:30.42 |
tor8 | and I think it could be of possible usefulness to see the mirrored function when debugging the java code down the line | 15:31.11 |
Robin_Watts | In order to be properly useful, we want to be able to write Devices in java, and to be able to call devices from Java. | 15:31.33 |
| That duality is where the complexity comes from. | 15:31.44 |
tor8 | yeah, I'm going to tackle calling a device implemented in java next to see if I can get that to work here | 15:32.04 |
Robin_Watts | This seems like duplication of work to me, but if you want... | 15:32.32 |
tor8 | for a subset of the device calls, obviously. just to see whether it's worth progressing. I also need to learn more details about JNI and this is the best way for me to do it. | 15:32.39 |
Robin_Watts | sure. | 15:32.45 |
tor8 | your JNI marshaling in the C functions does a lot of ColorSpace_from_fz_colorspace etc | 15:33.21 |
| that would be eliminated by just passing longs across the language boundary | 15:33.33 |
Robin_Watts | tor8: Yes, it would. | 15:33.40 |
tor8 | that's what I see as the major difference | 15:33.53 |
Robin_Watts | right. | 15:34.16 |
tor8 | doing that with the JavaDevice will need some thinking | 15:34.18 |
| fz_java_device (wrapped by a NativeDevice object) that does the unmarshaling fromlongs and calls a separate JavaDevice interface | 15:35.28 |
| and have the native devices implement the same interface to do the marshaling the other way | 15:35.42 |
Robin_Watts | I guess I'd be interested to know what is faster. "blah.internal" in java, or calling the C with blah, and doing the blah.internal lookup in the C. | 15:39.29 |
| If the former is faster (or no worse at least), then it probably produces smaller code (both source and binaries). | 15:40.17 |
tor8 | I would expect 'blah.internal' in java | 15:40.21 |
| the JNI interface is known to be slow | 15:40.37 |
Robin_Watts | which would lean towards your way of working. | 15:40.39 |
tor8 | but you might get reasonable performance by caching all the string lookups (the methodIDs etc) | 15:40.52 |
Robin_Watts | tor8: They are cached in my version. | 15:41.06 |
| I think I'd still prefer not to have ffi. | 15:41.37 |
tor8 | it would not surprise me if the JNI stuff is based on the reflection api | 15:41.43 |
Robin_Watts | but rather to have the native stuff in the native functions. | 15:41.50 |
| s/native functions/individual java classes/ | 15:43.08 |
| the java device interface needs to be thought through. Can't visualise the implications for that at the moment. Too fried by the clist. | 15:44.40 |
| The lack of const in java makes it tricky. | 15:44.56 |
tor8 | it is going to be weird | 15:45.29 |
| you don't want a feedback loop | 15:45.35 |
| calling dev.fillText() should call ffi.fz_device_fill_text() on a native device. on a device implemened in java, you don't want the page.run(dev) to call fz_device_fill_text() to call dev.fillText() in a feedback loop | 15:47.45 |
| in case the implementations are inherited | 15:48.00 |
Robin_Watts | tor8: yeah, that's accounted for in my version. | 15:50.44 |
| because JavaDevice overrides the Device methods (or something like that) | 15:51.23 |
| I guess one way to proceed would be to just modify my stuff to pass longs instead of java objects. | 15:52.08 |
tor8 | I'm thinking an abstract top class Device { long ptr; } with subclasses NativeDevice that map fillText to ffi.fz_fill_text and another subclass JavaDevice which wraps a fz_java_device and fillText is a no-op to be implemented by subclassers | 16:02.15 |
| is that similar to what you did? | 16:02.19 |
| and the JavaDevice would have a bunch of secret methods that are called from C and do the marshaling to java fillText calls | 16:03.05 |
Robin_Watts | tor8: Yes. Though I've just noticed the history on jni2 is borked. | 16:06.09 |
| Some stuff is in the "Add jni project" commit that should be rolled into the previous one. | 16:06.40 |
| essentially I have a top level 'Device' class than java peeps can override and extend. | 16:06.58 |
| and a CDevice class that all the C devices are based on. | 16:07.15 |
| The CDevice class inherits from Device, but overrides all the methods, pretty much. | 16:07.34 |
| OK, jni2 fixed. | 16:10.54 |
tor8 | Robin_Watts: thanks, easier to brows in gitk when squashed | 16:11.56 |
Robin_Watts | oh, yes, and for the devices there are additional issues to do with 'locking'. | 16:12.46 |
| When we are drawing to an android bitmap (or an array of ints for Awt), we need to 'lock' those objects in memory around the render call. | 16:13.16 |
| and unlock when we're done. | 16:13.27 |
| We don't want to unlock too often though (as I suspect android flushes the bitmap back to texture memory on an unlock). | 16:14.12 |
| so we can't lock/unlock on every device call (unless it's from java, when we need to) | 16:15.33 |
tor8 | would it make sense to render to a fitz-owned byte array and then copy into the Android bitmap once done? | 16:16.17 |
Robin_Watts | tor8: a) That'd be bad, cos bitmaps are HUGE. | 16:16.54 |
| b) we don't need to. My code shows that it can be done efficiently. | 16:17.06 |
| It's just something that needs to be considered. | 16:17.19 |
| Ah! | 16:19.25 |
| I remember why I opted to pass java objects to the C rather than longs now. | 16:19.42 |
| We can pass either longs or objects to the C. | 16:20.21 |
| but the C can only ever pass 1 thing back. | 16:20.29 |
| so in cases where we want to return a rectangle, we've GOT to pass a jobject back, which means creating that jobject in the C. | 16:21.06 |
| (well, we could hack around it, and do multiple calls etc, but that's horrid). | 16:21.24 |
| hence given that I was going to be passing jobjects over the interface in that case, I thought it was better to be consistent and to pass jobjects both ways. | 16:22.10 |
tor8 | I can only see it mattering if we care about pointer equivalence in java of the same underlying struct | 16:22.15 |
| ah, but I special case rects and matrixes in the marshaling (like strings need to be as well) | 16:22.44 |
| we pass and return rects and matrixes to 99% of functions by value | 16:23.18 |
| you changed them to be const in pointers and out pointers at one point, where before they were actually passed by value | 16:23.59 |
Robin_Watts | tor8: When the java makes a call to say "get me the bbox for this search result", how will you handle that ? | 16:24.20 |
tor8 | I create a new Rect from C (the to_Rect function in ffi.c) | 16:24.40 |
| likewise I have from_Matrix to convert the Matrix into a fz_matrix | 16:24.59 |
Robin_Watts | So you create a jobject in the C and return that. | 16:25.00 |
tor8 | yeah. | 16:25.04 |
Robin_Watts | right. I see that as a different style to the passing of longs. | 16:25.31 |
tor8 | our rects and matrixes don't live on the heap, so don't match well with the java way of doing objects | 16:25.37 |
Robin_Watts | and I opted for consistency. | 16:25.39 |
tor8 | all our structs that live on the heap go into longs | 16:25.59 |
Robin_Watts | surely the reverse of that? | 16:26.05 |
tor8 | the stuff on the stack will need to be copied | 16:26.05 |
| into jobjects | 16:26.16 |
Robin_Watts | yeah. | 16:26.28 |
tor8 | false consistency, given the heap/stack distinction (IM very arrogant O) | 16:26.41 |
Robin_Watts | whatever happens we need to create java objects and copy stuff into them. | 16:27.31 |
tor8 | yeah, there's no other way around rects and matrices | 16:27.47 |
Robin_Watts | The question of consistency is just in what we pass. | 16:27.48 |
| And if we're prepared to accept that we pass one thing one way, and another thing the other, then so be it. | 16:28.09 |
tor8 | the only diff is that you do the 'this.ptr' dereference in C where I do it in Java | 16:28.25 |
Robin_Watts | yes. | 16:28.33 |
| and I am coming around to the idea of doing it Java. | 16:28.43 |
| rayjj: awake? | 17:30.00 |
ray_phone | I'm away some of today. if you ask something I'll check the logs when I get back. | 18:42.07 |
| Forward 1 day (to 2015/12/31)>>> | |