1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright © 2009 Intel Corporation
3*4882a593Smuzhiyun * Copyright © 1998 Keith Packard
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
6*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
7*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
8*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
10*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * The above copyright notice and this permission notice (including the next
13*4882a593Smuzhiyun * paragraph) shall be included in all copies or substantial portions of the
14*4882a593Smuzhiyun * Software.
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*4882a593Smuzhiyun * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*4882a593Smuzhiyun * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*4882a593Smuzhiyun * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*4882a593Smuzhiyun * IN THE SOFTWARE.
23*4882a593Smuzhiyun *
24*4882a593Smuzhiyun * Authors:
25*4882a593Smuzhiyun * Zhigang Gong <zhigang.gong@gmail.com>
26*4882a593Smuzhiyun *
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #include <stdlib.h>
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include "glamor_priv.h"
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun void
glamor_destroy_fbo(glamor_screen_private * glamor_priv,glamor_pixmap_fbo * fbo)34*4882a593Smuzhiyun glamor_destroy_fbo(glamor_screen_private *glamor_priv,
35*4882a593Smuzhiyun glamor_pixmap_fbo *fbo)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun glamor_make_current(glamor_priv);
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun if (fbo->fb)
40*4882a593Smuzhiyun glDeleteFramebuffers(1, &fbo->fb);
41*4882a593Smuzhiyun if (fbo->tex)
42*4882a593Smuzhiyun glDeleteTextures(1, &fbo->tex);
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun free(fbo);
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun static int
glamor_pixmap_ensure_fb(glamor_screen_private * glamor_priv,glamor_pixmap_fbo * fbo)48*4882a593Smuzhiyun glamor_pixmap_ensure_fb(glamor_screen_private *glamor_priv,
49*4882a593Smuzhiyun glamor_pixmap_fbo *fbo)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun int status, err = 0;
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun glamor_make_current(glamor_priv);
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun if (fbo->fb == 0)
56*4882a593Smuzhiyun glGenFramebuffers(1, &fbo->fb);
57*4882a593Smuzhiyun assert(fbo->tex != 0);
58*4882a593Smuzhiyun glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
59*4882a593Smuzhiyun glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
60*4882a593Smuzhiyun GL_TEXTURE_2D, fbo->tex, 0);
61*4882a593Smuzhiyun status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
62*4882a593Smuzhiyun if (status != GL_FRAMEBUFFER_COMPLETE) {
63*4882a593Smuzhiyun const char *str;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun switch (status) {
66*4882a593Smuzhiyun case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
67*4882a593Smuzhiyun str = "incomplete attachment";
68*4882a593Smuzhiyun break;
69*4882a593Smuzhiyun case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
70*4882a593Smuzhiyun str = "incomplete/missing attachment";
71*4882a593Smuzhiyun break;
72*4882a593Smuzhiyun case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
73*4882a593Smuzhiyun str = "incomplete draw buffer";
74*4882a593Smuzhiyun break;
75*4882a593Smuzhiyun case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
76*4882a593Smuzhiyun str = "incomplete read buffer";
77*4882a593Smuzhiyun break;
78*4882a593Smuzhiyun case GL_FRAMEBUFFER_UNSUPPORTED:
79*4882a593Smuzhiyun str = "unsupported";
80*4882a593Smuzhiyun break;
81*4882a593Smuzhiyun case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
82*4882a593Smuzhiyun str = "incomplete multiple";
83*4882a593Smuzhiyun break;
84*4882a593Smuzhiyun default:
85*4882a593Smuzhiyun str = "unknown error";
86*4882a593Smuzhiyun break;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun glamor_fallback("glamor: Failed to create fbo, %s\n", str);
90*4882a593Smuzhiyun err = -1;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun return err;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun glamor_pixmap_fbo *
glamor_create_fbo_from_tex(glamor_screen_private * glamor_priv,PixmapPtr pixmap,int w,int h,GLint tex,int flag)97*4882a593Smuzhiyun glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
98*4882a593Smuzhiyun PixmapPtr pixmap, int w, int h, GLint tex, int flag)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
101*4882a593Smuzhiyun glamor_pixmap_fbo *fbo;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun fbo = calloc(1, sizeof(*fbo));
104*4882a593Smuzhiyun if (fbo == NULL)
105*4882a593Smuzhiyun return NULL;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun fbo->tex = tex;
108*4882a593Smuzhiyun fbo->width = w;
109*4882a593Smuzhiyun fbo->height = h;
110*4882a593Smuzhiyun fbo->is_red = f->format == GL_RED;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
113*4882a593Smuzhiyun if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) {
114*4882a593Smuzhiyun glamor_destroy_fbo(glamor_priv, fbo);
115*4882a593Smuzhiyun fbo = NULL;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun return fbo;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun static int
_glamor_create_tex(glamor_screen_private * glamor_priv,PixmapPtr pixmap,int w,int h)123*4882a593Smuzhiyun _glamor_create_tex(glamor_screen_private *glamor_priv,
124*4882a593Smuzhiyun PixmapPtr pixmap, int w, int h)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
127*4882a593Smuzhiyun unsigned int tex;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun glamor_make_current(glamor_priv);
130*4882a593Smuzhiyun glGenTextures(1, &tex);
131*4882a593Smuzhiyun glBindTexture(GL_TEXTURE_2D, tex);
132*4882a593Smuzhiyun glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
133*4882a593Smuzhiyun glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
134*4882a593Smuzhiyun if (f->format == GL_RED)
135*4882a593Smuzhiyun glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
136*4882a593Smuzhiyun glamor_priv->suppress_gl_out_of_memory_logging = true;
137*4882a593Smuzhiyun glTexImage2D(GL_TEXTURE_2D, 0, f->internalformat, w, h, 0,
138*4882a593Smuzhiyun f->format, f->type, NULL);
139*4882a593Smuzhiyun glamor_priv->suppress_gl_out_of_memory_logging = false;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun if (glGetError() == GL_OUT_OF_MEMORY) {
142*4882a593Smuzhiyun if (!glamor_priv->logged_any_fbo_allocation_failure) {
143*4882a593Smuzhiyun LogMessageVerb(X_WARNING, 0, "glamor: Failed to allocate %dx%d "
144*4882a593Smuzhiyun "FBO due to GL_OUT_OF_MEMORY.\n", w, h);
145*4882a593Smuzhiyun LogMessageVerb(X_WARNING, 0,
146*4882a593Smuzhiyun "glamor: Expect reduced performance.\n");
147*4882a593Smuzhiyun glamor_priv->logged_any_fbo_allocation_failure = true;
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun glDeleteTextures(1, &tex);
150*4882a593Smuzhiyun return 0;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun return tex;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun glamor_pixmap_fbo *
glamor_create_fbo(glamor_screen_private * glamor_priv,PixmapPtr pixmap,int w,int h,int flag)157*4882a593Smuzhiyun glamor_create_fbo(glamor_screen_private *glamor_priv,
158*4882a593Smuzhiyun PixmapPtr pixmap, int w, int h, int flag)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun GLint tex = _glamor_create_tex(glamor_priv, pixmap, w, h);
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun if (!tex) /* Texture creation failed due to GL_OUT_OF_MEMORY */
163*4882a593Smuzhiyun return NULL;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun return glamor_create_fbo_from_tex(glamor_priv, pixmap, w, h,
166*4882a593Smuzhiyun tex, flag);
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun /**
170*4882a593Smuzhiyun * Create storage for the w * h region, using FBOs of the GL's maximum
171*4882a593Smuzhiyun * supported size.
172*4882a593Smuzhiyun */
173*4882a593Smuzhiyun glamor_pixmap_fbo *
glamor_create_fbo_array(glamor_screen_private * glamor_priv,PixmapPtr pixmap,int flag,int block_w,int block_h,glamor_pixmap_private * priv)174*4882a593Smuzhiyun glamor_create_fbo_array(glamor_screen_private *glamor_priv,
175*4882a593Smuzhiyun PixmapPtr pixmap, int flag,
176*4882a593Smuzhiyun int block_w, int block_h,
177*4882a593Smuzhiyun glamor_pixmap_private *priv)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun int w = pixmap->drawable.width;
180*4882a593Smuzhiyun int h = pixmap->drawable.height;
181*4882a593Smuzhiyun int block_wcnt;
182*4882a593Smuzhiyun int block_hcnt;
183*4882a593Smuzhiyun glamor_pixmap_fbo **fbo_array;
184*4882a593Smuzhiyun BoxPtr box_array;
185*4882a593Smuzhiyun int i, j;
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun priv->block_w = block_w;
188*4882a593Smuzhiyun priv->block_h = block_h;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun block_wcnt = (w + block_w - 1) / block_w;
191*4882a593Smuzhiyun block_hcnt = (h + block_h - 1) / block_h;
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun box_array = calloc(block_wcnt * block_hcnt, sizeof(box_array[0]));
194*4882a593Smuzhiyun if (box_array == NULL)
195*4882a593Smuzhiyun return NULL;
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun fbo_array = calloc(block_wcnt * block_hcnt, sizeof(glamor_pixmap_fbo *));
198*4882a593Smuzhiyun if (fbo_array == NULL) {
199*4882a593Smuzhiyun free(box_array);
200*4882a593Smuzhiyun return FALSE;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun for (i = 0; i < block_hcnt; i++) {
203*4882a593Smuzhiyun int block_y1, block_y2;
204*4882a593Smuzhiyun int fbo_w, fbo_h;
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun block_y1 = i * block_h;
207*4882a593Smuzhiyun block_y2 = (block_y1 + block_h) > h ? h : (block_y1 + block_h);
208*4882a593Smuzhiyun fbo_h = block_y2 - block_y1;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun for (j = 0; j < block_wcnt; j++) {
211*4882a593Smuzhiyun box_array[i * block_wcnt + j].x1 = j * block_w;
212*4882a593Smuzhiyun box_array[i * block_wcnt + j].y1 = block_y1;
213*4882a593Smuzhiyun box_array[i * block_wcnt + j].x2 =
214*4882a593Smuzhiyun (j + 1) * block_w > w ? w : (j + 1) * block_w;
215*4882a593Smuzhiyun box_array[i * block_wcnt + j].y2 = block_y2;
216*4882a593Smuzhiyun fbo_w =
217*4882a593Smuzhiyun box_array[i * block_wcnt + j].x2 - box_array[i * block_wcnt +
218*4882a593Smuzhiyun j].x1;
219*4882a593Smuzhiyun fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv,
220*4882a593Smuzhiyun pixmap,
221*4882a593Smuzhiyun fbo_w, fbo_h,
222*4882a593Smuzhiyun GLAMOR_CREATE_PIXMAP_FIXUP);
223*4882a593Smuzhiyun if (fbo_array[i * block_wcnt + j] == NULL)
224*4882a593Smuzhiyun goto cleanup;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun priv->box = box_array[0];
229*4882a593Smuzhiyun priv->box_array = box_array;
230*4882a593Smuzhiyun priv->fbo_array = fbo_array;
231*4882a593Smuzhiyun priv->block_wcnt = block_wcnt;
232*4882a593Smuzhiyun priv->block_hcnt = block_hcnt;
233*4882a593Smuzhiyun return fbo_array[0];
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun cleanup:
236*4882a593Smuzhiyun for (i = 0; i < block_wcnt * block_hcnt; i++)
237*4882a593Smuzhiyun if (fbo_array[i])
238*4882a593Smuzhiyun glamor_destroy_fbo(glamor_priv, fbo_array[i]);
239*4882a593Smuzhiyun free(box_array);
240*4882a593Smuzhiyun free(fbo_array);
241*4882a593Smuzhiyun return NULL;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun void
glamor_pixmap_clear_fbo(glamor_screen_private * glamor_priv,glamor_pixmap_fbo * fbo)245*4882a593Smuzhiyun glamor_pixmap_clear_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo)
246*4882a593Smuzhiyun {
247*4882a593Smuzhiyun glamor_make_current(glamor_priv);
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun assert(fbo->fb != 0 && fbo->tex != 0);
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun glamor_set_destination_pixmap_fbo(glamor_priv, fbo, 0, 0, fbo->width, fbo->height);
252*4882a593Smuzhiyun glClearColor(0.0, 0.0, 0.0, 0.0);
253*4882a593Smuzhiyun glClear(GL_COLOR_BUFFER_BIT);
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun glamor_pixmap_fbo *
glamor_pixmap_detach_fbo(glamor_pixmap_private * pixmap_priv)257*4882a593Smuzhiyun glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun glamor_pixmap_fbo *fbo;
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun if (pixmap_priv == NULL)
262*4882a593Smuzhiyun return NULL;
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun fbo = pixmap_priv->fbo;
265*4882a593Smuzhiyun if (fbo == NULL)
266*4882a593Smuzhiyun return NULL;
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun pixmap_priv->fbo = NULL;
269*4882a593Smuzhiyun return fbo;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun /* The pixmap must not be attached to another fbo. */
273*4882a593Smuzhiyun void
glamor_pixmap_attach_fbo(PixmapPtr pixmap,glamor_pixmap_fbo * fbo)274*4882a593Smuzhiyun glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun glamor_pixmap_private *pixmap_priv;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun pixmap_priv = glamor_get_pixmap_private(pixmap);
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun if (pixmap_priv->fbo)
281*4882a593Smuzhiyun return;
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun pixmap_priv->fbo = fbo;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun switch (pixmap_priv->type) {
286*4882a593Smuzhiyun case GLAMOR_TEXTURE_ONLY:
287*4882a593Smuzhiyun case GLAMOR_TEXTURE_DRM:
288*4882a593Smuzhiyun pixmap_priv->gl_fbo = GLAMOR_FBO_NORMAL;
289*4882a593Smuzhiyun pixmap->devPrivate.ptr = NULL;
290*4882a593Smuzhiyun default:
291*4882a593Smuzhiyun break;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun void
glamor_pixmap_destroy_fbo(PixmapPtr pixmap)296*4882a593Smuzhiyun glamor_pixmap_destroy_fbo(PixmapPtr pixmap)
297*4882a593Smuzhiyun {
298*4882a593Smuzhiyun ScreenPtr screen = pixmap->drawable.pScreen;
299*4882a593Smuzhiyun glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
300*4882a593Smuzhiyun glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
301*4882a593Smuzhiyun glamor_pixmap_fbo *fbo;
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun if (glamor_pixmap_priv_is_large(priv)) {
304*4882a593Smuzhiyun int i;
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun for (i = 0; i < priv->block_wcnt * priv->block_hcnt; i++)
307*4882a593Smuzhiyun glamor_destroy_fbo(glamor_priv, priv->fbo_array[i]);
308*4882a593Smuzhiyun free(priv->fbo_array);
309*4882a593Smuzhiyun priv->fbo_array = NULL;
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun else {
312*4882a593Smuzhiyun fbo = glamor_pixmap_detach_fbo(priv);
313*4882a593Smuzhiyun if (fbo)
314*4882a593Smuzhiyun glamor_destroy_fbo(glamor_priv, fbo);
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun Bool
glamor_pixmap_ensure_fbo(PixmapPtr pixmap,int flag)319*4882a593Smuzhiyun glamor_pixmap_ensure_fbo(PixmapPtr pixmap, int flag)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun glamor_screen_private *glamor_priv;
322*4882a593Smuzhiyun glamor_pixmap_private *pixmap_priv;
323*4882a593Smuzhiyun glamor_pixmap_fbo *fbo;
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
326*4882a593Smuzhiyun pixmap_priv = glamor_get_pixmap_private(pixmap);
327*4882a593Smuzhiyun if (pixmap_priv->fbo == NULL) {
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun fbo = glamor_create_fbo(glamor_priv, pixmap, pixmap->drawable.width,
330*4882a593Smuzhiyun pixmap->drawable.height, flag);
331*4882a593Smuzhiyun if (fbo == NULL)
332*4882a593Smuzhiyun return FALSE;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun glamor_pixmap_attach_fbo(pixmap, fbo);
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun else {
337*4882a593Smuzhiyun /* We do have a fbo, but it may lack of fb or tex. */
338*4882a593Smuzhiyun if (!pixmap_priv->fbo->tex)
339*4882a593Smuzhiyun pixmap_priv->fbo->tex =
340*4882a593Smuzhiyun _glamor_create_tex(glamor_priv, pixmap, pixmap->drawable.width,
341*4882a593Smuzhiyun pixmap->drawable.height);
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
344*4882a593Smuzhiyun if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->fbo) != 0)
345*4882a593Smuzhiyun return FALSE;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun return TRUE;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun _X_EXPORT void
glamor_pixmap_exchange_fbos(PixmapPtr front,PixmapPtr back)352*4882a593Smuzhiyun glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back)
353*4882a593Smuzhiyun {
354*4882a593Smuzhiyun glamor_pixmap_private *front_priv, *back_priv;
355*4882a593Smuzhiyun glamor_pixmap_fbo *temp_fbo;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun front_priv = glamor_get_pixmap_private(front);
358*4882a593Smuzhiyun back_priv = glamor_get_pixmap_private(back);
359*4882a593Smuzhiyun temp_fbo = front_priv->fbo;
360*4882a593Smuzhiyun front_priv->fbo = back_priv->fbo;
361*4882a593Smuzhiyun back_priv->fbo = temp_fbo;
362*4882a593Smuzhiyun }
363