Commit 9c6fd931 authored by Zhigang Gong's avatar Zhigang Gong Committed by Eric Anholt

glamor-fbo-pool: Enable to reuse different size fbo/texture.

Fixup three special cases, one is in tile and the other is in
composite. Both cases are due to repeat texture issue. Maybe
we can refine the shader to recalculate texture coords to
support partial texture's repeating.

The third is when upload a memory pixmap to texture, as now
the texture may not have the exact size as the pixmap, we
should not use the full rect coords.
Signed-off-by: default avatarZhigang Gong <zhigang.gong@linux.intel.com>
parent c7e79d6a
......@@ -164,7 +164,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
if (w == 0 || h == 0)
return pixmap;
fbo = glamor_create_fbo(glamor_priv, w, h, depth, 0);
fbo = glamor_create_fbo(glamor_priv, w, h, depth, usage);
if (fbo == NULL) {
fbDestroyPixmap(pixmap);
......
......@@ -90,7 +90,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
[cache_hbucket(h)];
if (flag != GLAMOR_CACHE_EXACT_SIZE) {
list_for_each_entry(fbo_entry, cache, list) {
if (fbo_entry->width == w && fbo_entry->height == h) {
if (fbo_entry->width >= w && fbo_entry->height >= h) {
DEBUGF("Request w %d h %d \n", w, h);
DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
......@@ -263,7 +263,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
gl_iformat_for_depth(depth, &format);
fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h,
format, GLAMOR_CACHE_EXACT_SIZE);
format, cache_flag);
if (fbo)
return fbo;
......
......@@ -216,7 +216,7 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
int in_restore = 0;
static void
__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
GLenum type, GLuint tex)
GLenum type, GLuint tex, int sub)
{
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
......@@ -255,12 +255,19 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
} else
texels = pixmap->devPrivate.ptr;
dispatch->glTexImage2D(GL_TEXTURE_2D,
0,
iformat,
pixmap->drawable.width,
pixmap->drawable.height, 0, format, type,
texels);
if (sub)
dispatch->glTexSubImage2D(GL_TEXTURE_2D,
0,0,0,
pixmap->drawable.width,
pixmap->drawable.height, format, type,
texels);
else
dispatch->glTexImage2D(GL_TEXTURE_2D,
0,
iformat,
pixmap->drawable.width,
pixmap->drawable.height, 0, format, type,
texels);
}
......@@ -280,11 +287,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
static float vertices[8] = { -1, -1,
1, -1,
1, 1,
-1, 1
};
static float vertices[8];
static float texcoords[8] = { 0, 1,
1, 1,
1, 0,
......@@ -296,7 +299,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
0, 1
};
float *ptexcoords;
float dst_xscale, dst_yscale;
GLuint tex;
int need_flip;
......@@ -315,16 +318,23 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
* to the fbo directly. */
if (no_alpha == 0 && no_revert == 1 && !need_flip) {
__glamor_upload_pixmap_to_texture(pixmap, format, type,
pixmap_priv->fbo->tex);
pixmap_priv->fbo->tex, 1);
return;
}
if (need_flip)
ptexcoords = texcoords;
else
ptexcoords = texcoords_inv;
pixmap_priv_get_scale(pixmap_priv, &dst_xscale, &dst_yscale);
glamor_set_normalize_vcoords(dst_xscale,
dst_yscale,
0, 0,
pixmap->drawable.width, pixmap->drawable.height,
glamor_priv->yInverted,
vertices);
/* Slow path, we need to flip y or wire alpha to 1. */
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
GL_FALSE, 2 * sizeof(float),
......@@ -338,7 +348,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
dispatch->glGenTextures(1, &tex);
__glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
__glamor_upload_pixmap_to_texture(pixmap, format, type, tex, 0);
dispatch->glActiveTexture(GL_TEXTURE0);
dispatch->glBindTexture(GL_TEXTURE_2D, tex);
......@@ -791,3 +801,66 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
return TRUE;
}
/* fixup a fbo to the exact size as the pixmap. */
Bool
glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
{
glamor_screen_private *glamor_priv;
glamor_pixmap_fbo *old_fbo;
glamor_pixmap_fbo *new_fbo = NULL;
PixmapPtr scratch = NULL;
glamor_pixmap_private *scratch_priv;
DrawablePtr drawable;
GCPtr gc = NULL;
int ret = FALSE;
drawable = &pixmap_priv->container->drawable;
if (pixmap_priv->container->drawable.width == pixmap_priv->fbo->width
&& pixmap_priv->container->drawable.height == pixmap_priv->fbo->height)
return TRUE;
old_fbo = pixmap_priv->fbo;
glamor_priv = pixmap_priv->glamor_priv;
if (!old_fbo)
return FALSE;
gc = GetScratchGC(drawable->depth, screen);
if (!gc)
goto fail;
scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
drawable->depth,
GLAMOR_CREATE_PIXMAP_FIXUP);
scratch_priv = glamor_get_pixmap_private(scratch);
if (!scratch_priv || !scratch_priv->fbo)
goto fail;
ValidateGC(&scratch->drawable, gc);
glamor_copy_area(drawable,
&scratch->drawable,
gc, 0, 0,
drawable->width, drawable->height,
0, 0);
old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
glamor_pixmap_attach_fbo(pixmap_priv->container, new_fbo);
glamor_pixmap_attach_fbo(scratch, old_fbo);
DEBUGF("old %dx%d type %d\n",
drawable->width, drawable->height, pixmap_priv->type);
DEBUGF("copy tex %d %dx%d to tex %d %dx%d \n",
old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex, new_fbo->width, new_fbo->height);
ret = TRUE;
fail:
if (gc)
FreeScratchGC(gc);
if (scratch)
glamor_destroy_pixmap(scratch);
return ret;
}
......@@ -594,6 +594,10 @@ void glamor_destroy_picture(PicturePtr picture);
enum glamor_pixmap_status
glamor_upload_picture_to_texture(PicturePtr picture);
/* fixup a fbo to the exact size as the pixmap. */
Bool
glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
void
glamor_picture_format_fixup(PicturePtr picture,
glamor_pixmap_private * pixmap_priv);
......
......@@ -342,7 +342,6 @@ glamor_fini_composite_shaders(ScreenPtr screen)
dispatch->glDeleteBuffers(1, &glamor_priv->vbo);
dispatch->glDeleteBuffers(1, &glamor_priv->ebo);
for(i = 0; i < SHADER_SOURCE_COUNT; i++)
for(j = 0; j < SHADER_MASK_COUNT; j++)
for(k = 0; k < SHADER_IN_COUNT; k++)
......@@ -408,6 +407,33 @@ glamor_set_composite_op(ScreenPtr screen,
return TRUE;
}
static void
glamor_composite_texture_fixup(ScreenPtr screen,
PicturePtr picture,
glamor_pixmap_private * pixmap_priv)
{
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
Bool has_repeat;
int width, height;
if (picture->repeatType == RepeatNone)
has_repeat = FALSE;
else
has_repeat = TRUE;
if (has_repeat
&& ( (pixmap_priv->container->drawable.width != pixmap_priv->fbo->width)
|| (pixmap_priv->container->drawable.height != pixmap_priv->fbo->height))) {
/* Currently, we can't support repeat on partial texture, now redirect it
* to an exact size fbo. */
DEBUGF("prepare to fixup texture \n");
if (!glamor_fixup_pixmap_priv(screen, pixmap_priv))
ErrorF("Failed to fixup a unmatch size of repeat picture. \n");
}
}
static void
glamor_set_composite_texture(ScreenPtr screen, int unit,
PicturePtr picture,
......@@ -979,6 +1005,12 @@ glamor_composite_with_shader(CARD8 op,
}
}
#endif
if (key.source != SHADER_SOURCE_SOLID)
glamor_composite_texture_fixup(screen, source, source_pixmap_priv);
if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID)
glamor_composite_texture_fixup(screen, mask, mask_pixmap_priv);
glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
glamor_validate_pixmap(dest_pixmap);
if (!glamor_set_composite_op(screen, op, dest, mask)) {
......
......@@ -127,8 +127,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
if (((tile_x != 0) && (tile_x + width > tile->drawable.width))
|| ((tile_y != 0)
&& (tile_y + height > tile->drawable.height))) {
/* XXX We can recreate a new pixmap here to avoid partial tiling. */
goto fail;
}
if (glamor_priv->tile_prog == 0) {
glamor_fallback("Tiling unsupported\n");
goto fail;
......@@ -148,6 +150,15 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
glamor_fallback("unsupported planemask %lx\n", planemask);
goto fail;
}
if (src_pixmap_priv->fbo->width != tile->drawable.width
|| src_pixmap_priv->fbo->height != tile->drawable.height) {
if (!glamor_fixup_pixmap_priv(screen, src_pixmap_priv)) {
glamor_fallback("Failed to create a fixup pixmap for partial tiling. \n");
goto fail;
}
}
if (alu != GXcopy) {
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
glamor_validate_pixmap(tile);
......
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