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: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
parent
c7e79d6acf
commit
9c6fd931a6
|
@ -164,7 +164,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
|
||||||
if (w == 0 || h == 0)
|
if (w == 0 || h == 0)
|
||||||
return pixmap;
|
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) {
|
if (fbo == NULL) {
|
||||||
fbDestroyPixmap(pixmap);
|
fbDestroyPixmap(pixmap);
|
||||||
|
|
|
@ -90,7 +90,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
|
||||||
[cache_hbucket(h)];
|
[cache_hbucket(h)];
|
||||||
if (flag != GLAMOR_CACHE_EXACT_SIZE) {
|
if (flag != GLAMOR_CACHE_EXACT_SIZE) {
|
||||||
list_for_each_entry(fbo_entry, cache, list) {
|
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("Request w %d h %d \n", w, h);
|
||||||
DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
|
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);
|
gl_iformat_for_depth(depth, &format);
|
||||||
fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h,
|
fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h,
|
||||||
format, GLAMOR_CACHE_EXACT_SIZE);
|
format, cache_flag);
|
||||||
if (fbo)
|
if (fbo)
|
||||||
return fbo;
|
return fbo;
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
|
||||||
int in_restore = 0;
|
int in_restore = 0;
|
||||||
static void
|
static void
|
||||||
__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
|
__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_pixmap_private *pixmap_priv =
|
||||||
glamor_get_pixmap_private(pixmap);
|
glamor_get_pixmap_private(pixmap);
|
||||||
|
@ -255,12 +255,19 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
|
||||||
} else
|
} else
|
||||||
texels = pixmap->devPrivate.ptr;
|
texels = pixmap->devPrivate.ptr;
|
||||||
|
|
||||||
dispatch->glTexImage2D(GL_TEXTURE_2D,
|
if (sub)
|
||||||
0,
|
dispatch->glTexSubImage2D(GL_TEXTURE_2D,
|
||||||
iformat,
|
0,0,0,
|
||||||
pixmap->drawable.width,
|
pixmap->drawable.width,
|
||||||
pixmap->drawable.height, 0, format, type,
|
pixmap->drawable.height, format, type,
|
||||||
texels);
|
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_screen_private *glamor_priv =
|
||||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||||
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
|
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
|
||||||
static float vertices[8] = { -1, -1,
|
static float vertices[8];
|
||||||
1, -1,
|
|
||||||
1, 1,
|
|
||||||
-1, 1
|
|
||||||
};
|
|
||||||
static float texcoords[8] = { 0, 1,
|
static float texcoords[8] = { 0, 1,
|
||||||
1, 1,
|
1, 1,
|
||||||
1, 0,
|
1, 0,
|
||||||
|
@ -296,7 +299,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
|
||||||
0, 1
|
0, 1
|
||||||
};
|
};
|
||||||
float *ptexcoords;
|
float *ptexcoords;
|
||||||
|
float dst_xscale, dst_yscale;
|
||||||
GLuint tex;
|
GLuint tex;
|
||||||
int need_flip;
|
int need_flip;
|
||||||
|
|
||||||
|
@ -315,16 +318,23 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
|
||||||
* to the fbo directly. */
|
* to the fbo directly. */
|
||||||
if (no_alpha == 0 && no_revert == 1 && !need_flip) {
|
if (no_alpha == 0 && no_revert == 1 && !need_flip) {
|
||||||
__glamor_upload_pixmap_to_texture(pixmap, format, type,
|
__glamor_upload_pixmap_to_texture(pixmap, format, type,
|
||||||
pixmap_priv->fbo->tex);
|
pixmap_priv->fbo->tex, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (need_flip)
|
if (need_flip)
|
||||||
ptexcoords = texcoords;
|
ptexcoords = texcoords;
|
||||||
else
|
else
|
||||||
ptexcoords = texcoords_inv;
|
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. */
|
/* Slow path, we need to flip y or wire alpha to 1. */
|
||||||
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||||
GL_FALSE, 2 * sizeof(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);
|
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
||||||
dispatch->glGenTextures(1, &tex);
|
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->glActiveTexture(GL_TEXTURE0);
|
||||||
dispatch->glBindTexture(GL_TEXTURE_2D, tex);
|
dispatch->glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
|
|
||||||
|
@ -791,3 +801,66 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
||||||
|
|
||||||
return TRUE;
|
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
|
enum glamor_pixmap_status
|
||||||
glamor_upload_picture_to_texture(PicturePtr picture);
|
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
|
void
|
||||||
glamor_picture_format_fixup(PicturePtr picture,
|
glamor_picture_format_fixup(PicturePtr picture,
|
||||||
glamor_pixmap_private * pixmap_priv);
|
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->vbo);
|
||||||
dispatch->glDeleteBuffers(1, &glamor_priv->ebo);
|
dispatch->glDeleteBuffers(1, &glamor_priv->ebo);
|
||||||
|
|
||||||
|
|
||||||
for(i = 0; i < SHADER_SOURCE_COUNT; i++)
|
for(i = 0; i < SHADER_SOURCE_COUNT; i++)
|
||||||
for(j = 0; j < SHADER_MASK_COUNT; j++)
|
for(j = 0; j < SHADER_MASK_COUNT; j++)
|
||||||
for(k = 0; k < SHADER_IN_COUNT; k++)
|
for(k = 0; k < SHADER_IN_COUNT; k++)
|
||||||
|
@ -408,6 +407,33 @@ glamor_set_composite_op(ScreenPtr screen,
|
||||||
return TRUE;
|
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
|
static void
|
||||||
glamor_set_composite_texture(ScreenPtr screen, int unit,
|
glamor_set_composite_texture(ScreenPtr screen, int unit,
|
||||||
PicturePtr picture,
|
PicturePtr picture,
|
||||||
|
@ -979,6 +1005,12 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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_set_destination_pixmap_priv_nc(dest_pixmap_priv);
|
||||||
glamor_validate_pixmap(dest_pixmap);
|
glamor_validate_pixmap(dest_pixmap);
|
||||||
if (!glamor_set_composite_op(screen, op, dest, mask)) {
|
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))
|
if (((tile_x != 0) && (tile_x + width > tile->drawable.width))
|
||||||
|| ((tile_y != 0)
|
|| ((tile_y != 0)
|
||||||
&& (tile_y + height > tile->drawable.height))) {
|
&& (tile_y + height > tile->drawable.height))) {
|
||||||
|
/* XXX We can recreate a new pixmap here to avoid partial tiling. */
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glamor_priv->tile_prog == 0) {
|
if (glamor_priv->tile_prog == 0) {
|
||||||
glamor_fallback("Tiling unsupported\n");
|
glamor_fallback("Tiling unsupported\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -148,6 +150,15 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
glamor_fallback("unsupported planemask %lx\n", planemask);
|
glamor_fallback("unsupported planemask %lx\n", planemask);
|
||||||
goto fail;
|
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) {
|
if (alu != GXcopy) {
|
||||||
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
|
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
|
||||||
glamor_validate_pixmap(tile);
|
glamor_validate_pixmap(tile);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user