-
Notifications
You must be signed in to change notification settings - Fork 24
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
Musings and ideas for a potential v2 API #43
Comments
Just a quick braindump, too, some of which was detailed a tiny bit in the linked PR ;).
That said, a truly modular library model is definitely not a bad idea, and certainly a fairly minor (famous last words ;p) hurdle once the API is taken care of ;).
|
If you need to keep the fbfd AUTO behaviour, I suppose you could pass that as a parameter to the context 'constructor', and use the same logic as you already are to test it. |
I think I've mentioned this before, but I'm not really a CS person, and I've never managed to get into OOP, so designing a cool API is really not my forte ^^. So, yeah, please feel free to throw stuff at the wall, and we'll see what sticks ^^. |
I'm not an OOP person myself, although I did take a class on it. I tend to take some of the bits I find useful, but I'm hardly one to preach the OOP gospel! From a bindings perspective, not having to deal with lots of structs (externally) is kind of a nice thought, which is why I'm a little partial to the getter/setter idea here. |
Changing tack slightly, from an internal FBInk standpoint, would it be worth investigating using put_pixels variants? I was just looking at the if-ladder in As well as simplifying the if-else ladder(s), I'm wondering if the individual calls to Thoughts? |
Variants in which way, exactly? (There's already one variant per bitdepth, which the insane ladder in draw_image takes advantage of. Speaking of that ladder, most/all of it gets hoisted properly, so it's fugly as hell, but it doesn't perform too badly, as far as branching is concerned at least). But, yeah, none of that gets vectorized, mostly because the loops are too complex, and/or the bounds are unclear/dynamic IIRC. (Which is why anything than can go through a memcpy or fill_rect instead of put_pixel* is a happy camper ^^). (The vectorization diagnostics are much more readable since GCC 9). |
put_pixels with an s. a function for each bit depth that takes an input buffer, coordinates, dimensions, stride etc, and plots pixels with inversions/alpha as necessary, without needing to use individual function calls to put/get pixels. I'm also a bit surprised you haven't made put/get_pixel macros or inline functions to be honest. Whether that would make a measurable improvment or not I don't know... |
IIRC, every (The |
Huh. Ok. Fair enough. |
KOReader's C blitter does use a few macros, but I found it a bit of a PITA to work with in practice ;p. Granted, it has to bend its back to follow the legacy Lua API of the Lua blitter, which doesn't help ^^. |
I don't blame you on the macro's, I avoid 'em like the plague myself generally. |
Okay, apparently they're not inlined everywhere (at a glance, specifically in |
Oh, or when I last checked, having them inlined where the compiler wasn't already doing so was a loss. Can't recall -_-". Will test again ^^. |
For ref. diff --git a/fbink_internal.h b/fbink_internal.h
index 87a9f69..d167b56 100644
--- a/fbink_internal.h
+++ b/fbink_internal.h
@@ -450,24 +450,24 @@ static void rotate_coordinates_nop(FBInkCoordinates* restrict __attribute__((unu
static inline uint16_t pack_rgb565(uint8_t, uint8_t, uint8_t);
-static void put_pixel_Gray4(const FBInkCoordinates* restrict, const FBInkPixel* restrict);
-static void put_pixel_Gray8(const FBInkCoordinates* restrict, const FBInkPixel* restrict);
-static void put_pixel_RGB24(const FBInkCoordinates* restrict, const FBInkPixel* restrict);
-static void put_pixel_RGB32(const FBInkCoordinates* restrict, const FBInkPixel* restrict);
-static void put_pixel_RGB565(const FBInkCoordinates* restrict, const FBInkPixel* restrict);
+static inline void put_pixel_Gray4(const FBInkCoordinates* restrict, const FBInkPixel* restrict);
+static inline void put_pixel_Gray8(const FBInkCoordinates* restrict, const FBInkPixel* restrict);
+static inline void put_pixel_RGB24(const FBInkCoordinates* restrict, const FBInkPixel* restrict);
+static inline void put_pixel_RGB32(const FBInkCoordinates* restrict, const FBInkPixel* restrict);
+static inline void put_pixel_RGB565(const FBInkCoordinates* restrict, const FBInkPixel* restrict);
// NOTE: We pass coordinates by value here, because a rotation transformation *may* be applied to them,
// and that's a rotation that the caller will *never* care about.
-static void put_pixel(FBInkCoordinates, const FBInkPixel* restrict, bool);
+static inline void put_pixel(FBInkCoordinates, const FBInkPixel* restrict, bool);
// NOTE: On the other hand, if you happen to be calling function pointers directly,
// it's left to you to not do anything stupid ;)
-static void get_pixel_Gray4(const FBInkCoordinates* restrict, FBInkPixel* restrict);
-static void get_pixel_Gray8(const FBInkCoordinates* restrict, FBInkPixel* restrict);
-static void get_pixel_RGB24(const FBInkCoordinates* restrict, FBInkPixel* restrict);
-static void get_pixel_RGB32(const FBInkCoordinates* restrict, FBInkPixel* restrict);
-static void get_pixel_RGB565(const FBInkCoordinates* restrict, FBInkPixel* restrict);
+static inline void get_pixel_Gray4(const FBInkCoordinates* restrict, FBInkPixel* restrict);
+static inline void get_pixel_Gray8(const FBInkCoordinates* restrict, FBInkPixel* restrict);
+static inline void get_pixel_RGB24(const FBInkCoordinates* restrict, FBInkPixel* restrict);
+static inline void get_pixel_RGB32(const FBInkCoordinates* restrict, FBInkPixel* restrict);
+static inline void get_pixel_RGB565(const FBInkCoordinates* restrict, FBInkPixel* restrict);
// NOTE: Same as put_pixel ;)
-static void get_pixel(FBInkCoordinates, FBInkPixel* restrict);
+static inline void get_pixel(FBInkCoordinates, FBInkPixel* restrict);
#if defined(FBINK_WITH_IMAGE) || defined(FBINK_WITH_OPENTYPE)
// This is only needed for alpha blending in the image or OpenType codepath ;).
|
And at a very very quick glance, enforcing 'em nets a noticeable win. Now I have to rememebr when I last checked and why it wasn't so at the time... :D |
Chiefly affects |
Back to the hypothetical v2 API, just had a quick thought, maybe consider dumping the whole rows/columns thing? Seems a simple offset/dimensions system would cause a lot less implementation headache. |
But I luuuuurrve it ;p. (Also, it's inherited from eips, and I just find it practical for the fixed-cell rendering codepath. Practical to use, say, certainly not to make it work more or less properly inside FBInk :D). |
I guess from my perspective, most of the complexities appear to come from trying to mix the fixed cell layout with pixel based adjustments for centering, padding etc. Seems a bit counter-intuitive to me, but hey, I never used eips, so what do I know...? |
Yeah, I definitely get that. I say "it makes sense as a user", but then I also remember when I was wondering WTF were the lab126 guys on when I first played with it, soooooo :D. I do like it, once you wrap your head around it. I do agree that it only makes sense in the fixed-cell codepath, which means the whole thing clashes a bit once you start mixing the two together ;). |
IIRC, I wasn't mixing the two together (inside the fixed-cell codepath, I mean) at the start. Then the whole "let's handle the weird H2O viewport" thing happen, and here I was with a huge pixel shift grain of sand in my shiny row/column machinery ^^... And then image support happen, where you probably definitely expected pixels... Then I went, hey, might be fun to align images to text... And that's how you end up with a baby monster :D. |
Incidentally, once the two started getting mixed together, the fact that you could essentially ignore one whole side of it altogether was kinda neat (i.e., you can use the fixed-cell codepath entirely with pixel values, or entirely w/ row/col). That doesn't help the code, but at least that insanity doesn't bleed though too much to the user (except in the "there's seventy billion different settings" kind of way ^^). |
Whee, found the traces of my previous inline tests:
The first once I can understand, results were poor because stuff was still going through function pointers; but the second one is interesting: that's what made me switch away from function pointers in That was in the middle of the |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Just for the record, I was asleep during this current bout of nonsense. |
Hey, there's now a fancy new? Report/Block button, kudos GitHub! :). (If it isn't new, I failed to notice it during the last round of trolling last year or so). |
Yes, that's new (it was added around halfway through last year). Unfortunately, it still says this issue was "Fixed by hdhbdh/Kobo-Reader#1", though. |
Huh. The fact that this is picked up in the title comments (or whatever that area is called) across unconnected repos in the first place is... weird? (I mean, it's great when it works for actually connected repos, which comes in handy with the various KOReader submodules for cross-references, for instance), but across unconnected (not the same owner/organization/commit rights) feels like an oversight? One that's ripe for the taking for trolling opportunities... |
other pointers). Tweak the new signatures to keep honoring that. It doesn't necessarily make much sense (hi #43!), but, eh.
Note to self before I entirely forget about it: On the subject of setters/getters. Having recently played with ZSTD, I kinda like the approach of a single setter/getter function, which takes a pointer to an opaque struct (e.g., it's just an empty forward declaration in the public header), and you choose what to get/set via a list of constants from an enum as the actual argument. That is all ;p. |
Note to self, again:
|
Carrying on from our discussions in shermp/go-fbink-v2/pull/9, I just wanted to jot down a few ideas rolling around in my skull while they are fresh.
Feel free to ignore, or wait on this.
That's one initial thought from me. I'm generally not a fan of getter/setters, coming from a Python/C background, but in this case it might help prevent API breakage by hiding internal structs etc.
The text was updated successfully, but these errors were encountered: