Commit b0d2e010 authored by Keith Packard's avatar Keith Packard

glamor: Replace CompositeGlyphs code [v2]

New composite glyphs code uses the updated glamor program
infrastructure to create efficient shaders for drawing render text.

Glyphs are cached in two atlases (one 8-bit, one 32-bit) in a simple
linear fashion. When the atlas fills, it is discarded and a new one
constructed.

v2: Eric Anholt changed the non-GLSL 130 path to use quads instead of
two triangles for a significant performance improvement on hardware
with quads. Someone can fix the GLES quads emulation if they want to
make it faster there.

v3: Eric found more dead code to delete
Signed-off-by: Keith Packard's avatarKeith Packard <keithp@keithp.com>
Reviewed-by: Eric Anholt's avatarEric Anholt <eric@anholt.net>
parent 1b745e0c
......@@ -14,7 +14,7 @@ libglamor_la_SOURCES = \
glamor_font.c \
glamor_font.h \
glamor_glx.c \
glamor_glyphs.c \
glamor_composite_glyphs.c \
glamor_image.c \
glamor_lines.c \
glamor_segs.c \
......
......@@ -288,16 +288,6 @@ glamor_create_screen_resources(ScreenPtr screen)
ret = screen->CreateScreenResources(screen);
screen->CreateScreenResources = glamor_create_screen_resources;
if (!glamor_glyphs_init(screen)) {
ErrorF("Failed to initialize glyphs\n");
ret = FALSE;
}
if (!glamor_realize_glyph_caches(screen)) {
ErrorF("Failed to initialize glyph cache\n");
ret = FALSE;
}
return ret;
}
......@@ -509,6 +499,11 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_priv->saved_procs.block_handler = screen->BlockHandler;
screen->BlockHandler = _glamor_block_handler;
if (!glamor_composite_glyphs_init(screen)) {
ErrorF("Failed to initialize composite masks\n");
goto fail;
}
glamor_priv->saved_procs.create_gc = screen->CreateGC;
screen->CreateGC = glamor_create_gc;
......@@ -550,10 +545,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
ps->CompositeRects = miCompositeRects;
glamor_priv->saved_procs.glyphs = ps->Glyphs;
ps->Glyphs = glamor_glyphs;
glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph;
ps->UnrealizeGlyph = glamor_glyph_unrealize;
ps->Glyphs = glamor_composite_glyphs;
glamor_priv->saved_procs.create_picture = ps->CreatePicture;
ps->CreatePicture = glamor_create_picture;
......@@ -634,7 +626,7 @@ glamor_close_screen(ScreenPtr screen)
glamor_priv = glamor_get_screen_private(screen);
glamor_sync_close(screen);
glamor_glyphs_fini(screen);
glamor_composite_glyphs_fini(screen);
screen->CloseScreen = glamor_priv->saved_procs.close_screen;
screen->CreateScreenResources =
glamor_priv->saved_procs.create_screen_resources;
......@@ -655,7 +647,6 @@ glamor_close_screen(ScreenPtr screen)
ps->CreatePicture = glamor_priv->saved_procs.create_picture;
ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
ps->Glyphs = glamor_priv->saved_procs.glyphs;
ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
screen_pixmap = screen->GetScreenPixmap(screen);
......
......@@ -105,8 +105,6 @@ extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap,
extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap);
extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap,
unsigned int tex);
......
This diff is collapsed.
This diff is collapsed.
......@@ -154,41 +154,8 @@ enum glamor_gl_flavor {
GLAMOR_GL_ES2 // OPENGL ES2.0 API
};
#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
#define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024)
typedef struct {
PicturePtr picture; /* Where the glyphs of the cache are stored */
GlyphPtr *glyphs;
uint16_t count;
uint16_t evict;
} glamor_glyph_cache_t;
#define CACHE_PICTURE_SIZE 1024
#define GLYPH_MIN_SIZE 8
#define GLYPH_MAX_SIZE 64
#define GLYPH_CACHE_SIZE ((CACHE_PICTURE_SIZE) * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE))
#define MASK_CACHE_MAX_SIZE 32
#define MASK_CACHE_WIDTH (CACHE_PICTURE_SIZE / MASK_CACHE_MAX_SIZE)
#define MASK_CACHE_MASK ((1LL << (MASK_CACHE_WIDTH)) - 1)
struct glamor_glyph_mask_cache_entry {
int idx;
int width;
int height;
int x;
int y;
};
typedef struct {
PixmapPtr pixmap;
struct glamor_glyph_mask_cache_entry mcache[MASK_CACHE_WIDTH];
unsigned int free_bitmap;
unsigned int cleared_bitmap;
} glamor_glyph_mask_cache_t;
struct glamor_saved_procs {
CloseScreenProcPtr close_screen;
CreateScreenResourcesProcPtr create_screen_resources;
......@@ -208,7 +175,6 @@ struct glamor_saved_procs {
AddTrapsProcPtr addtraps;
CreatePictureProcPtr create_picture;
DestroyPictureProcPtr destroy_picture;
UnrealizeGlyphProcPtr unrealize_glyph;
SetWindowPixmapProcPtr set_window_pixmap;
#if XSYNC
SyncScreenFuncsRec sync_screen_funcs;
......@@ -274,6 +240,14 @@ typedef struct glamor_screen_private {
glamor_program_fill on_off_dash_line_progs;
glamor_program double_dash_line_prog;
/* glamor composite_glyphs shaders */
glamor_program_render glyphs_program;
struct glamor_glyph_atlas *glyph_atlas_a;
struct glamor_glyph_atlas *glyph_atlas_argb;
int glyph_atlas_dim;
int glyph_max_dim;
char *glyph_defines;
/* vertext/elment_index buffer object for render */
GLuint vbo, ebo;
/** Next offset within the VBO that glamor_get_vbo_space() will use. */
......@@ -292,9 +266,6 @@ typedef struct glamor_screen_private {
glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
[SHADER_MASK_COUNT]
[SHADER_IN_COUNT];
glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
glamor_glyph_mask_cache_t *mask_cache[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
Bool glyph_caches_realized;
/* shaders to restore a texture to another texture. */
GLint finish_access_prog[2];
......@@ -707,17 +678,6 @@ RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
void
glamor_track_stipple(GCPtr gc);
/* glamor_glyphs.c */
Bool glamor_realize_glyph_caches(ScreenPtr screen);
void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
void glamor_glyphs_fini(ScreenPtr screen);
void glamor_glyphs(CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs);
/* glamor_render.c */
Bool glamor_composite_clipped_region(CARD8 op,
PicturePtr source,
......@@ -744,10 +704,6 @@ void glamor_composite(CARD8 op,
void glamor_init_composite_shaders(ScreenPtr screen);
void glamor_fini_composite_shaders(ScreenPtr screen);
void glamor_composite_glyph_rects(CARD8 op,
PicturePtr src, PicturePtr mask,
PicturePtr dst, int nrect,
glamor_composite_rect_t *rects);
void glamor_composite_rects(CARD8 op,
PicturePtr pDst,
xRenderColor *color, int nRect, xRectangle *rects);
......@@ -994,6 +950,22 @@ void glamor_composite_rectangles(CARD8 op,
xRenderColor *color,
int num_rects, xRectangle *rects);
/* glamor_composite_glyphs.c */
Bool
glamor_composite_glyphs_init(ScreenPtr pScreen);
void
glamor_composite_glyphs_fini(ScreenPtr pScreen);
void
glamor_composite_glyphs(CARD8 op,
PicturePtr src,
PicturePtr dst,
PictFormatPtr mask_format,
INT16 x_src,
INT16 y_src, int nlist,
GlyphListPtr list, GlyphPtr *glyphs);
/* glamor_sync.c */
Bool
glamor_sync_init(ScreenPtr screen);
......@@ -1077,8 +1049,6 @@ void glamor_xv_render(glamor_port_private *port_priv);
#if 0
#define MAX_FBO_SIZE 32 /* For test purpose only. */
#endif
//#define GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
#define GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
#include "glamor_font.h"
......
......@@ -139,6 +139,10 @@ static glamor_location_var location_vars[] = {
.vs_vars = "uniform float dash_length;\n",
.fs_vars = "uniform sampler2D dash;\n",
},
{
.location = glamor_program_location_atlas,
.fs_vars = "uniform sampler2D atlas;\n",
},
};
#define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0])
......@@ -355,6 +359,7 @@ glamor_build_program(ScreenPtr screen,
prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul");
prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash");
prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length");
prog->atlas_uniform = glamor_get_uniform(prog, glamor_program_location_atlas, "atlas");
free(version_string);
free(fs_vars);
......
......@@ -81,6 +81,7 @@ struct _glamor_program {
GLint bitmul_uniform;
GLint dash_uniform;
GLint dash_length_uniform;
GLint atlas_uniform;
glamor_program_location locations;
glamor_program_flag flags;
glamor_use prim_use;
......
......@@ -1701,139 +1701,3 @@ glamor_composite(CARD8 op,
glamor_finish_access_picture(source);
glamor_finish_access_picture(dest);
}
static void
glamor_get_src_rect_extent(int nrect,
glamor_composite_rect_t *rects, BoxPtr extent)
{
extent->x1 = MAXSHORT;
extent->y1 = MAXSHORT;
extent->x2 = MINSHORT;
extent->y2 = MINSHORT;
while (nrect--) {
if (extent->x1 > rects->x_src)
extent->x1 = rects->x_src;
if (extent->y1 > rects->y_src)
extent->y1 = rects->y_src;
if (extent->x2 < rects->x_src + rects->width)
extent->x2 = rects->x_src + rects->width;
if (extent->y2 < rects->y_src + rects->height)
extent->y2 = rects->y_src + rects->height;
rects++;
}
}
static void
glamor_composite_src_rect_translate(int nrect,
glamor_composite_rect_t *rects,
int x, int y)
{
while (nrect--) {
rects->x_src += x;
rects->y_src += y;
rects++;
}
}
void
glamor_composite_glyph_rects(CARD8 op,
PicturePtr src, PicturePtr mask, PicturePtr dst,
int nrect, glamor_composite_rect_t *rects)
{
int n;
PicturePtr temp_src = NULL;
glamor_composite_rect_t *r;
ValidatePicture(src);
ValidatePicture(dst);
if (!(glamor_is_large_picture(src)
|| (mask && glamor_is_large_picture(mask))
|| glamor_is_large_picture(dst))) {
PixmapPtr src_pixmap = NULL;
PixmapPtr mask_pixmap = NULL;
PixmapPtr dst_pixmap = NULL;
PixmapPtr temp_src_pixmap = NULL;
glamor_pixmap_private *src_pixmap_priv = NULL;
glamor_pixmap_private *mask_pixmap_priv = NULL;
glamor_pixmap_private *dst_pixmap_priv;
glamor_pixmap_private *temp_src_priv = NULL;
BoxRec src_extent;
dst_pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
if (mask && mask->pDrawable) {
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
}
if (src->pDrawable) {
src_pixmap = glamor_get_drawable_pixmap(src->pDrawable);
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
}
if (!src->pDrawable
&& (src->pSourcePict->type != SourcePictTypeSolidFill)) {
glamor_get_src_rect_extent(nrect, rects, &src_extent);
temp_src = glamor_convert_gradient_picture(dst->pDrawable->pScreen,
src,
src_extent.x1,
src_extent.y1,
src_extent.x2 -
src_extent.x1,
src_extent.y2 -
src_extent.y1);
if (!temp_src)
goto fallback;
temp_src_pixmap = (PixmapPtr) (temp_src->pDrawable);
temp_src_priv = glamor_get_pixmap_private(temp_src_pixmap);
glamor_composite_src_rect_translate(nrect, rects,
-src_extent.x1, -src_extent.y1);
}
else {
temp_src = src;
temp_src_pixmap = src_pixmap;
temp_src_priv = src_pixmap_priv;
}
if (mask && mask->componentAlpha) {
if (op == PictOpOver) {
if (glamor_composite_with_shader(PictOpOutReverse,
temp_src, mask, dst,
temp_src_pixmap, mask_pixmap, dst_pixmap,
temp_src_priv,
mask_pixmap_priv,
dst_pixmap_priv, nrect, rects,
TRUE))
goto done;
}
}
else {
if (glamor_composite_with_shader
(op, temp_src, mask, dst,
temp_src_pixmap, mask_pixmap, dst_pixmap,
temp_src_priv, mask_pixmap_priv,
dst_pixmap_priv, nrect, rects, FALSE))
goto done;
}
}
fallback:
n = nrect;
r = rects;
while (n--) {
CompositePicture(op,
temp_src ? temp_src : src,
mask,
dst,
r->x_src, r->y_src,
r->x_mask, r->y_mask,
r->x_dst, r->y_dst, r->width, r->height);
r++;
}
done:
if (temp_src && temp_src != src)
FreePicture(temp_src, 0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment