b=572968 use gdk_pixmap_foreign_new_for_screen to avoid XGetGeometry round trip r=jrmuizel

This commit is contained in:
Karl Tomlinson 2010-06-23 11:11:42 +12:00
parent a25ef46bc3
commit 6823bb4d5e
3 changed files with 55 additions and 52 deletions

View File

@ -71,12 +71,7 @@ public:
virtual ~gfxXlibSurface();
const gfxIntSize& GetSize() {
if (mSize.width == -1 || mSize.height == -1)
DoSizeQuery();
return mSize;
}
const gfxIntSize& GetSize() { return mSize; }
Display* XDisplay() { return mDisplay; }
Drawable XDrawable() { return mDrawable; }

View File

@ -741,23 +741,8 @@ gfxPlatformGtk::SetGdkDrawable(gfxASurface *target,
#ifdef MOZ_X11
// Look for an existing Colormap that is known to be associated with visual.
static GdkColormap *
LookupGdkColormapForVisual(const Screen* screen, const Visual* visual)
LookupGdkColormapForVisual(GdkScreen* gdkScreen, const Visual* visual)
{
Display* dpy = DisplayOfScreen(screen);
GdkDisplay* gdkDpy = gdk_x11_lookup_xdisplay(dpy);
if (!gdkDpy)
return NULL;
// I wish there were a gdk_x11_display_lookup_screen.
gint screen_num = 0;
for (int s = 0; s < ScreenCount(dpy); ++s) {
if (ScreenOfDisplay(dpy, s) == screen) {
screen_num = s;
break;
}
}
GdkScreen* gdkScreen = gdk_display_get_screen(gdkDpy, screen_num);
// Common case: the display's default colormap
if (visual ==
GDK_VISUAL_XVISUAL(gdk_screen_get_system_visual(gdkScreen)))
@ -790,7 +775,7 @@ GdkDrawable *
gfxPlatformGtk::GetGdkDrawable(gfxASurface *target)
{
if (target->CairoStatus())
return nsnull;
return NULL;
GdkDrawable *result;
@ -800,39 +785,60 @@ gfxPlatformGtk::GetGdkDrawable(gfxASurface *target)
return result;
#ifdef MOZ_X11
if (target->GetType() == gfxASurface::SurfaceTypeXlib) {
gfxXlibSurface *xs = (gfxXlibSurface*) target;
if (target->GetType() != gfxASurface::SurfaceTypeXlib)
return NULL;
// try looking it up in gdk's table
result = (GdkDrawable*) gdk_xid_table_lookup(xs->XDrawable());
if (result) {
SetGdkDrawable(target, result);
return result;
}
gfxXlibSurface *xs = static_cast<gfxXlibSurface*>(target);
// If all else fails, try doing a foreign_new
// but don't bother if we can't get a colormap.
// Without a colormap GDK won't know how to draw.
Screen *screen = cairo_xlib_surface_get_screen(xs->CairoSurface());
Visual *visual = cairo_xlib_surface_get_visual(xs->CairoSurface());
GdkColormap *cmap = LookupGdkColormapForVisual(screen, visual);
if (cmap == None)
return nsnull;
// try looking it up in gdk's table
result = (GdkDrawable*) gdk_xid_table_lookup(xs->XDrawable());
if (result) {
SetGdkDrawable(target, result);
return result;
}
result = (GdkDrawable*) gdk_pixmap_foreign_new_for_display
(gdk_display_get_default(), xs->XDrawable());
if (result) {
gdk_drawable_set_colormap(result, cmap);
// If all else fails, try doing a foreign_new
// but don't bother if we can't get a colormap.
// Without a colormap GDK won't know how to draw.
Screen *screen = cairo_xlib_surface_get_screen(xs->CairoSurface());
Visual *visual = cairo_xlib_surface_get_visual(xs->CairoSurface());
Display* dpy = DisplayOfScreen(screen);
SetGdkDrawable(target, result);
// Release our ref. The object is held by target. Caller will
// only need to ref if it wants to keep the drawable longer than
// target.
g_object_unref(result);
return result;
GdkDisplay* gdkDpy = gdk_x11_lookup_xdisplay(dpy);
if (!gdkDpy)
return NULL;
// I wish there were a gdk_x11_display_lookup_screen.
gint screen_num = 0;
for (int s = 0; s < ScreenCount(dpy); ++s) {
if (ScreenOfDisplay(dpy, s) == screen) {
screen_num = s;
break;
}
}
#endif
GdkScreen* gdkScreen = gdk_display_get_screen(gdkDpy, screen_num);
return nsnull;
GdkColormap *cmap = LookupGdkColormapForVisual(gdkScreen, visual);
if (cmap == NULL)
return NULL;
gfxIntSize size = xs->GetSize();
int depth = cairo_xlib_surface_get_depth(xs->CairoSurface());
result = gdk_pixmap_foreign_new_for_screen(gdkScreen, xs->XDrawable(),
size.width, size.height, depth);
if (!result)
return NULL;
gdk_drawable_set_colormap(result, cmap);
SetGdkDrawable(target, result);
// Release our ref. The object is held by target. Caller will
// only need to ref if it wants to keep the drawable longer than
// target.
g_object_unref(result);
return result;
#else
return NULL;
#endif
}

View File

@ -118,7 +118,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, XRenderPictFormat *format, const gf
}
gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf)
: mPixmapTaken(PR_FALSE), mSize(-1.0, -1.0)
: mPixmapTaken(PR_FALSE),
mSize(cairo_xlib_surface_get_width(csurf),
cairo_xlib_surface_get_height(csurf))
{
mDrawable = cairo_xlib_surface_get_drawable(csurf);
mDisplay = cairo_xlib_surface_get_display(csurf);