xserver-multidpi/glamor/glamor_window.c

104 lines
3.3 KiB
C
Raw Normal View History

/*
* Copyright © 2008 Intel Corporation
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "glamor_priv.h"
/** @file glamor_window.c
*
* Screen Change Window Attribute implementation.
*/
static void
glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr * ppPixmap)
{
PixmapPtr pPixmap = *ppPixmap;
glamor_pixmap_private *pixmap_priv;
if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
pixmap_priv = glamor_get_pixmap_private(pPixmap);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
glamor_fallback("pixmap %p has no fbo\n", pPixmap);
goto fail;
}
glamor_debug_output(GLAMOR_DEBUG_UNIMPL,
"To be implemented.\n");
}
return;
fail:
GLAMOR_PANIC
(" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile"
" is broken for glamor. \n");
}
Bool
glamor_change_window_attributes(WindowPtr pWin, unsigned long mask)
{
if (mask & CWBackPixmap) {
if (pWin->backgroundState == BackgroundPixmap)
glamor_fixup_window_pixmap(&pWin->drawable,
&pWin->
background.pixmap);
}
if (mask & CWBorderPixmap) {
if (pWin->borderIsPixel == FALSE)
glamor_fixup_window_pixmap(&pWin->drawable,
&pWin->border.pixmap);
}
return TRUE;
}
fixup picture in SetWindowPixmap When creating a window with recordmydesktop running, the following may happen: create picture 0x1cd457e0, with drawable 0x1327d1f0 (SetWindowPixmap is called) destroy picture 0x1cd457e0, with drawable 0x1cd65820 Obtaining format for pixmap 0x1327d1f0 and picture 0x1cd457e0 ==7989== Invalid read of size 4 ==7989== at 0x8CAA0CA: glamor_get_tex_format_type_from_pixmap (glamor_utils.h:1252) ==7989== by 0x8CAD1B7: glamor_download_sub_pixmap_to_cpu (glamor_pixmap.c:1074) ==7989== by 0x8CA8BB7: _glamor_get_image (glamor_getimage.c:66) ==7989== by 0x8CA8D2F: glamor_get_image (glamor_getimage.c:92) ==7989== by 0x29AEF2: miSpriteGetImage (misprite.c:413) ==7989== by 0x1E7674: compGetImage (compinit.c:148) ==7989== by 0x1F5E5B: ProcShmGetImage (shm.c:684) ==7989== by 0x1F686F: ProcShmDispatch (shm.c:1121) ==7989== by 0x15D00D: Dispatch (dispatch.c:432) ==7989== by 0x14C569: main (main.c:298) ==7989== Address 0x1cd457f0 is 16 bytes inside a block of size 120 free'd ==7989== at 0x4C2B60C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==7989== by 0x228897: FreePicture (picture.c:1477) ==7989== by 0x228B23: PictureDestroyWindow (picture.c:73) ==7989== by 0x234C19: damageDestroyWindow (damage.c:1646) ==7989== by 0x1E92C0: compDestroyWindow (compwindow.c:590) ==7989== by 0x20FF85: DbeDestroyWindow (dbe.c:1389) ==7989== by 0x185D46: FreeWindowResources (window.c:907) ==7989== by 0x1889A7: DeleteWindow (window.c:975) ==7989== by 0x17EBF1: doFreeResource (resource.c:873) ==7989== by 0x17FC1B: FreeClientResources (resource.c:1139) ==7989== by 0x15C4DE: CloseDownClient (dispatch.c:3402) ==7989== by 0x2AB843: CheckConnections (connection.c:1008) ==7989== (II) fail to get matched format for dfdfdfdf The fix is to update the picture pointer when the window pixmap is changed, so it moves the picture around with the window rather than the pixmap. This makes FreePicture work correctly. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71088 Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
2013-11-06 10:25:27 +01:00
void
glamor_set_window_pixmap(WindowPtr win, PixmapPtr pPixmap)
{
ScreenPtr screen = win->drawable.pScreen;
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
PixmapPtr old = screen->GetWindowPixmap(win);
if (pPixmap != old) {
glamor_pixmap_private *pixmap_priv;
PicturePtr pic = NULL;
pixmap_priv = glamor_get_pixmap_private(old);
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) && pixmap_priv->base.picture->pDrawable == (DrawablePtr)win) {
pic = pixmap_priv->base.picture;
pixmap_priv->base.is_picture = 0;
pixmap_priv->base.picture = NULL;
}
pixmap_priv = glamor_get_pixmap_private(pPixmap);
if (pixmap_priv) {
pixmap_priv->base.is_picture = !!pic;
pixmap_priv->base.picture = pic;
}
}
screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
(screen->SetWindowPixmap)(win, pPixmap);
glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
screen->SetWindowPixmap = glamor_set_window_pixmap;
}