Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef GFX_XLIBSURFACE_H
7 : #define GFX_XLIBSURFACE_H
8 :
9 : #include "gfxASurface.h"
10 :
11 : #include <X11/extensions/Xrender.h>
12 : #include <X11/Xlib.h>
13 : #include "X11UndefineNone.h"
14 :
15 : #if defined(GL_PROVIDER_GLX)
16 : #include "GLXLibrary.h"
17 : #endif
18 :
19 : #include "nsSize.h"
20 :
21 : // Although the dimension parameters in the xCreatePixmapReq wire protocol are
22 : // 16-bit unsigned integers, the server's CreatePixmap returns BadAlloc if
23 : // either dimension cannot be represented by a 16-bit *signed* integer.
24 : #define XLIB_IMAGE_SIDE_SIZE_LIMIT 0x7fff
25 :
26 :
27 : class gfxXlibSurface final : public gfxASurface {
28 : public:
29 : // construct a wrapper around the specified drawable with dpy/visual.
30 : // Will use XGetGeometry to query the window/pixmap size.
31 : gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual);
32 :
33 : // construct a wrapper around the specified drawable with dpy/visual,
34 : // and known width/height.
35 : gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const mozilla::gfx::IntSize& size);
36 :
37 : // construct a wrapper around the specified drawable with dpy/format,
38 : // and known width/height.
39 : gfxXlibSurface(::Screen *screen, Drawable drawable, XRenderPictFormat *format,
40 : const mozilla::gfx::IntSize& size);
41 :
42 : explicit gfxXlibSurface(cairo_surface_t *csurf);
43 :
44 : // create a new Pixmap and wrapper surface.
45 : // |relatedDrawable| provides a hint to the server for determining whether
46 : // the pixmap should be in video or system memory. It must be on
47 : // |screen| (if specified).
48 : static already_AddRefed<gfxXlibSurface>
49 : Create(::Screen *screen, Visual *visual, const mozilla::gfx::IntSize& size,
50 : Drawable relatedDrawable = X11None);
51 : static cairo_surface_t *
52 : CreateCairoSurface(::Screen *screen, Visual *visual, const mozilla::gfx::IntSize& size,
53 : Drawable relatedDrawable = X11None);
54 : static already_AddRefed<gfxXlibSurface>
55 : Create(::Screen* screen, XRenderPictFormat *format, const mozilla::gfx::IntSize& size,
56 : Drawable relatedDrawable = X11None);
57 :
58 : virtual ~gfxXlibSurface();
59 :
60 : virtual already_AddRefed<gfxASurface>
61 : CreateSimilarSurface(gfxContentType aType,
62 : const mozilla::gfx::IntSize& aSize) override;
63 : virtual void Finish() override;
64 :
65 : virtual const mozilla::gfx::IntSize GetSize() const override;
66 :
67 0 : Display* XDisplay() { return mDisplay; }
68 : ::Screen* XScreen();
69 0 : Drawable XDrawable() { return mDrawable; }
70 : XRenderPictFormat* XRenderFormat();
71 :
72 : static int DepthOfVisual(const ::Screen* screen, const Visual* visual);
73 : static Visual* FindVisual(::Screen* screen, gfxImageFormat format);
74 : static XRenderPictFormat *FindRenderFormat(Display *dpy, gfxImageFormat format);
75 : static bool GetColormapAndVisual(cairo_surface_t* aXlibSurface, Colormap* colormap, Visual **visual);
76 :
77 : // take ownership of a passed-in Pixmap, calling XFreePixmap on it
78 : // when the gfxXlibSurface is destroyed.
79 : void TakePixmap();
80 :
81 : // Release ownership of this surface's Pixmap. This is only valid
82 : // on gfxXlibSurfaces for which the user called TakePixmap(), or
83 : // on those created by a Create() factory method.
84 : Drawable ReleasePixmap();
85 :
86 : // Find a visual and colormap pair suitable for rendering to this surface.
87 : bool GetColormapAndVisual(Colormap* colormap, Visual **visual);
88 :
89 : #if defined(GL_PROVIDER_GLX)
90 : GLXPixmap GetGLXPixmap();
91 : // Binds a GLXPixmap backed by this context's surface.
92 : // Primarily for use in sharing surfaces.
93 : void BindGLXPixmap(GLXPixmap aPixmap);
94 : #endif
95 :
96 : // Return true if cairo will take its slow path when this surface is used
97 : // in a pattern with EXTEND_PAD. As a workaround for XRender's RepeatPad
98 : // not being implemented correctly on old X servers, cairo avoids XRender
99 : // and instead reads back to perform EXTEND_PAD with pixman. Cairo does
100 : // this for servers older than xorg-server 1.7.
101 : bool IsPadSlow() {
102 : // The test here matches that for buggy_pad_reflect in
103 : // _cairo_xlib_device_create.
104 : return VendorRelease(mDisplay) >= 60700000 ||
105 : VendorRelease(mDisplay) < 10699000;
106 : }
107 :
108 : protected:
109 : // if TakePixmap() has been called on this
110 : bool mPixmapTaken;
111 :
112 : Display *mDisplay;
113 : Drawable mDrawable;
114 :
115 : const mozilla::gfx::IntSize DoSizeQuery();
116 :
117 : #if defined(GL_PROVIDER_GLX)
118 : GLXPixmap mGLXPixmap;
119 : #endif
120 : };
121 :
122 : #endif /* GFX_XLIBSURFACE_H */
|