xref: /OK3568_Linux_fs/external/xserver/glamor/glamor_fbo.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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