summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-04-28 08:51:20 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-05-28 13:26:19 -0400
commit737b4564356196f2c922b197cad7d334633c34b9 (patch)
tree259a9e75e3a311b387ec11dfad55c50566aa777e
parent13ad1c51e49674b59ec7defa9975cf9b4c1f6743 (diff)
Add glyphs.txt
glyphs.txt
-rw-r--r--glyphs.txt338
1 files changed, 338 insertions, 0 deletions
diff --git a/glyphs.txt b/glyphs.txt
new file mode 100644
index 00000000..ec7c531f
--- /dev/null
+++ b/glyphs.txt
@@ -0,0 +1,338 @@
+TODO:
+ - uploading glyphs should be done through pixman images
+ - this is convenient for both cairo and X. And in fact
+ easier within pixman as well.
+
+ - bearing/advance probably needs to be computed outside of
+ pixman. Alternatively, there should be the possibility of
+ including offsets within the list of glyphs.
+
+
+New approach:
+
+Pixman has the concept of a glyph cache, and not the concept of a
+glyph set.
+
+API:
+
+pixman_glyph_cache_freeze();
+pixman_glyph_cache_thaw();
+bool pixman_glyph_cache_contains(cache, void *font, uint32_t index);
+void pixman_glyph_cache_insert(cache, void *font, uint32_t index,
+ format, x, y, data, ...);
+struct command
+{
+ union
+ {
+ struct
+ {
+ void *font;
+ } switch;
+
+ struct
+ {
+ int x, y;
+ } displace;
+
+ struct
+ {
+ uint32_t n_glyphs;
+ } glyphs;
+ } u;
+};
+
+pixman_glyph_commands_t *pixman_glyph_commands_begin (void *data, int n_bytes);
+
+pixman_glyph_commands_t *pixman_glyph_commands_switch (void *data, void *font);
+... *pixman_glyph_commands_displace (void *data, int x, int y);
+... *pixman_glyph_commands_glyphs (void *data, uint32_t n_glyphs,
+ uint32_t *indices);
+
+void *pixman_glyph_commands_end (void *data);
+void pixman_glyph_commands_free (void *data);
+
+
+void pixman_composite_glyphs(..., src, cache, commands, dst);
+
+To use it, you would do:
+
+ uint8_t data[1024];
+ uint32_t glyphs[N_STACK_GLYPHS];
+ uint32_t *g = glyphs;
+
+ pixman_glyph_commands_t *commands;
+
+ pixman_glyph_cache_freeze();
+
+ commands = pixman_glyph_commands_begin (data, sizeof (data));
+
+ for (i = 0; i < blah; ++i)
+ {
+ if (glyph)
+ {
+ if (g - glyphs == N_STACK_GLYPHS)
+ {
+ command = add_glyphs (command, font, glyphs, N_STACK_GLYPHS);
+ g = glyphs;
+ }
+ *g++ = index;
+ }
+ else
+ {
+ command = add_glyphs (command, font, glyphs, g - glyphs);
+ g = glyphs;
+
+ if (displace)
+ ...;
+ else if (font)
+ ...;
+ }
+ }
+
+ command = add_glyphs (command, font, glyphs, g - glyphs);
+ commands = pixman_glyph_commands_end (commands);
+
+ pixman_composite_glyphs (src, cache, commands, dst, ...);
+
+ pixman_glyph_commands_free (commands);
+
+
+In the X server, do we get any notification when a glyph disappears?
+Yes, we do in UnrealizeGlyph().
+
+We can be even simpler than this:
+
+pixman_glyph_cache_freeze();
+pixman_glyph_cache_thaw();
+bool pixman_glyph_cache_contains(cache, void *font, void *index);
+void pixman_glyph_cache_insert(cache, void *font, void *index,
+ format, x, y, data, ...);
+pixman_composite_glyphs (src,
+ void *font, void **indices, int n_indices,
+ pixman_format_t mask_format,
+ dst,
+ ...);
+
+where the X server void use NULL for font, and the glyph pointer for
+indices, and cairo would use scaled_font for font and the
+glyph_indices for the indices.
+
+mask_format would determine the format used for the mask, although
+another possibility would be to say that a8 glyphs are expanded to
+shades of white. Or saying that glyphs get added with a white source.
+
+How do we deal with font matrices in cairo? Presumably the same way
+they are dealt with in the xlib surface.
+
+
+Glyphs in the X server
+
+- Glyphsets are current global and not attached to a screen and
+ therefore not something the driver can influence
+
+- In EXA, glyphs work like this:
+
+ - There are cache pixmaps in device memory that contain
+ recently rendered glyphs.
+
+ - when a set of glyph arrives to be rendered, they are looked up in
+ the pixmap caches; if they are not there, they are uploaded, and a
+ random glyph is evicted.
+
+Ideally, I think all glyphs would be stored contiguously in device
+memory, and a primitive would be emitted per glyph with sufficient
+information that each glyph could be composited.
+
+For software, we definitely want to store all the glyphs in one "tall"
+image, possibly sorted by frequency. Or even contiguously in a big
+array with varying strides.
+
+In either case, the driver/DDX needs to be involved in the X server.
+
+There is already a per-screen copy of each glyph, so it's not a
+problem to make a per-screen copy of each glyph set. Besides, in a
+randr world, people generally only have one screen even if they have
+multiple monitors.
+
+Per-screen glyph sets
+
+- Useful for DMX as well - since there is no real reason to store the
+ glyphs on the dmx server.
+
+- Actually, the glyph handling in DMX is broken - it is sending
+ pointers across, not the actual bits.
+
+GlyphSet
+{
+ XID id;
+ RealGlyphSet real_sets[num_screens];
+};
+
+CreateGlyphSet ->
+ GlyphSet set = malloc();
+ set->id = id;
+
+ for each screen s
+ glyphset[s] = screen->CreateGlyphSet();
+
+ FreeGlyphSet would of course call into each screen to free
+ the real sets.
+
+ Maybe a "RealGlyphSet" should actually be called GlyphSet,
+ and the global structure should be called something else.
+
+AddGlyphs (set, glyphs) ->
+ for each screen s
+ s->AddGlyphs (set->real_sets[s], glyphs);
+
+CompositeGlyphs () ->
+ s = screen
+ walk glyph list and replace glyphset with real sets depending
+ on screen .
+ screen->CompositeGlyphs (s, glyphs);
+
+ Or just use the existing GlyphList infrastructure
+
+There would mi versions of these calls of course.
+
+And there should perhaps be some compatibility wrapper macros type
+things in place, though it probably can't be completely source
+compatible.
+
+
+(a) Change the GlyphSet structure, make it compile.
+
+(b) mi would have to store some private information related to the
+ glyph sets.
+
+(c) It may make sense to move most of the existing mi code into exa,
+ and then do something entirely different for fb.
+
+ This does mean the uxas will have to be updated.
+
+
+
+Assumptions:
+
+- if you are going to composite the glyphs in software, then you will
+ eventually use pixman, which means it is fundamentally not
+ unreasonable to have the glyphs stored in a pixman data structure.
+
+- if you are going to composite the glyphs in hardware, then the
+ glyphs should still be stored somewhere in host memory because they
+ will be needed there anyway from time to time and migrating them out
+ is expensive. Currently, the glyphs in pixmaps, which may or may not
+ be in video memory.
+
+The consequence is that if we add an fbGlyphs that doesn't require
+individual pictures, then it is not entirely unreasonable to construct
+the glyph pictures on the fly. The open source drivers should be fine
+with this - the nvidia binary driver probably not, given that Aaron
+added the USAGE_GLYPH hint to CreatePixmap.
+
+Another possibility would be to still create the glyph pixmaps like we
+do now, but have them point to the pixman data.
+
+A third possibility is to simply have fb create a pixman_glyph_set_t
+and cache it in private data.
+
+Fundamentally, X should not make the assumption that the driver wants
+to store the glyph in a pixmap. That is a decision that the driver
+should make.
+
+
+- Glyphs in Render have strides that are padded to 32 bits. The spec
+ is unclear (the *Render* spec is unclear? No way) about this, but
+ the code pads the stride to 32 bits.
+
+ Well, it uses PixmapBytePad(), which is padding to 32 bits.
+
+- The server has a pixman_glyph_context_t. This context is global and
+ holds all the cached glyphs.
+
+ Such a context can
+
+ - be created
+ - be destroyd
+
+ - privately,
+ - add a glyph
+ - remove a glyph
+ - has static glyph pointers that remain valid until the glyph
+ is removed
+
+ - when the context is deleted, all associated glyphs are
+ deleted with it.
+
+ The only public API for it is "create()" and "destroy()". It is also
+ passed to pixman_glyph_set_create().
+
+- A pixman_glyph_set can
+ - be created with a reference to a context
+ - hold a reference to a context
+ - map ids to bits
+ - add/remove glyphs (both id based)
+ - map ids to bits
+
+Server side:
+
+At the moment, the glyphs are stored in Pictures, one picture (and
+pixmap) per glyph. The drivers usually copy some of the glyphs into
+textures and use those for hardware acceleration.
+
+
+- There is one global glyph context
+
+- GlyphSet becomes something that just holds a reference a pixman
+ glyph set.
+
+- Glyph still exists pretty much as it is now.
+
+- GlyphUninit deletes the global context.
+
+
+
+
+fb gains fbGlyphs which will issue pixman_composite_glyphs() with a
+list of glyph commands.
+
+
+Later
+
+Ways to get at the whole image
+
+
+In server, GlyphSet goes away, replaced with pixman_glyph_set_t.
+
+Glyph still exists, it is the private pointer in the glyph set.
+
+- fb caches pixman images
+
+- fb also gains an fbGlyphs which will replace miGlyphs and
+
+
+
+GlyphSet
+Add glyphs
+
+
+
+
+glyph set:
+- add_glyphs_unique() /* hashes */
+- add_glyphs /* doesn't hash glyph data */
+- get pointer, format, width, height, stride of big image
+- get coordinates in big image for glyph
+- callback when big image becomes invalid
+
+ - instructions on the desired tiling type?
+
+- method to composite a bunch of glyphs
+
+ pixman_glyph_set_composite (op, source, glyphs, dest, sx, sy, dx, dy);
+
+
+ pixman_image_composite_glyphs (op, source, dest, sx, sy, dx, dy,
+
+
+