xref: /OK3568_Linux_fs/external/xserver/hw/xwayland/xwayland-glamor.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright © 2011-2014 Intel Corporation
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission to use, copy, modify, distribute, and sell this software
5*4882a593Smuzhiyun  * and its documentation for any purpose is hereby granted without
6*4882a593Smuzhiyun  * fee, provided that the above copyright notice appear in all copies
7*4882a593Smuzhiyun  * and that both that copyright notice and this permission notice
8*4882a593Smuzhiyun  * appear in supporting documentation, and that the name of the
9*4882a593Smuzhiyun  * copyright holders not be used in advertising or publicity
10*4882a593Smuzhiyun  * pertaining to distribution of the software without specific,
11*4882a593Smuzhiyun  * written prior permission.  The copyright holders make no
12*4882a593Smuzhiyun  * representations about the suitability of this software for any
13*4882a593Smuzhiyun  * purpose.  It is provided "as is" without express or implied
14*4882a593Smuzhiyun  * warranty.
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17*4882a593Smuzhiyun  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18*4882a593Smuzhiyun  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19*4882a593Smuzhiyun  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20*4882a593Smuzhiyun  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
21*4882a593Smuzhiyun  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
22*4882a593Smuzhiyun  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
23*4882a593Smuzhiyun  * SOFTWARE.
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #include "xwayland.h"
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define MESA_EGL_NO_X11_HEADERS
29*4882a593Smuzhiyun #define EGL_NO_X11
30*4882a593Smuzhiyun #include <glamor_egl.h>
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #include <glamor.h>
33*4882a593Smuzhiyun #include <glamor_context.h>
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun static void
glamor_egl_make_current(struct glamor_context * glamor_ctx)36*4882a593Smuzhiyun glamor_egl_make_current(struct glamor_context *glamor_ctx)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun     eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
39*4882a593Smuzhiyun                    EGL_NO_SURFACE, EGL_NO_CONTEXT);
40*4882a593Smuzhiyun     if (!eglMakeCurrent(glamor_ctx->display,
41*4882a593Smuzhiyun                         EGL_NO_SURFACE, EGL_NO_SURFACE,
42*4882a593Smuzhiyun                         glamor_ctx->ctx))
43*4882a593Smuzhiyun         FatalError("Failed to make EGL context current\n");
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun void
xwl_glamor_egl_make_current(struct xwl_screen * xwl_screen)47*4882a593Smuzhiyun xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun     if (lastGLContext == xwl_screen->glamor_ctx)
50*4882a593Smuzhiyun         return;
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun     lastGLContext = xwl_screen->glamor_ctx;
53*4882a593Smuzhiyun     xwl_screen->glamor_ctx->make_current(xwl_screen->glamor_ctx);
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun void
glamor_egl_screen_init(ScreenPtr screen,struct glamor_context * glamor_ctx)57*4882a593Smuzhiyun glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun     struct xwl_screen *xwl_screen = xwl_screen_get(screen);
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun     glamor_enable_dri3(screen);
62*4882a593Smuzhiyun     glamor_ctx->ctx = xwl_screen->egl_context;
63*4882a593Smuzhiyun     glamor_ctx->display = xwl_screen->egl_display;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun     glamor_ctx->make_current = glamor_egl_make_current;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun     xwl_screen->glamor_ctx = glamor_ctx;
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun void
xwl_glamor_init_wl_registry(struct xwl_screen * xwl_screen,struct wl_registry * registry,uint32_t id,const char * interface,uint32_t version)71*4882a593Smuzhiyun xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
72*4882a593Smuzhiyun                             struct wl_registry *registry,
73*4882a593Smuzhiyun                             uint32_t id, const char *interface,
74*4882a593Smuzhiyun                             uint32_t version)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun     if (xwl_screen->gbm_backend.is_available &&
77*4882a593Smuzhiyun         xwl_screen->gbm_backend.init_wl_registry(xwl_screen,
78*4882a593Smuzhiyun                                                  registry,
79*4882a593Smuzhiyun                                                  id,
80*4882a593Smuzhiyun                                                  interface,
81*4882a593Smuzhiyun                                                  version)); /* no-op */
82*4882a593Smuzhiyun     else if (xwl_screen->eglstream_backend.is_available &&
83*4882a593Smuzhiyun              xwl_screen->eglstream_backend.init_wl_registry(xwl_screen,
84*4882a593Smuzhiyun                                                             registry,
85*4882a593Smuzhiyun                                                             id,
86*4882a593Smuzhiyun                                                             interface,
87*4882a593Smuzhiyun                                                             version)); /* no-op */
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun Bool
xwl_glamor_has_wl_interfaces(struct xwl_screen * xwl_screen,struct xwl_egl_backend * xwl_egl_backend)91*4882a593Smuzhiyun xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
92*4882a593Smuzhiyun                             struct xwl_egl_backend *xwl_egl_backend)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun     return xwl_egl_backend->has_wl_interfaces(xwl_screen);
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun struct wl_buffer *
xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap,Bool * created)98*4882a593Smuzhiyun xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap,
99*4882a593Smuzhiyun                                 Bool *created)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun     struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun     if (xwl_screen->egl_backend->get_wl_buffer_for_pixmap)
104*4882a593Smuzhiyun         return xwl_screen->egl_backend->get_wl_buffer_for_pixmap(pixmap,
105*4882a593Smuzhiyun                                                                  created);
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun     return NULL;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun void
xwl_glamor_post_damage(struct xwl_window * xwl_window,PixmapPtr pixmap,RegionPtr region)111*4882a593Smuzhiyun xwl_glamor_post_damage(struct xwl_window *xwl_window,
112*4882a593Smuzhiyun                        PixmapPtr pixmap, RegionPtr region)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun     if (xwl_screen->egl_backend->post_damage)
117*4882a593Smuzhiyun         xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region);
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun Bool
xwl_glamor_allow_commits(struct xwl_window * xwl_window)121*4882a593Smuzhiyun xwl_glamor_allow_commits(struct xwl_window *xwl_window)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun     if (xwl_screen->egl_backend->allow_commits)
126*4882a593Smuzhiyun         return xwl_screen->egl_backend->allow_commits(xwl_window);
127*4882a593Smuzhiyun     else
128*4882a593Smuzhiyun         return TRUE;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun static Bool
xwl_glamor_create_screen_resources(ScreenPtr screen)132*4882a593Smuzhiyun xwl_glamor_create_screen_resources(ScreenPtr screen)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun     struct xwl_screen *xwl_screen = xwl_screen_get(screen);
135*4882a593Smuzhiyun     int ret;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun     screen->CreateScreenResources = xwl_screen->CreateScreenResources;
138*4882a593Smuzhiyun     ret = (*screen->CreateScreenResources) (screen);
139*4882a593Smuzhiyun     xwl_screen->CreateScreenResources = screen->CreateScreenResources;
140*4882a593Smuzhiyun     screen->CreateScreenResources = xwl_glamor_create_screen_resources;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun     if (!ret)
143*4882a593Smuzhiyun         return ret;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun     if (xwl_screen->rootless) {
146*4882a593Smuzhiyun         screen->devPrivate =
147*4882a593Smuzhiyun             fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0);
148*4882a593Smuzhiyun     }
149*4882a593Smuzhiyun     else {
150*4882a593Smuzhiyun         screen->devPrivate = screen->CreatePixmap(
151*4882a593Smuzhiyun             screen, screen->width, screen->height, screen->rootDepth,
152*4882a593Smuzhiyun             CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
153*4882a593Smuzhiyun     }
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun     SetRootClip(screen, xwl_screen->root_clip_mode);
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun     return screen->devPrivate != NULL;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun int
glamor_egl_fd_name_from_pixmap(ScreenPtr screen,PixmapPtr pixmap,CARD16 * stride,CARD32 * size)161*4882a593Smuzhiyun glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
162*4882a593Smuzhiyun                                PixmapPtr pixmap,
163*4882a593Smuzhiyun                                CARD16 *stride, CARD32 *size)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun     return 0;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun void
xwl_glamor_init_backends(struct xwl_screen * xwl_screen,Bool use_eglstream)169*4882a593Smuzhiyun xwl_glamor_init_backends(struct xwl_screen *xwl_screen, Bool use_eglstream)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun #ifdef GLAMOR_HAS_GBM
172*4882a593Smuzhiyun     xwl_glamor_init_gbm(xwl_screen);
173*4882a593Smuzhiyun     if (!xwl_screen->gbm_backend.is_available && !use_eglstream)
174*4882a593Smuzhiyun         ErrorF("xwayland glamor: GBM backend (default) is not available\n");
175*4882a593Smuzhiyun #endif
176*4882a593Smuzhiyun #ifdef XWL_HAS_EGLSTREAM
177*4882a593Smuzhiyun     xwl_glamor_init_eglstream(xwl_screen);
178*4882a593Smuzhiyun     if (!xwl_screen->eglstream_backend.is_available && use_eglstream)
179*4882a593Smuzhiyun         ErrorF("xwayland glamor: EGLStream backend requested but not available\n");
180*4882a593Smuzhiyun #endif
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun static Bool
xwl_glamor_select_gbm_backend(struct xwl_screen * xwl_screen)184*4882a593Smuzhiyun xwl_glamor_select_gbm_backend(struct xwl_screen *xwl_screen)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun #ifdef GLAMOR_HAS_GBM
187*4882a593Smuzhiyun     if (xwl_screen->gbm_backend.is_available &&
188*4882a593Smuzhiyun         xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->gbm_backend)) {
189*4882a593Smuzhiyun         xwl_screen->egl_backend = &xwl_screen->gbm_backend;
190*4882a593Smuzhiyun         return TRUE;
191*4882a593Smuzhiyun     }
192*4882a593Smuzhiyun     else
193*4882a593Smuzhiyun         ErrorF("Missing Wayland requirements for glamor GBM backend\n");
194*4882a593Smuzhiyun #endif
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun     return FALSE;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun static Bool
xwl_glamor_select_eglstream_backend(struct xwl_screen * xwl_screen)200*4882a593Smuzhiyun xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun #ifdef XWL_HAS_EGLSTREAM
203*4882a593Smuzhiyun     if (xwl_screen->eglstream_backend.is_available &&
204*4882a593Smuzhiyun         xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->eglstream_backend)) {
205*4882a593Smuzhiyun         ErrorF("glamor: Using nvidia's EGLStream interface, direct rendering impossible.\n");
206*4882a593Smuzhiyun         ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n");
207*4882a593Smuzhiyun         xwl_screen->egl_backend = &xwl_screen->eglstream_backend;
208*4882a593Smuzhiyun         return TRUE;
209*4882a593Smuzhiyun     }
210*4882a593Smuzhiyun     else
211*4882a593Smuzhiyun         ErrorF("Missing Wayland requirements for glamor EGLStream backend\n");
212*4882a593Smuzhiyun #endif
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun     return FALSE;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun void
xwl_glamor_select_backend(struct xwl_screen * xwl_screen,Bool use_eglstream)218*4882a593Smuzhiyun xwl_glamor_select_backend(struct xwl_screen *xwl_screen, Bool use_eglstream)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun     if (use_eglstream) {
221*4882a593Smuzhiyun         if (!xwl_glamor_select_eglstream_backend(xwl_screen))
222*4882a593Smuzhiyun             xwl_glamor_select_gbm_backend(xwl_screen);
223*4882a593Smuzhiyun     }
224*4882a593Smuzhiyun     else {
225*4882a593Smuzhiyun         if (!xwl_glamor_select_gbm_backend(xwl_screen))
226*4882a593Smuzhiyun             xwl_glamor_select_eglstream_backend(xwl_screen);
227*4882a593Smuzhiyun     }
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun Bool
xwl_glamor_init(struct xwl_screen * xwl_screen)231*4882a593Smuzhiyun xwl_glamor_init(struct xwl_screen *xwl_screen)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun     ScreenPtr screen = xwl_screen->screen;
234*4882a593Smuzhiyun     const char *no_glamor_env;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun     no_glamor_env = getenv("XWAYLAND_NO_GLAMOR");
237*4882a593Smuzhiyun     if (no_glamor_env && *no_glamor_env != '0') {
238*4882a593Smuzhiyun         ErrorF("Disabling glamor and dri3 support, XWAYLAND_NO_GLAMOR is set\n");
239*4882a593Smuzhiyun         return FALSE;
240*4882a593Smuzhiyun     }
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun     if (!xwl_screen->egl_backend->init_egl(xwl_screen)) {
243*4882a593Smuzhiyun         ErrorF("EGL setup failed, disabling glamor\n");
244*4882a593Smuzhiyun         return FALSE;
245*4882a593Smuzhiyun     }
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun     if (!glamor_init(xwl_screen->screen, GLAMOR_USE_EGL_SCREEN)) {
248*4882a593Smuzhiyun         ErrorF("Failed to initialize glamor\n");
249*4882a593Smuzhiyun         return FALSE;
250*4882a593Smuzhiyun     }
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun     if (!xwl_screen->egl_backend->init_screen(xwl_screen)) {
253*4882a593Smuzhiyun         ErrorF("EGL backend init_screen() failed, disabling glamor\n");
254*4882a593Smuzhiyun         return FALSE;
255*4882a593Smuzhiyun     }
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun     xwl_screen->CreateScreenResources = screen->CreateScreenResources;
258*4882a593Smuzhiyun     screen->CreateScreenResources = xwl_glamor_create_screen_resources;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun #ifdef XV
261*4882a593Smuzhiyun     if (!xwl_glamor_xv_init(screen))
262*4882a593Smuzhiyun         ErrorF("Failed to initialize glamor Xv extension\n");
263*4882a593Smuzhiyun #endif
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun     return TRUE;
266*4882a593Smuzhiyun }
267